2349ea7c3ca4cb4ddb1c0960a1a81beb66143abd
[ghc-hetmet.git] / ghc / lib / std / cbits / system.c
1 /* 
2  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
3  *
4  * $Id: system.c,v 1.5 1999/03/01 08:57:57 sof Exp $
5  *
6  * system Runtime Support
7  */
8
9 #include "Rts.h"
10 #include "stgio.h"
11
12 #ifdef HAVE_UNISTD_H
13 #include <unistd.h>
14 #endif
15
16 #ifndef mingw32_TARGET_OS
17 # ifdef HAVE_SYS_WAIT_H
18 #  include <sys/wait.h>
19 # endif
20 #endif
21
22 #ifdef HAVE_VFORK_H
23 #include <vfork.h>
24 #endif
25
26 #ifdef HAVE_VFORK
27 #define fork vfork
28 #endif
29
30 StgInt
31 systemCmd(cmd)
32 StgByteArray cmd;
33 {
34 #if defined(mingw32_TARGET_OS)
35   if (system(cmd) < 0) {
36      cvtErrno();
37      stdErrno();
38      return -1;
39   }
40   sleep(1);
41   return 0;
42 #else
43 #if defined(cygwin32_TARGET_OS)
44    /* The implementation of std. fork() has its problems
45       under cygwin32-b18, so we fall back on using libc's
46       system() instead. (It in turn has problems, as it
47       does not wait until the sub shell has finished before
48       returning. Using sleep() works around that.)
49   */
50   if (system(cmd) < 0) {
51      cvtErrno();
52      stdErrno();
53      return -1;
54   }
55   sleep(1);
56   return 0;
57 #else
58     int pid;
59     int wstat;
60
61     switch(pid = fork()) {
62     case -1:
63         if (errno != EINTR) {
64             cvtErrno();
65             stdErrno();
66             return -1;
67         }
68     case 0:
69         /* the child */
70         execl("/bin/sh", "sh", "-c", cmd, NULL);
71         _exit(127);
72     }
73
74     while (waitpid(pid, &wstat, 0) < 0) {
75         if (errno != EINTR) {
76             cvtErrno();
77             stdErrno();
78             return -1;
79         }
80     }
81
82     if (WIFEXITED(wstat))
83         return WEXITSTATUS(wstat);
84     else if (WIFSIGNALED(wstat)) {
85         ghc_errtype = ERR_INTERRUPTED;
86         ghc_errstr = "system command interrupted";
87     }
88     else {
89         /* This should never happen */
90         ghc_errtype = ERR_OTHERERROR;
91         ghc_errstr = "internal error (process neither exited nor signalled)";
92     }
93     return -1;
94 #endif
95 #endif
96 }