summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
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;
}