summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2021-02-18 09:36:56 -0800
committerThiago Macieira <thiago.macieira@intel.com>2021-02-21 18:46:28 -0800
commit73a04edce151b21ea5d07494603c0317716e99d9 (patch)
tree145b501dbb9a9ad5eb03e73c595b7066bdd47769 /src/corelib
parent86ebdc07dfd8c4df09b21ecc528dcae8d978f7e1 (diff)
QProcess::startDetached: set the error condition on failure to start
And set *pid to -1. [ChangeLog][QtCore][QProcess] If a startDetached() fails to start the target application, the QProcess object should now have a proper error string in errorString(). Pick-to: 6.1 Change-Id: Ic90d8429a0eb4837971dfffd1664e825ffcb923e Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qprocess.cpp11
-rw-r--r--src/corelib/io/qprocess_unix.cpp28
-rw-r--r--src/corelib/io/qprocess_win.cpp6
3 files changed, 31 insertions, 14 deletions
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 2462d829a0..f03fc067cf 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -2132,11 +2132,12 @@ void QProcess::startCommand(const QString &command, OpenMode mode)
temporarily freeze.
If the function is successful then *\a pid is set to the process identifier
- of the started process. Note that the child process may exit and the PID
- may become invalid without notice. Furthermore, after the child process
- exits, the same PID may be recycled and used by a completely different
- process. User code should be careful when using this variable, especially
- if one intends to forcibly terminate the process by operating system means.
+ of the started process; otherwise, it's set to -1. Note that the child
+ process may exit and the PID may become invalid without notice.
+ Furthermore, after the child process exits, the same PID may be recycled
+ and used by a completely different process. User code should be careful
+ when using this variable, especially if one intends to forcibly terminate
+ the process by operating system means.
Only the following property setters are supported by startDetached():
\list
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index b6757e5b79..1e74cfff60 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -1,7 +1,8 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2021 Intel Corporation.
+** Copyright (C) 2021 Alex Trotsenko.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -883,17 +884,21 @@ bool QProcessPrivate::startDetached(qint64 *pid)
// To catch the startup of the child
int startedPipe[2];
- if (qt_safe_pipe(startedPipe) != 0)
+ if (qt_safe_pipe(startedPipe) != 0) {
+ 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);
@@ -981,6 +986,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
::_exit(1);
}
+ int savedErrno = errno;
closeChannel(&stdinChannel);
closeChannel(&stdoutChannel);
closeChannel(&stderrChannel);
@@ -990,6 +996,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
if (childPid == -1) {
qt_safe_close(startedPipe[0]);
qt_safe_close(pidPipe[0]);
+ setErrorAndEmit(QProcess::FailedToStart, QLatin1String("fork: ") + qt_error_string(savedErrno));
return false;
}
@@ -998,14 +1005,17 @@ bool QProcessPrivate::startDetached(qint64 *pid)
int result;
qt_safe_close(startedPipe[0]);
qt_safe_waitpid(childPid, &result, 0);
+
bool success = (startResult != -1 && reply == '\0');
if (success && pid) {
- pid_t actualPid = 0;
- if (qt_safe_read(pidPipe[0], (char *)&actualPid, sizeof(pid_t)) == sizeof(pid_t)) {
- *pid = actualPid;
- } else {
- *pid = 0;
- }
+ pid_t actualPid;
+ if (qt_safe_read(pidPipe[0], &actualPid, sizeof(pid_t)) != sizeof(pid_t))
+ actualPid = 0;
+ *pid = actualPid;
+ } else if (!success) {
+ if (pid)
+ *pid = -1;
+ setErrorAndEmit(QProcess::FailedToStart);
}
qt_safe_close(pidPipe[0]);
return success;
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index dc8c50127d..0088284d2d 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -869,6 +869,7 @@ bool QProcessPrivate::startDetached(qint64 *pid)
static const DWORD errorElevationRequired = 740;
if (!openChannelsForDetached()) {
+ // openChannel sets the error string
closeChannel(&stdinChannel);
closeChannel(&stdoutChannel);
closeChannel(&stderrChannel);
@@ -913,6 +914,11 @@ bool QProcessPrivate::startDetached(qint64 *pid)
success = startDetachedUacPrompt(program, arguments, nativeArguments,
workingDirectory, pid);
}
+ if (!success) {
+ if (pid)
+ *pid = -1;
+ setErrorAndEmit(QProcess::FailedToStart);
+ }
closeChannel(&stdinChannel);
closeChannel(&stdoutChannel);