9983c9257809f6e9e4f6f813260f52b895358b73
[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.15 2001/06/29 11:35:14 simonpj Exp $
5  *
6  * system Runtime Support
7  */
8
9 /* The itimer stuff in this module is non-posix */
10 #define NON_POSIX_SOURCE
11
12 #include "HsStd.h"
13
14 #if defined(mingw32_TARGET_OS)
15 #include <windows.h>
16 #endif
17
18 HsInt
19 systemCmd(HsAddr cmd)
20 {
21   /* -------------------- WINDOWS VERSION --------------------- */
22 #if defined(mingw32_TARGET_OS)
23   STARTUPINFO sInfo;
24   PROCESS_INFORMATION pInfo;
25   DWORD retCode;
26
27   sInfo.cb              = sizeof(STARTUPINFO);
28   sInfo.lpReserved      = NULL;
29   sInfo.lpReserved2     = NULL;
30   sInfo.cbReserved2     = 0;
31   sInfo.lpDesktop       = NULL;
32   sInfo.lpTitle         = NULL;
33   sInfo.dwFlags         = 0;
34
35   if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &sInfo, &pInfo))
36     return -1;
37   WaitForSingleObject(pInfo.hProcess, INFINITE);
38   if (GetExitCodeProcess(pInfo.hProcess, &retCode) == 0) return -1;
39   CloseHandle(pInfo.hProcess);
40   CloseHandle(pInfo.hThread);
41   return retCode;
42
43 #else
44   /* -------------------- UNIX VERSION --------------------- */
45     int pid;
46     int wstat;
47
48     switch(pid = fork()) {
49     case -1:
50         if (errno != EINTR) {
51             return -1;
52         }
53     case 0:
54       {
55 #ifdef HAVE_SETITIMER
56         /* Reset the itimers in the child, so it doesn't get plagued
57          * by SIGVTALRM interrupts.
58          */
59         struct timeval tv_null = { 0, 0 };
60         struct itimerval itv;
61         itv.it_interval = tv_null;
62         itv.it_value = tv_null;
63         setitimer(ITIMER_REAL, &itv, NULL);
64         setitimer(ITIMER_VIRTUAL, &itv, NULL);
65         setitimer(ITIMER_PROF, &itv, NULL);
66 #endif
67
68         /* the child */
69         execl("/bin/sh", "sh", "-c", cmd, NULL);
70         _exit(127);
71       }
72     }
73
74     while (waitpid(pid, &wstat, 0) < 0) {
75         if (errno != EINTR) {
76             return -1;
77         }
78     }
79
80     if (WIFEXITED(wstat))
81         return WEXITSTATUS(wstat);
82     else if (WIFSIGNALED(wstat)) {
83         errno = EINTR;
84     }
85     else {
86         /* This should never happen */
87     }
88     return -1;
89 #endif
90 }