QNX: fix QProcess fd inheritance
authorRafael Roquetto <rafael.roquetto.qnx@kdab.com>
Tue, 20 Nov 2012 20:30:15 +0000 (18:30 -0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 27 Nov 2012 18:31:21 +0000 (19:31 +0100)
Under QNX, QProcess was not inheriting the parent's file descriptors. This
patch fills in the fd_map array, containing the file descriptors to be
inherited, which is passed to spawn(), accordingly.

Change-Id: Ia160abda88c1ffede877301aeae93a97c2b35320
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Sérgio Martins <sergio.martins.qnx@kdab.com>
src/corelib/io/qprocess_unix.cpp

index 0a928e4..19d0b06 100644 (file)
@@ -107,6 +107,8 @@ QT_END_NAMESPACE
 #include <stdlib.h>
 #include <string.h>
 #ifdef Q_OS_QNX
+#include "qvarlengtharray.h"
+
 #include <spawn.h>
 #include <sys/neutrino.h>
 #endif
@@ -779,8 +781,21 @@ static pid_t doSpawn(int fd_count, int fd_map[], char **argv, char **envp,
 
 pid_t QProcessPrivate::spawnChild(const char *workingDir, char **argv, char **envp)
 {
-    const int fd_count = 3;
-    int fd_map[fd_count];
+    // we need to manually fill in fd_map
+    // to inherit the file descriptors from
+    // the parent
+    const int fd_count = sysconf(_SC_OPEN_MAX);
+    QVarLengthArray<int, 1024> fd_map(fd_count);
+
+    for (int i = 3; i < fd_count; ++i) {
+        // here we rely that fcntl returns -1 and
+        // sets errno to EBADF
+        const int flags = ::fcntl(i, F_GETFD);
+
+        fd_map[i] = ((flags >= 0) && !(flags & FD_CLOEXEC))
+                  ? i : SPAWN_FDCLOSED;
+    }
+
     switch (processChannelMode) {
     case QProcess::ForwardedChannels:
         fd_map[0] = stdinChannel.pipe[0];
@@ -799,7 +814,7 @@ pid_t QProcessPrivate::spawnChild(const char *workingDir, char **argv, char **en
         break;
     }
 
-    pid_t childPid = doSpawn(fd_count, fd_map, argv, envp, workingDir, false);
+    pid_t childPid = doSpawn(fd_count, fd_map.data(), argv, envp, workingDir, false);
 
     if (childPid == -1) {
         QString error = qt_error_string(errno);