From 7bd848eb6bc1885c696fe84ed2d4ae7fee8c01bd Mon Sep 17 00:00:00 2001 From: Peer Sommerlund Date: Thu, 11 Oct 2007 16:45:02 +0100 Subject: [PATCH] no-fork.p Child processes on Windows Functionality similar to fork() and system() are quite different on Windows. - Disable open_ctx_forked since fork is not available - Implement my_system with CreateProcess --- cvs_direct.c | 4 ++++ cvsps.c | 3 +++ util.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/cvs_direct.c b/cvs_direct.c index cff0ffa..1e582b8 100644 --- a/cvs_direct.c +++ b/cvs_direct.c @@ -261,6 +261,9 @@ static CvsServerCtx * open_ctx_pserver(CvsServerCtx * ctx, const char * p_root) static CvsServerCtx * open_ctx_forked(CvsServerCtx * ctx, const char * p_root) { +#ifdef __MINGW32__ + debug(DEBUG_SYSERROR, "cvs_direct: fork not supported on MinGW"); +#else char root[PATH_MAX]; char * p = root, *tok, *tok2, *rep; char execcmd[PATH_MAX]; @@ -357,6 +360,7 @@ static CvsServerCtx * open_ctx_forked(CvsServerCtx * ctx, const char * p_root) close(to_cvs[1]); out_free_err: free(ctx); +#endif return NULL; } diff --git a/cvsps.c b/cvsps.c index 5a74b12..bf0ce85 100644 --- a/cvsps.c +++ b/cvsps.c @@ -10,6 +10,9 @@ #include #ifdef __MINGW32__ #include +#define WEXITSTATUS(status) (status) +/* WIFSIGNALED is not entierly correct, but almost */ +#define WIFSIGNALED(status) ((status)==-1) #else #include #endif diff --git a/util.c b/util.c index db335b0..79a44e8 100644 --- a/util.c +++ b/util.c @@ -11,6 +11,7 @@ #include #ifdef __MINGW32__ #include +#include #else #include #endif @@ -246,9 +247,60 @@ void timing_stop(const char * msg) extern char ** environ; -/* taken from the linux manual page for system */ -int my_system (const char *command) +/* taken from the linux manual page for system + See http://linux.die.net/man/3/system + */ +int my_system (const char *command) { +#ifdef __MINGW32__ + /* Launch child process */ + STARTUPINFO si; + ZeroMemory( &si, sizeof( si ) ); + si.cb = sizeof( si ); + PROCESS_INFORMATION pi; + ZeroMemory( &pi, sizeof( pi ) ); + if( !CreateProcess( + 0, /* module name (0 means use first token in command line) */ + (char*)command, /* command line */ + 0, /* process security attributes */ + 0, /* primary thread security attributes */ + TRUE, /* handles are inherited */ + 0, /* creation flags (none) */ + 0, /* use parent's environment */ + 0, /* use parent's current directory */ + &si, /* STARTUPINFO pointer */ + &pi /* receives PROCESS_INFORMATION */ + ) ) { + debug(DEBUG_APPERROR, "CreateProcess failed.\n command line was: %s", command); + return -1; + } + + /* Wait for child process to exit */ + DWORD timeout = 10*1000; /* milliseconds */ + DWORD ret = WaitForSingleObject( pi.hProcess, timeout ); + if (ret == WAIT_OBJECT_0) { + /* OK. Child has exited */ + } + else if (ret == WAIT_FAILED) { + DWORD last_err = GetLastError(); + debug(DEBUG_APPERROR, "WaitForSingleObject failed.\n GetLastError returned : %d", last_err); + return -1; + } + else { + debug(DEBUG_APPERROR, "WaitForSingleObject returned %x", ret); + return -1; + } + + /* Retrieve exit code */ + DWORD exit_code; + if( !GetExitCodeProcess( pi.hProcess, &exit_code ) ) { + DWORD last_err = GetLastError(); + debug(DEBUG_APPERROR, "GetExitCodeProcess failed.\n GetLastError returned : %d", last_err); + return -1; + } + + return exit_code; +#else int pid, status; if (command == 0) @@ -272,6 +324,7 @@ int my_system (const char *command) } else return status; } while(1); +#endif } int escape_filename(char * dst, int len, const char * src) -- 2.11.4.GIT