[project @ 2001-06-28 14:15:04 by simonmar]
[packages/old-time.git] / cbits / system.c
1 /*
2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
3 *
4 * $Id: system.c,v 1.1 2001/06/28 14:15:04 simonmar 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 "HsCore.h"
13
14 #if defined(mingw32_TARGET_OS)
15 #include <windows.h>
16 #endif
17
18 HsInt
19 systemCmd(HsAddr cmd)
20 {
21 #if defined(mingw32_TARGET_OS)
22 STARTUPINFO sInfo;
23 PROCESS_INFORMATION pInfo;
24 DWORD retCode;
25
26 sInfo.cb = sizeof(STARTUPINFO);
27 sInfo.lpReserved = NULL;
28 sInfo.lpReserved2 = NULL;
29 sInfo.cbReserved2 = 0;
30 sInfo.lpDesktop = NULL;
31 sInfo.lpTitle = NULL;
32 sInfo.dwFlags = 0;
33
34 if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &sInfo, &pInfo))
35 return -1;
36 WaitForSingleObject(pInfo.hProcess, INFINITE);
37 if (GetExitCodeProcess(pInfo.hProcess, &retCode) == 0) return -1;
38 CloseHandle(pInfo.hProcess);
39 CloseHandle(pInfo.hThread);
40 return retCode;
41 #else
42 int pid;
43 int wstat;
44
45 switch(pid = fork()) {
46 case -1:
47 if (errno != EINTR) {
48 return -1;
49 }
50 case 0:
51 {
52 #ifdef HAVE_SETITIMER
53 /* Reset the itimers in the child, so it doesn't get plagued
54 * by SIGVTALRM interrupts.
55 */
56 struct timeval tv_null = { 0, 0 };
57 struct itimerval itv;
58 itv.it_interval = tv_null;
59 itv.it_value = tv_null;
60 setitimer(ITIMER_REAL, &itv, NULL);
61 setitimer(ITIMER_VIRTUAL, &itv, NULL);
62 setitimer(ITIMER_PROF, &itv, NULL);
63 #endif
64
65 /* the child */
66 execl("/bin/sh", "sh", "-c", cmd, NULL);
67 _exit(127);
68 }
69 }
70
71 while (waitpid(pid, &wstat, 0) < 0) {
72 if (errno != EINTR) {
73 return -1;
74 }
75 }
76
77 if (WIFEXITED(wstat))
78 return WEXITSTATUS(wstat);
79 else if (WIFSIGNALED(wstat)) {
80 errno = EINTR;
81 }
82 else {
83 /* This should never happen */
84 }
85 return -1;
86 #endif
87 }