summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qprocess_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qprocess_unix.cpp')
-rw-r--r--src/corelib/io/qprocess_unix.cpp81
1 files changed, 70 insertions, 11 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index e9957d2384..9868ea624a 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -807,19 +807,29 @@ pid_t QProcessPrivate::spawnChild(const char *workingDir, char **argv, char **en
? i : SPAWN_FDCLOSED;
}
+ if (inputChannelMode == QProcess::ManagedInputChannel)
+ fd_map[0] = stdinChannel.pipe[0];
+ else
+ fd_map[0] = QT_FILENO(stdin);
+
switch (processChannelMode) {
case QProcess::ForwardedChannels:
- fd_map[0] = stdinChannel.pipe[0];
fd_map[1] = QT_FILENO(stdout);
fd_map[2] = QT_FILENO(stderr);
break;
+ case QProcess::ForwardedOutputChannel:
+ fd_map[1] = QT_FILENO(stdout);
+ fd_map[2] = stderrChannel.pipe[1];
+ break;
+ case QProcess::ForwardedErrorChannel:
+ fd_map[1] = stdoutChannel.pipe[1];
+ fd_map[2] = QT_FILENO(stderr);
+ break;
case QProcess::MergedChannels:
- fd_map[0] = stdinChannel.pipe[0];
fd_map[1] = stdoutChannel.pipe[1];
fd_map[2] = stdoutChannel.pipe[1];
break;
case QProcess::SeparateChannels:
- fd_map[0] = stdinChannel.pipe[0];
fd_map[1] = stdoutChannel.pipe[1];
fd_map[2] = stderrChannel.pipe[1];
break;
@@ -845,17 +855,19 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
Q_Q(QProcess);
- // copy the stdin socket (without closing on exec)
- qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0);
+ // copy the stdin socket if asked to (without closing on exec)
+ if (inputChannelMode != QProcess::ForwardedInputChannel)
+ qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0);
// copy the stdout and stderr if asked to
if (processChannelMode != QProcess::ForwardedChannels) {
- qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0);
+ if (processChannelMode != QProcess::ForwardedOutputChannel)
+ qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0);
// merge stdout and stderr if asked to
if (processChannelMode == QProcess::MergedChannels) {
qt_safe_dup2(fileno(stdout), fileno(stderr), 0);
- } else {
+ } else if (processChannelMode != QProcess::ForwardedErrorChannel) {
qt_safe_dup2(stderrChannel.pipe[1], fileno(stderr), 0);
}
}
@@ -1031,6 +1043,41 @@ static int qt_timeout_value(int msecs, int elapsed)
return timeout < 0 ? 0 : timeout;
}
+#ifdef Q_OS_BLACKBERRY
+// The BlackBerry event dispatcher uses bps_get_event. Unfortunately, already registered
+// socket notifiers are disabled by a call to select. This is to rearm the standard streams.
+static int bb_select(QProcessPrivate *process, int nfds, fd_set *fdread, fd_set *fdwrite, int timeout)
+{
+ bool stdoutEnabled = false;
+ bool stderrEnabled = false;
+ bool stdinEnabled = false;
+
+ if (process->stdoutChannel.notifier && process->stdoutChannel.notifier->isEnabled()) {
+ stdoutEnabled = true;
+ process->stdoutChannel.notifier->setEnabled(false);
+ }
+ if (process->stderrChannel.notifier && process->stderrChannel.notifier->isEnabled()) {
+ stderrEnabled = true;
+ process->stderrChannel.notifier->setEnabled(false);
+ }
+ if (process->stdinChannel.notifier && process->stdinChannel.notifier->isEnabled()) {
+ stdinEnabled = true;
+ process->stdinChannel.notifier->setEnabled(false);
+ }
+
+ const int ret = select_msecs(nfds, fdread, fdwrite, timeout);
+
+ if (stdoutEnabled)
+ process->stdoutChannel.notifier->setEnabled(true);
+ if (stderrEnabled)
+ process->stderrChannel.notifier->setEnabled(true);
+ if (stdinEnabled)
+ process->stdinChannel.notifier->setEnabled(true);
+
+ return ret;
+}
+#endif // Q_OS_BLACKBERRY
+
bool QProcessPrivate::waitForStarted(int msecs)
{
Q_Q(QProcess);
@@ -1091,7 +1138,11 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
+#ifdef Q_OS_BLACKBERRY
+ int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+#else
int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+#endif
if (ret < 0) {
break;
}
@@ -1163,8 +1214,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
- int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
- int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+ int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
+#ifdef Q_OS_BLACKBERRY
+ int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+#else
+ int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+#endif
if (ret < 0) {
break;
}
@@ -1230,8 +1285,12 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
- int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
- int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+ int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
+#ifdef Q_OS_BLACKBERRY
+ int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+#else
+ int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+#endif
if (ret < 0) {
break;
}