2 * (c) The University of Glasgow 1994-2004
4 * WARNING: this file is here for backwards compatibility only. It is
5 * not included as part of the base package, but is #included into the
6 * compiler and the runghc utility when building either of these with
7 * an old version of GHC.
9 * shell-less system Runtime Support (see System.Cmd.rawSystem).
12 /* The itimer stuff in this module is non-posix */
13 /* #include "PosixSource.h" */
15 /* This ifdef is required because this source might be compiled by an
16 * external compiler. See ghc/utils/runghc/rawSystem.c for example.
18 #ifdef __GLASGOW_HASKELL__
19 #if __GLASGOW_HASKELL__ < 603
22 #include "ghcconfig.h"
35 #ifdef HAVE_SYS_WAIT_H
39 # ifdef TIME_WITH_SYS_TIME
40 # include <sys/time.h>
43 # ifdef HAVE_SYS_TIME_H
44 # include <sys/time.h>
52 #if defined(mingw32_TARGET_OS)
64 #if defined(mingw32_TARGET_OS)
65 /* -------------------- WINDOWS VERSION --------------------- */
71 PROCESS_INFORMATION pInfo;
74 ZeroMemory(&sInfo, sizeof(sInfo));
75 sInfo.cb = sizeof(sInfo);
77 if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &sInfo, &pInfo)) {
78 /* The 'TRUE' says that the created process should share
79 handles with the current process. This is vital to ensure
80 that error messages sent to stderr actually appear on the screen.
81 Since we are going to wait for the process to terminate anyway,
82 there is no problem with such sharing. */
84 errno = EINVAL; // ToDo: wrong, caller should use GetLastError()
87 WaitForSingleObject(pInfo.hProcess, INFINITE);
88 if (GetExitCodeProcess(pInfo.hProcess, &retCode) == 0) {
89 errno = EINVAL; // ToDo: wrong, caller should use GetLastError()
93 CloseHandle(pInfo.hProcess);
94 CloseHandle(pInfo.hThread);
99 /* -------------------- UNIX VERSION --------------------- */
102 rawSystem(HsAddr cmd, HsAddr args)
107 switch(pid = fork()) {
114 #ifdef HAVE_SETITIMER
115 /* Reset the itimers in the child, so it doesn't get plagued
116 * by SIGVTALRM interrupts.
118 struct timeval tv_null = { 0, 0 };
119 struct itimerval itv;
120 itv.it_interval = tv_null;
121 itv.it_value = tv_null;
122 setitimer(ITIMER_REAL, &itv, NULL);
123 setitimer(ITIMER_VIRTUAL, &itv, NULL);
124 setitimer(ITIMER_PROF, &itv, NULL);
133 while (waitpid(pid, &wstat, 0) < 0) {
134 if (errno != EINTR) {
139 if (WIFEXITED(wstat))
140 return WEXITSTATUS(wstat);
141 else if (WIFSIGNALED(wstat)) {
145 /* This should never happen */