3 * ghc wrapper for Win32 only
5 * This wrapper simply invokes ghc.exe
7 * (c) The GHC Team 2001
9 * ghc.exe is searched for using the 'normal' search rules
10 * for DLLs / EXEs (i.e., first in the same dir as this wrapper,
11 * then system dirs, then PATH).
15 * MSVC: cl /o ghc.exe /c ghc.c
16 * mingw: gcc -o ghc.exe ghc.c
18 * If you want to associate your own icon with the wrapper,
19 * here's how to do it:
21 * * Create a one-line .rc file, ghc.rc (say), containing
23 * (subst the string literal for the name of your icon file).
24 * * Compile it up (assuming the .ico file is in the same dir
27 * MSVC: rc /i. /fo ghc.res ghc.rc
28 * mingw: windres -o ghc.res -i ghc.rc -O coff
30 * * Add the resulting .res file to the link line of the wrapper:
32 * MSVC: cl /o ghc.exe /c ghc.c ghc.res
33 * mingw: gcc -o ghc.exe ghc.c ghc.res
45 #define BINARY_NAME "ghc.exe"
47 #define errmsg(msg) fprintf(stderr, msg "\n"); fflush(stderr)
48 #define errmsg1(msg,val) fprintf(stderr, msg "\n",val); fflush(stderr)
51 main(int argc, char** argv)
53 TCHAR binPath[FILENAME_MAX+1];
54 TCHAR binPathShort[MAX_PATH+1];
55 DWORD dwSize = FILENAME_MAX;
60 unsigned int cmdline_len = 0;
65 PROCESS_INFORMATION pi;
67 ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
68 ZeroMemory(&si, sizeof(STARTUPINFO));
69 si.cb = sizeof(STARTUPINFO);
71 /* Locate the binary we want to start up */
72 if ( !SearchPath(NULL,
78 errmsg1("%s: Unable to locate ghc.exe", argv[0]);
83 /* Turn the path into short form - LFN form causes problems
84 when passed in argv[0]. */
85 if ( !(GetShortPathName(binPath, binPathShort, dwSize)) ) {
86 errmsg1("%s: Unable to locate ghc.exe", argv[0]);
90 /* Compute length of the flattened 'argv' */
92 /* Note: play it safe and quote all argv strings */
93 cmdline_len += 1 + strlen(argv[i]) + 2;
95 new_cmdline = (char*)malloc(sizeof(char) * (cmdline_len + 1));
97 errmsg1("%s: failed to start up ghc.exe; insufficient memory", argv[0]);
102 for(i=1;i<argc;i++) {
113 /* Note: Used to use _spawnv(_P_WAIT, ...) here, but it suffered
114 from the parent intercepting console events such as Ctrl-C,
115 which it shouldn't. Installing an ignore-all console handler
116 didn't do the trick either.
118 Irrespective of this issue, using CreateProcess() is preferable,
119 as it makes this wrapper work on both mingw and cygwin.
122 fprintf(stderr, "Invoking ghc: %s %s\n", binPathShort, new_cmdline); fflush(stderr);
124 if (!CreateProcess(binPathShort,
129 0, /* dwCreationFlags */
130 NULL, /* lpEnvironment */
131 NULL, /* lpCurrentDirectory */
132 &si, /* lpStartupInfo */
134 errmsg1("Unable to start ghc.exe (error code: %lu)", GetLastError());
137 /* Disable handling of console events in the parent by dropping its
138 * connection to the console. This has the (minor) downside of not being
139 * able to subsequently emit any error messages to the console.
143 switch (WaitForSingleObject(pi.hProcess, INFINITE) ) {
148 /* in the event we get any hard errors, bring the child to a halt. */
149 TerminateProcess(pi.hProcess,1);