[project @ 2005-03-07 10:40:44 by simonmar]
[ghc-base.git] / cbits / runProcess.c
index 56d4eab..82fa97e 100644 (file)
@@ -30,7 +30,9 @@
 \r
 ProcHandle\r
 runProcess (char *const args[], char *workingDirectory, char **environment, \r
-           int fdStdInput, int fdStdOutput, int fdStdError)\r
+           int fdStdInput, int fdStdOutput, int fdStdError,\r
+           int set_inthandler, long inthandler, \r
+           int set_quithandler, long quithandler)\r
 {\r
     int pid;\r
     struct sigaction dfl;\r
@@ -48,27 +50,18 @@ runProcess (char *const args[], char *workingDirectory, char **environment,
            chdir (workingDirectory);\r
        }\r
        \r
-       /*\r
-        * Restore SIGINT and SIGQUIT to default actions\r
-        *\r
-        * Glyn Clemments writes:\r
-        * For your purposes, runProcess + waitForProcess is probably\r
-        * the way to go. Except that runProcess appears to be missing\r
-        * the usual signal handling. system() ignores SIGINT and\r
-        * SIGQUIT in the parent, and resets them to their defaults in\r
-        * the child; it also blocks SIGCHLD in the parent. runProcess\r
-        * may need to do something similar; it should probably at\r
-        * least reset SIGINT and SIGQUIT in the child, in case they\r
-        * are ignored in the parent. The parent can set up its own\r
-        * signal handling, but the only place it can control the\r
-        * child's signal handling is between the fork() and the\r
-        * exec(), so if runProcess doesn't do it, it won't get done.\r
+       /* Set the SIGINT/SIGQUIT signal handlers in the child, if requested \r
         */\r
-        dfl.sa_handler = SIG_DFL;\r
         (void)sigemptyset(&dfl.sa_mask);\r
         dfl.sa_flags = 0;\r
-       (void)sigaction(SIGINT, &dfl, NULL);\r
-       (void)sigaction(SIGQUIT,  &dfl, NULL);\r
+       if (set_inthandler) {\r
+           dfl.sa_handler = (void *)inthandler;\r
+           (void)sigaction(SIGINT, &dfl, NULL);\r
+       }\r
+       if (set_quithandler) {\r
+           dfl.sa_handler = (void *)quithandler;\r
+           (void)sigaction(SIGQUIT,  &dfl, NULL);\r
+       }\r
 \r
        dup2 (fdStdInput,  STDIN_FILENO);\r
        dup2 (fdStdOutput, STDOUT_FILENO);\r
@@ -160,11 +153,11 @@ terminateProcess (ProcHandle handle)
 int\r
 getProcessExitCode (ProcHandle handle, int *pExitCode)\r
 {\r
-    int wstat;\r
+    int wstat, res;\r
     \r
     *pExitCode = 0;\r
     \r
-    if (waitpid(handle, &wstat, WNOHANG) > 0)\r
+    if ((res = waitpid(handle, &wstat, WNOHANG)) > 0)\r
     {\r
        if (WIFEXITED(wstat))\r
        {\r
@@ -183,7 +176,15 @@ getProcessExitCode (ProcHandle handle, int *pExitCode)
            }\r
     }\r
     \r
-    return 0;\r
+    if (res == 0) return 0;\r
+\r
+    if (errno == ECHILD) \r
+    {\r
+           *pExitCode = 0;\r
+           return 1;\r
+    }\r
+\r
+    return -1;\r
 }\r
 \r
 int waitForProcess (ProcHandle handle)\r