Commit 7ea43827 authored by Clemens Fruhwirth's avatar Clemens Fruhwirth

Refactor cross-plattform process spawning from ghc-inplace into shell-tools.c

parent 7f54dbc0
......@@ -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 $@
......
#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
#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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment