summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2021-02-18 11:16:47 -0800
committerThiago Macieira <thiago.macieira@intel.com>2021-02-21 18:47:19 -0800
commitf0ce50d3353e8a684f905e19dc6116dd1b515bf2 (patch)
tree75a79721995617c6a95847f3506d65d56aa88ad7 /src
parent089bcb007454fe44224139b2d0a0e4145f209b15 (diff)
QProcess::startDetached/Unix: simplify handling of the pipes
Use a structure that will automatically close them for us. This doesn't apply to startProcess() because the pipes there are long-lived (though each of them in QProcessPrivate could be an AutoPipe...). The destructor only runs in the parent process, so the child processes don't need to worry about setting file descriptors to -1. Pick-to: 6.1 Change-Id: Ic90d8429a0eb4837971dfffd1664ed98f3d74d1c Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qprocess_unix.cpp47
1 files changed, 26 insertions, 21 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index f235ab1320..bfb5c8d6a4 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -148,6 +148,26 @@ QProcessEnvironment QProcessEnvironment::systemEnvironment()
#if QT_CONFIG(process)
namespace {
+struct AutoPipe
+{
+ int pipe[2] = { -1, -1 };
+ AutoPipe(int flags = 0)
+ {
+ qt_safe_pipe(pipe, flags);
+ }
+ ~AutoPipe()
+ {
+ for (int fd : pipe) {
+ if (fd >= 0)
+ qt_safe_close(fd);
+ }
+ }
+
+ explicit operator bool() const { return pipe[0] >= 0; }
+ int &operator[](int idx) { return pipe[idx]; }
+ int operator[](int idx) const { return pipe[idx]; }
+};
+
struct QProcessPoller
{
QProcessPoller(const QProcessPrivate &proc);
@@ -882,30 +902,18 @@ bool QProcessPrivate::startDetached(qint64 *pid)
{
QByteArray encodedWorkingDirectory = QFile::encodeName(workingDirectory);
- // To catch the startup of the child
- int startedPipe[2];
- if (qt_safe_pipe(startedPipe) != 0) {
+ // To catch the startup of the child and communicate its pid
+ AutoPipe startedPipe, pidPipe;
+ if (!startedPipe || !pidPipe) {
setErrorAndEmit(QProcess::FailedToStart, QLatin1String("pipe: ") + qt_error_string(errno));
return false;
}
- // To communicate the pid of the child
- int pidPipe[2];
- if (qt_safe_pipe(pidPipe) != 0) {
- setErrorAndEmit(QProcess::FailedToStart, QLatin1String("pipe: ") + qt_error_string(errno));
- qt_safe_close(startedPipe[0]);
- qt_safe_close(startedPipe[1]);
- return false;
- }
if (!openChannelsForDetached()) {
// openChannel sets the error string
closeChannel(&stdinChannel);
closeChannel(&stdoutChannel);
closeChannel(&stderrChannel);
- qt_safe_close(pidPipe[0]);
- qt_safe_close(pidPipe[1]);
- qt_safe_close(startedPipe[0]);
- qt_safe_close(startedPipe[1]);
return false;
}
@@ -976,20 +984,18 @@ bool QProcessPrivate::startDetached(qint64 *pid)
closeChannel(&stdinChannel);
closeChannel(&stdoutChannel);
closeChannel(&stderrChannel);
- qt_safe_close(startedPipe[1]);
- qt_safe_close(pidPipe[1]);
if (childPid == -1) {
- qt_safe_close(startedPipe[0]);
- qt_safe_close(pidPipe[0]);
setErrorAndEmit(QProcess::FailedToStart, QLatin1String("fork: ") + qt_error_string(savedErrno));
return false;
}
+ qt_safe_close(startedPipe[1]);
+ startedPipe[1] = -1;
+
char reply = '\0';
int startResult = qt_safe_read(startedPipe[0], &reply, 1);
int result;
- qt_safe_close(startedPipe[0]);
qt_safe_waitpid(childPid, &result, 0);
bool success = (startResult != -1 && reply == '\0');
@@ -1003,7 +1009,6 @@ bool QProcessPrivate::startDetached(qint64 *pid)
*pid = -1;
setErrorAndEmit(QProcess::FailedToStart);
}
- qt_safe_close(pidPipe[0]);
return success;
}