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