Refactor cross-plattform process spawning from ghc-inplace into shell-tools.c
authorClemens Fruhwirth <clemens@endorphin.org>
Thu, 10 Jan 2008 09:07:21 +0000 (09:07 +0000)
committerClemens Fruhwirth <clemens@endorphin.org>
Thu, 10 Jan 2008 09:07:21 +0000 (09:07 +0000)
compiler/Makefile
compiler/ghc-inplace.c
includes/shell-tools.c [new file with mode: 0644]

index 04c7778..ceb47b0 100644 (file)
@@ -745,16 +745,13 @@ SRC_LD_OPTS += -no-link-chk
 
 INPLACE_SRC  = $(odir)/ghc-inplace.c
 INPLACE_PROG = $(odir)/ghc-inplace$(_way)$(exeext)
+INPLACE_EXTRA_FLAGS = -I$(TOP)/includes
 EXCLUDED_C_SRCS += ghc-inplace.c
 
 CLEAN_FILES += $(INPLACE_SRC)
 
 GHC_PATH=$(FPTOOLS_TOP_ABS)/$(GHC_COMPILER_DIR_REL)/$(GHC_PROG)$(exeext)
 
-ifeq "$(HOSTPLATFORM)" "i386-unknown-mingw32"
-INPLACE_EXTRA_FLAGS = -optc-DWINDOWS
-endif
-
 $(INPLACE_PROG): ghc-inplace.c
        $(SED) -e "s@GHC_PATH@$(GHC_PATH)@g" -e "s@TOP_ABS@$(FPTOOLS_TOP_ABS)@g" < $< > $(INPLACE_SRC)
        $(HC) -cpp $(INPLACE_EXTRA_FLAGS) $(INPLACE_SRC) -o $@
index d7599ea..59ceae6 100644 (file)
@@ -1,28 +1,9 @@
-
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-
-#ifdef WINDOWS
-#include <windows.h>
-#include <process.h>
-#include <malloc.h>
-#include <signal.h>
-#include <io.h>
-#endif
-
-int run(char *this, char *program, int argc, char **argv);
-
-void error(const char *fmt, ...) {
-    va_list argp;
-    va_start(argp, fmt);
-    vfprintf(stderr, fmt, argp);
-    va_end(argp);
-    fprintf(stderr, "\n");
-    fflush(stderr);
-}
+#include <shell-tools.c>
 
 int main(int argc, char **argv) {
     char **args;
@@ -45,112 +26,3 @@ int main(int argc, char **argv) {
                argc + 2,
                args);
 }
-
-#ifndef WINDOWS
-int run(char *this, char *program, int argc, char** argv) {
-    execv(program, argv);
-    return 1; /* Not reached */
-}
-#else
-int run(char *this, char *program, int argc, char** argv) {
-    TCHAR  programShort[MAX_PATH+1];
-    DWORD  dwSize;
-    DWORD  dwExitCode;
-    int    i;
-    char*  new_cmdline;
-    char   *ptr;
-    char   *src;
-    unsigned int cmdline_len;
-
-    STARTUPINFO si;
-    PROCESS_INFORMATION pi;
-  
-    ZeroMemory(&si, sizeof(STARTUPINFO));
-    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
-
-    si.cb = sizeof(STARTUPINFO);
-
-    dwSize = MAX_PATH;
-    /* Turn the path into short form - LFN form causes problems
-       when passed in argv[0]. */
-    if ( !(GetShortPathName(program, programShort, dwSize)) ) {
-        error("%s: Unable to locate %s", this, program);
-        return 1;
-    }
-  
-    /* Compute length of the flattened 'argv', including spaces! */
-    cmdline_len = 0;
-    for(i = 1; i < argc; i++) {
-        /* Note: play it safe and quote all argv strings */
-        cmdline_len += 1 + strlen(argv[i]) + 2;
-    }
-    new_cmdline = (char*)malloc(sizeof(char) * (cmdline_len + 1));
-    if (!new_cmdline) {
-        error("%s: failed to start up ghc.exe; insufficient memory", this);
-        return 1;
-    }
-  
-    ptr = new_cmdline;
-    for(i = 1; i < argc; i++) {
-        *ptr++ = ' ';
-        *ptr++ = '"';
-        src = argv[i];
-        while(*src) {
-            *ptr++ = *src++;
-        }
-        *ptr++ = '"';
-    }
-    *ptr = '\0';
-  
-    /* Note: Used to use _spawnv(_P_WAIT, ...) here, but it suffered
-       from the parent intercepting console events such as Ctrl-C,
-       which it shouldn't. Installing an ignore-all console handler
-       didn't do the trick either.
-
-       Irrespective of this issue, using CreateProcess() is preferable,
-       as it makes this wrapper work on both mingw and cygwin.
-    */
-#if 0
-    fprintf(stderr, "Invoking ghc: %s %s\n", programShort, new_cmdline);
-    fflush(stderr);
-#endif
-    if (!CreateProcess(programShort,
-                       new_cmdline,
-                       NULL,
-                       NULL,
-                       TRUE,
-                       0, /* dwCreationFlags */
-                       NULL, /* lpEnvironment */
-                       NULL, /* lpCurrentDirectory */
-                       &si,  /* lpStartupInfo */
-                       &pi) ) {
-        error("%s: Unable to start ghc.exe (error code: %lu)",
-              this, GetLastError());
-        return 1;
-    }
-    /* Disable handling of console events in the parent by dropping its
-     * connection to the console. This has the (minor) downside of not being
-     * able to subsequently emit any error messages to the console.
-     */
-    FreeConsole();
-
-    switch (WaitForSingleObject(pi.hProcess, INFINITE) ) {
-        case WAIT_OBJECT_0:
-            if (GetExitCodeProcess(pi.hProcess, &dwExitCode)) {
-                return dwExitCode;
-            }
-            else {
-                return 1;
-            }
-        case WAIT_ABANDONED:
-        case WAIT_FAILED:
-            /* in the event we get any hard errors, bring the child
-               to a halt. */
-            TerminateProcess(pi.hProcess, 1);
-            return 1;
-        default:
-            return 1;
-    }
-}
-#endif
-
diff --git a/includes/shell-tools.c b/includes/shell-tools.c
new file mode 100644 (file)
index 0000000..29b2e2d
--- /dev/null
@@ -0,0 +1,133 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ghcplatform.h>
+
+#ifdef mingw32_HOST_OS
+#include <windows.h>
+#include <process.h>
+#include <malloc.h>
+#include <signal.h>
+#include <io.h>
+#endif
+
+void error(const char *fmt, ...) {
+    va_list argp;
+    va_start(argp, fmt);
+    vfprintf(stderr, fmt, argp);
+    va_end(argp);
+    fflush(stderr);
+}
+
+#ifndef mingw32_HOST_OS
+int run(char *this, char *program, int argc, char** argv) {
+    execv(program, argv);
+    error("%s: Unable to start %s: ", this, program);
+    perror("");
+    return 1; /* Not reached */
+}
+#else
+int run(char *this, char *program, int argc, char** argv) {
+    TCHAR  programShort[MAX_PATH+1];
+    DWORD  dwSize;
+    DWORD  dwExitCode;
+    int    i;
+    char*  new_cmdline;
+    char   *ptr;
+    char   *src;
+    unsigned int cmdline_len;
+
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+  
+    ZeroMemory(&si, sizeof(STARTUPINFO));
+    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
+
+    si.cb = sizeof(STARTUPINFO);
+
+    dwSize = MAX_PATH;
+    /* Turn the path into short form - LFN form causes problems
+       when passed in argv[0]. */
+    if ( !(GetShortPathName(program, programShort, dwSize)) ) {
+        error("%s: Unable to locate %s\n", this, program);
+        return 1;
+    }
+  
+    /* Compute length of the flattened 'argv', including spaces! */
+    cmdline_len = 0;
+    for(i = 1; i < argc; i++) {
+        /* Note: play it safe and quote all argv strings */
+        cmdline_len += 1 + strlen(argv[i]) + 2;
+    }
+    new_cmdline = (char*)malloc(sizeof(char) * (cmdline_len + 1));
+    if (!new_cmdline) {
+        error("%s: failed to start up ghc.exe; insufficient memory\n", this);
+        return 1;
+    }
+
+    ptr = new_cmdline;
+    for(i = 1; i < argc; i++) {
+        *ptr++ = ' ';
+        *ptr++ = '"';
+        src = argv[i];
+        while(*src) {
+            *ptr++ = *src++;
+        }
+        *ptr++ = '"';
+    }
+    *ptr = '\0';
+
+    /* Note: Used to use _spawnv(_P_WAIT, ...) here, but it suffered
+       from the parent intercepting console events such as Ctrl-C,
+       which it shouldn't. Installing an ignore-all console handler
+       didn't do the trick either.
+
+       Irrespective of this issue, using CreateProcess() is preferable,
+       as it makes this wrapper work on both mingw and cygwin.
+    */
+#if 0
+    fprintf(stderr, "Invoking ghc: %s %s\n", programShort, new_cmdline);
+    fflush(stderr);
+#endif
+    if (!CreateProcess(programShort,
+                       new_cmdline,
+                       NULL,
+                       NULL,
+                       TRUE,
+                       0, /* dwCreationFlags */
+                       NULL, /* lpEnvironment */
+                       NULL, /* lpCurrentDirectory */
+                       &si,  /* lpStartupInfo */
+                       &pi) ) {
+        error("%s: Unable to start ghc.exe (error code: %lu)\n",
+              this, GetLastError());
+        return 1;
+    }
+    /* Disable handling of console events in the parent by dropping its
+     * connection to the console. This has the (minor) downside of not being
+     * able to subsequently emit any error messages to the console.
+     */
+    FreeConsole();
+
+    switch (WaitForSingleObject(pi.hProcess, INFINITE) ) {
+        case WAIT_OBJECT_0:
+            if (GetExitCodeProcess(pi.hProcess, &dwExitCode)) {
+                return dwExitCode;
+            }
+            else {
+                return 1;
+            }
+        case WAIT_ABANDONED:
+        case WAIT_FAILED:
+            /* in the event we get any hard errors, bring the child
+               to a halt. */
+            TerminateProcess(pi.hProcess, 1);
+            return 1;
+        default:
+            return 1;
+    }
+}
+#endif
+