6 #include <ghcplatform.h>
16 void error(const char *fmt, ...) {
19 vfprintf(stderr, fmt, argp);
24 #ifndef mingw32_HOST_OS
25 int run(char *this, char *program, int argc, char** argv) {
27 error("%s: Unable to start %s: ", this, program);
29 return 1; /* Not reached */
32 int run(char *this, char *program, int argc, char** argv) {
33 TCHAR programShort[MAX_PATH+1];
40 unsigned int cmdline_len;
43 PROCESS_INFORMATION pi;
45 ZeroMemory(&si, sizeof(STARTUPINFO));
46 ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
48 si.cb = sizeof(STARTUPINFO);
51 /* Turn the path into short form - LFN form causes problems
52 when passed in argv[0]. */
53 if ( !(GetShortPathName(program, programShort, dwSize)) ) {
54 error("%s: Unable to locate %s\n", this, program);
58 /* Compute length of the flattened 'argv', including spaces! */
60 for(i = 1; i < argc; i++) {
61 /* Note: play it safe and quote all argv strings */
62 cmdline_len += 1 + strlen(argv[i]) + 2;
64 new_cmdline = (char*)malloc(sizeof(char) * (cmdline_len + 1));
66 error("%s: failed to start up ghc.exe; insufficient memory\n", this);
71 for(i = 1; i < argc; i++) {
82 /* Note: Used to use _spawnv(_P_WAIT, ...) here, but it suffered
83 from the parent intercepting console events such as Ctrl-C,
84 which it shouldn't. Installing an ignore-all console handler
85 didn't do the trick either.
87 Irrespective of this issue, using CreateProcess() is preferable,
88 as it makes this wrapper work on both mingw and cygwin.
91 fprintf(stderr, "Invoking ghc: %s %s\n", programShort, new_cmdline);
94 if (!CreateProcess(programShort,
99 0, /* dwCreationFlags */
100 NULL, /* lpEnvironment */
101 NULL, /* lpCurrentDirectory */
102 &si, /* lpStartupInfo */
104 error("%s: Unable to start ghc.exe (error code: %lu)\n",
105 this, GetLastError());
108 /* Disable handling of console events in the parent by dropping its
109 * connection to the console. This has the (minor) downside of not being
110 * able to subsequently emit any error messages to the console.
114 switch (WaitForSingleObject(pi.hProcess, INFINITE) ) {
116 if (GetExitCodeProcess(pi.hProcess, &dwExitCode)) {
124 /* in the event we get any hard errors, bring the child
126 TerminateProcess(pi.hProcess, 1);