[project @ 2002-04-24 16:01:51 by simonmar]
[packages/random.git] / cbits / system.c
1 /*
2 * (c) The University of Glasgow 2002
3 *
4 * $Id: system.c,v 1.6 2002/03/26 21:02:19 sof 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 HsInt
20 systemCmd(HsAddr cmd)
21 {
22 /* -------------------- WINDOWS VERSION --------------------- */
23 #if defined(mingw32_TARGET_OS) || defined(cygwin32_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 }