[project @ 2002-02-12 11:44:54 by simonmar]
[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.19 2001/09/17 17:23:32 sewardj Exp $
5  *
6  * system Runtime Support
7  */
8
9 /* The itimer stuff in this module is non-posix */
10 /* #include "PosixSource.h" */
11
12 #include "HsStd.h"
13
14 #if defined(mingw32_TARGET_OS)
15 #include <windows.h>
16 #include <stdlib.h>
17 #endif
18
19 HsInt
20 systemCmd(HsAddr cmd)
21 {
22   /* -------------------- WINDOWS VERSION --------------------- */
23 #if defined(mingw32_TARGET_OS)
24     return system(cmd);
25 #else
26   /* -------------------- UNIX VERSION --------------------- */
27     int pid;
28     int wstat;
29
30     switch(pid = fork()) {
31     case -1:
32         if (errno != EINTR) {
33             return -1;
34         }
35     case 0:
36       {
37 #ifdef HAVE_SETITIMER
38         /* Reset the itimers in the child, so it doesn't get plagued
39          * by SIGVTALRM interrupts.
40          */
41         struct timeval tv_null = { 0, 0 };
42         struct itimerval itv;
43         itv.it_interval = tv_null;
44         itv.it_value = tv_null;
45         setitimer(ITIMER_REAL, &itv, NULL);
46         setitimer(ITIMER_VIRTUAL, &itv, NULL);
47         setitimer(ITIMER_PROF, &itv, NULL);
48 #endif
49
50         /* the child */
51         execl("/bin/sh", "sh", "-c", cmd, NULL);
52         _exit(127);
53       }
54     }
55
56     while (waitpid(pid, &wstat, 0) < 0) {
57         if (errno != EINTR) {
58             return -1;
59         }
60     }
61
62     if (WIFEXITED(wstat))
63         return WEXITSTATUS(wstat);
64     else if (WIFSIGNALED(wstat)) {
65         errno = EINTR;
66     }
67     else {
68         /* This should never happen */
69     }
70     return -1;
71 #endif
72 }