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]);
40 memcpy(args + 3, argv + 1, sizeof(char *) * (argc - 1));
42 return run(argv[0], GHC_PATH, argc + 2, args);
46 int run(char *this, char *program, int argc, char** argv) {
48 return 1; /* Not reached */
51 int run(char *this, char *program, int argc, char** argv) {
52 TCHAR programShort[MAX_PATH+1];
58 unsigned int cmdline_len;
61 PROCESS_INFORMATION pi;
63 ZeroMemory(&si, sizeof(STARTUPINFO));
64 ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
66 si.cb = sizeof(STARTUPINFO);
69 /* Turn the path into short form - LFN form causes problems
70 when passed in argv[0]. */
71 if ( !(GetShortPathName(program, programShort, dwSize)) ) {
72 error("%s: Unable to locate %s", this, program);
76 /* Compute length of the flattened 'argv', including spaces! */
78 for(i = 1; i < argc; i++) {
79 /* Note: play it safe and quote all argv strings */
80 cmdline_len += 1 + strlen(argv[i]) + 2;
82 new_cmdline = (char*)malloc(sizeof(char) * (cmdline_len + 1));
84 error("%s: failed to start up ghc.exe; insufficient memory", this);
89 for(i = 1; i < argc; i++) {
100 /* Note: Used to use _spawnv(_P_WAIT, ...) here, but it suffered
101 from the parent intercepting console events such as Ctrl-C,
102 which it shouldn't. Installing an ignore-all console handler
103 didn't do the trick either.
105 Irrespective of this issue, using CreateProcess() is preferable,
106 as it makes this wrapper work on both mingw and cygwin.
109 fprintf(stderr, "Invoking ghc: %s %s\n", programShort, new_cmdline);
112 if (!CreateProcess(programShort,
117 0, /* dwCreationFlags */
118 NULL, /* lpEnvironment */
119 NULL, /* lpCurrentDirectory */
120 &si, /* lpStartupInfo */
122 error("%s: Unable to start ghc.exe (error code: %lu)",
123 this, GetLastError());
126 /* Disable handling of console events in the parent by dropping its
127 * connection to the console. This has the (minor) downside of not being
128 * able to subsequently emit any error messages to the console.
132 switch (WaitForSingleObject(pi.hProcess, INFINITE) ) {
137 /* in the event we get any hard errors, bring the child
139 TerminateProcess(pi.hProcess, 1);