16 int run(char *this, char *program, int argc, char **argv);
18 void error(const char *fmt, ...) {
21 vfprintf(stderr, fmt, argp);
23 fprintf(stderr, "\n");
27 int main(int argc, char **argv) {
29 args = malloc(sizeof(char *) * (argc + 3));
31 fprintf(stderr, "Malloc failed\n");
35 args[1] = "-B" TOP_ABS;
36 args[2] = "-fhardwire-lib-paths";
37 if ((argc >= 2) && (strcmp(argv[1], "-v") == 0)) {
38 printf("Using %s %s %s\n", args[0], args[1], args[2]);
41 memcpy(args + 3, argv + 1, sizeof(char *) * (argc - 1));
43 return run(argv[0], GHC_PATH, argc + 2, args);
47 int run(char *this, char *program, int argc, char** argv) {
49 return 1; /* Not reached */
52 int run(char *this, char *program, int argc, char** argv) {
53 TCHAR programShort[MAX_PATH+1];
60 unsigned int cmdline_len;
63 PROCESS_INFORMATION pi;
65 ZeroMemory(&si, sizeof(STARTUPINFO));
66 ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
68 si.cb = sizeof(STARTUPINFO);
71 /* Turn the path into short form - LFN form causes problems
72 when passed in argv[0]. */
73 if ( !(GetShortPathName(program, programShort, dwSize)) ) {
74 error("%s: Unable to locate %s", this, program);
78 /* Compute length of the flattened 'argv', including spaces! */
80 for(i = 1; i < argc; i++) {
81 /* Note: play it safe and quote all argv strings */
82 cmdline_len += 1 + strlen(argv[i]) + 2;
84 new_cmdline = (char*)malloc(sizeof(char) * (cmdline_len + 1));
86 error("%s: failed to start up ghc.exe; insufficient memory", this);
91 for(i = 1; i < argc; i++) {
102 /* Note: Used to use _spawnv(_P_WAIT, ...) here, but it suffered
103 from the parent intercepting console events such as Ctrl-C,
104 which it shouldn't. Installing an ignore-all console handler
105 didn't do the trick either.
107 Irrespective of this issue, using CreateProcess() is preferable,
108 as it makes this wrapper work on both mingw and cygwin.
111 fprintf(stderr, "Invoking ghc: %s %s\n", programShort, new_cmdline);
114 if (!CreateProcess(programShort,
119 0, /* dwCreationFlags */
120 NULL, /* lpEnvironment */
121 NULL, /* lpCurrentDirectory */
122 &si, /* lpStartupInfo */
124 error("%s: Unable to start ghc.exe (error code: %lu)",
125 this, GetLastError());
128 /* Disable handling of console events in the parent by dropping its
129 * connection to the console. This has the (minor) downside of not being
130 * able to subsequently emit any error messages to the console.
134 switch (WaitForSingleObject(pi.hProcess, INFINITE) ) {
136 if (GetExitCodeProcess(pi.hProcess, &dwExitCode)) {
144 /* in the event we get any hard errors, bring the child
146 TerminateProcess(pi.hProcess, 1);