[project @ 2003-07-10 19:25:58 by sof]
[haskell-directory.git] / cbits / system.c
1 /* 
2  * (c) The University of Glasgow 2002
3  *
4  * $Id: system.c,v 1.8 2003/07/02 13:27:35 stolz 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 "HsBase.h"
13
14 #if defined(mingw32_TARGET_OS)
15 #include <windows.h>
16 #include <stdlib.h>
17 #endif
18
19 #ifdef HAVE_VFORK_H
20 #include <vfork.h>
21 #endif
22
23 #ifdef HAVE_VFORK
24 #define fork vfork
25 #endif
26
27 HsInt
28 systemCmd(HsAddr cmd)
29 {
30   /* -------------------- WINDOWS VERSION --------------------- */
31 #if defined(mingw32_TARGET_OS) || defined(cygwin32_TARGET_OS)
32     return system(cmd);
33 #else
34   /* -------------------- UNIX VERSION --------------------- */
35     int pid;
36     int wstat;
37
38     switch(pid = fork()) {
39     case -1:
40         {
41             return -1;
42         }
43     case 0:
44       {
45 #ifdef HAVE_SETITIMER
46         /* Reset the itimers in the child, so it doesn't get plagued
47          * by SIGVTALRM interrupts.
48          */
49         struct timeval tv_null = { 0, 0 };
50         struct itimerval itv;
51         itv.it_interval = tv_null;
52         itv.it_value = tv_null;
53         setitimer(ITIMER_REAL, &itv, NULL);
54         setitimer(ITIMER_VIRTUAL, &itv, NULL);
55         setitimer(ITIMER_PROF, &itv, NULL);
56 #endif
57
58         /* the child */
59         execl("/bin/sh", "sh", "-c", cmd, NULL);
60         _exit(127);
61       }
62     }
63
64     while (waitpid(pid, &wstat, 0) < 0) {
65         if (errno != EINTR) {
66             return -1;
67         }
68     }
69
70     if (WIFEXITED(wstat))
71         return WEXITSTATUS(wstat);
72     else if (WIFSIGNALED(wstat)) {
73         errno = EINTR;
74     }
75     else {
76         /* This should never happen */
77     }
78     return -1;
79 #endif
80 }