summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>2001-10-17 23:11:25 +0000
committerwtc%netscape.com <devnull@localhost>2001-10-17 23:11:25 +0000
commit90054d88b10bbf4929db38dc569c31ec4c66e5db (patch)
tree4a500bde5f1e89df072ca99056b6dfc779dadfa9
parentce4e3a3b2d1988771dd4cfc9d9ce871f7056c40c (diff)
downloadnspr-hg-90054d88b10bbf4929db38dc569c31ec4c66e5db.tar.gz
Bugzilla bug 77197: use spawn in Neutrino because fork & exec does not
work in multithreaded programs in Neutrino. The patch is contributed by dinglis@qnx.com (Dave Inglis), reviewed and modified by wtc.
-rw-r--r--pr/src/md/unix/uxproces.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/pr/src/md/unix/uxproces.c b/pr/src/md/unix/uxproces.c
index d7682494..9530cf52 100644
--- a/pr/src/md/unix/uxproces.c
+++ b/pr/src/md/unix/uxproces.c
@@ -267,6 +267,46 @@ ForkAndExec(
#ifdef AIX
process->md.pid = (*pr_wp.forkptr)();
+#elif defined(NTO)
+ /*
+ * fork() & exec() does not work in a multithreaded process.
+ * Use spawn() instead.
+ */
+ {
+ int fd_map[3] = { 0, 1, 2 };
+
+ if (attr) {
+ if (attr->stdinFd && attr->stdinFd->secret->md.osfd != 0) {
+ fd_map[0] = dup(attr->stdinFd->secret->md.osfd);
+ flags = fcntl(fd_map[0], F_GETFL, 0);
+ if (flags & O_NONBLOCK)
+ fcntl(fd_map[0], F_SETFL, flags & ~O_NONBLOCK);
+ }
+ if (attr->stdoutFd && attr->stdoutFd->secret->md.osfd != 1) {
+ fd_map[1] = dup(attr->stdoutFd->secret->md.osfd);
+ flags = fcntl(fd_map[1], F_GETFL, 0);
+ if (flags & O_NONBLOCK)
+ fcntl(fd_map[1], F_SETFL, flags & ~O_NONBLOCK);
+ }
+ if (attr->stderrFd && attr->stderrFd->secret->md.osfd != 2) {
+ fd_map[2] = dup(attr->stderrFd->secret->md.osfd);
+ flags = fcntl(fd_map[2], F_GETFL, 0);
+ if (flags & O_NONBLOCK)
+ fcntl(fd_map[2], F_SETFL, flags & ~O_NONBLOCK);
+ }
+
+ PR_ASSERT(attr->currentDirectory == NULL); /* not implemented */
+ }
+
+ process->md.pid = spawn(path, 3, fd_map, NULL, argv, childEnvp);
+
+ if (fd_map[0] != 0)
+ close(fd_map[0]);
+ if (fd_map[1] != 1)
+ close(fd_map[1]);
+ if (fd_map[2] != 2)
+ close(fd_map[2]);
+ }
#else
process->md.pid = fork();
#endif
@@ -285,6 +325,7 @@ ForkAndExec(
* the parent process's standard I/O data structures.
*/
+#if !defined(NTO)
#ifdef VMS
/* OpenVMS has already handled all this above */
#else
@@ -367,6 +408,7 @@ ForkAndExec(
#else
_exit(1);
#endif /* VMS */
+#endif /* !NTO */
}
if (newEnvp) {