[project @ 2002-02-12 11:44:54 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / cbits / system.c
index d4670bf..62f1360 100644 (file)
@@ -1,65 +1,60 @@
 /* 
  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
  *
- * $Id: system.c,v 1.3 1998/12/02 13:27:59 simonm Exp $
+ * $Id: system.c,v 1.19 2001/09/17 17:23:32 sewardj Exp $
  *
  * system Runtime Support
  */
 
-#include "Rts.h"
-#include "stgio.h"
+/* The itimer stuff in this module is non-posix */
+/* #include "PosixSource.h" */
 
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
-#endif
+#include "HsStd.h"
 
-#ifdef HAVE_VFORK
-#define fork vfork
+#if defined(mingw32_TARGET_OS)
+#include <windows.h>
+#include <stdlib.h>
 #endif
 
-StgInt
-systemCmd(cmd)
-StgByteArray cmd;
+HsInt
+systemCmd(HsAddr cmd)
 {
-#if defined(cygwin32_TARGET_OS)
-   /* The implementation of std. fork() has its problems
-      under cygwin32-b18, so we fall back on using libc's
-      system() instead. (It in turn has problems, as it
-      does not wait until the sub shell has finished before
-      returning. Using sleep() works around that.)
-  */
-  if (system(cmd) < 0) {
-     cvtErrno();
-     stdErrno();
-     return -1;
-  }
-  sleep(1);
-  return 0;
+  /* -------------------- WINDOWS VERSION --------------------- */
+#if defined(mingw32_TARGET_OS)
+    return system(cmd);
 #else
+  /* -------------------- UNIX VERSION --------------------- */
     int pid;
     int wstat;
 
     switch(pid = fork()) {
     case -1:
        if (errno != EINTR) {
-           cvtErrno();
-           stdErrno();
            return -1;
        }
     case 0:
+      {
+#ifdef HAVE_SETITIMER
+       /* Reset the itimers in the child, so it doesn't get plagued
+        * by SIGVTALRM interrupts.
+        */
+       struct timeval tv_null = { 0, 0 };
+       struct itimerval itv;
+       itv.it_interval = tv_null;
+       itv.it_value = tv_null;
+       setitimer(ITIMER_REAL, &itv, NULL);
+       setitimer(ITIMER_VIRTUAL, &itv, NULL);
+       setitimer(ITIMER_PROF, &itv, NULL);
+#endif
+
        /* the child */
        execl("/bin/sh", "sh", "-c", cmd, NULL);
        _exit(127);
+      }
     }
 
     while (waitpid(pid, &wstat, 0) < 0) {
        if (errno != EINTR) {
-           cvtErrno();
-           stdErrno();
            return -1;
        }
     }
@@ -67,13 +62,10 @@ StgByteArray cmd;
     if (WIFEXITED(wstat))
        return WEXITSTATUS(wstat);
     else if (WIFSIGNALED(wstat)) {
-       ghc_errtype = ERR_INTERRUPTED;
-       ghc_errstr = "system command interrupted";
+       errno = EINTR;
     }
     else {
        /* This should never happen */
-       ghc_errtype = ERR_OTHERERROR;
-       ghc_errstr = "internal error (process neither exited nor signalled)";
     }
     return -1;
 #endif