X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=win32%2Fwin32.c;h=8ffffd53720d2a505be08ad130fac938d2a6ceba;hb=8bb8fffa0cd55f5ec6c1b52236f8c5baff79c3c6;hp=4c36cc7806c569154963e9017d57bf76fc8e9b85;hpb=7b11e424f236ec2e8ad476d91917c44ed3b5fba9;p=p5sagit%2Fp5-mst-13.2.git diff --git a/win32/win32.c b/win32/win32.c index 4c36cc7..8ffffd5 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -7,7 +7,7 @@ * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. */ - +#define PERLIO_NOT_STDIO 0 #define WIN32_LEAN_AND_MEAN #define WIN32IO_IS_STDIO #include @@ -25,7 +25,6 @@ /* #include "config.h" */ -#define PERLIO_NOT_STDIO 0 #if !defined(PERLIO_IS_STDIO) && !defined(USE_SFIO) #define PerlIO FILE #endif @@ -1690,6 +1689,76 @@ win32_uname(struct utsname *name) return 0; } +int +win32_internal_wait(int *status, DWORD timeout) +{ + /* XXX this wait emulation only knows about processes + * spawned via win32_spawnvp(P_NOWAIT, ...). + */ + dTHX; + int i, retval; + DWORD exitcode, waitcode; + +#ifdef USE_ITHREADS + if (w32_num_pseudo_children) { + waitcode = WaitForMultipleObjects(w32_num_pseudo_children, + w32_pseudo_child_handles, + FALSE, + timeout); + /* Time out here if there are no other children to wait for. */ + if (waitcode == WAIT_TIMEOUT) { + if (!w32_num_children) { + return 0; + } + } + else if (waitcode != WAIT_FAILED) { + if (waitcode >= WAIT_ABANDONED_0 + && waitcode < WAIT_ABANDONED_0 + w32_num_pseudo_children) + i = waitcode - WAIT_ABANDONED_0; + else + i = waitcode - WAIT_OBJECT_0; + if (GetExitCodeThread(w32_pseudo_child_handles[i], &exitcode)) { + *status = (int)((exitcode & 0xff) << 8); + retval = (int)w32_pseudo_child_pids[i]; + remove_dead_pseudo_process(i); + return -retval; + } + } + } +#endif + + if (!w32_num_children) { + errno = ECHILD; + return -1; + } + + /* if a child exists, wait for it to die */ + waitcode = WaitForMultipleObjects(w32_num_children, + w32_child_handles, + FALSE, + timeout); + if (waitcode == WAIT_TIMEOUT) { + return 0; + } + if (waitcode != WAIT_FAILED) { + if (waitcode >= WAIT_ABANDONED_0 + && waitcode < WAIT_ABANDONED_0 + w32_num_children) + i = waitcode - WAIT_ABANDONED_0; + else + i = waitcode - WAIT_OBJECT_0; + if (GetExitCodeProcess(w32_child_handles[i], &exitcode) ) { + *status = (int)((exitcode & 0xff) << 8); + retval = (int)w32_child_pids[i]; + remove_dead_process(i); + return retval; + } + } + +FAILED: + errno = GetLastError(); + return -1; +} + DllExport int win32_waitpid(int pid, int *status, int flags) { @@ -1698,7 +1767,7 @@ win32_waitpid(int pid, int *status, int flags) int retval = -1; long child; if (pid == -1) /* XXX threadid == 1 ? */ - return win32_wait(status); + return win32_internal_wait(status, timeout); #ifdef USE_ITHREADS else if (pid < 0) { child = find_pseudo_pid(-pid); @@ -1774,62 +1843,7 @@ alien_process: DllExport int win32_wait(int *status) { - /* XXX this wait emulation only knows about processes - * spawned via win32_spawnvp(P_NOWAIT, ...). - */ - dTHX; - int i, retval; - DWORD exitcode, waitcode; - -#ifdef USE_ITHREADS - if (w32_num_pseudo_children) { - waitcode = WaitForMultipleObjects(w32_num_pseudo_children, - w32_pseudo_child_handles, - FALSE, - INFINITE); - if (waitcode != WAIT_FAILED) { - if (waitcode >= WAIT_ABANDONED_0 - && waitcode < WAIT_ABANDONED_0 + w32_num_pseudo_children) - i = waitcode - WAIT_ABANDONED_0; - else - i = waitcode - WAIT_OBJECT_0; - if (GetExitCodeThread(w32_pseudo_child_handles[i], &exitcode)) { - *status = (int)((exitcode & 0xff) << 8); - retval = (int)w32_pseudo_child_pids[i]; - remove_dead_pseudo_process(i); - return -retval; - } - } - } -#endif - - if (!w32_num_children) { - errno = ECHILD; - return -1; - } - - /* if a child exists, wait for it to die */ - waitcode = WaitForMultipleObjects(w32_num_children, - w32_child_handles, - FALSE, - INFINITE); - if (waitcode != WAIT_FAILED) { - if (waitcode >= WAIT_ABANDONED_0 - && waitcode < WAIT_ABANDONED_0 + w32_num_children) - i = waitcode - WAIT_ABANDONED_0; - else - i = waitcode - WAIT_OBJECT_0; - if (GetExitCodeProcess(w32_child_handles[i], &exitcode) ) { - *status = (int)((exitcode & 0xff) << 8); - retval = (int)w32_child_pids[i]; - remove_dead_process(i); - return retval; - } - } - -FAILED: - errno = GetLastError(); - return -1; + return win32_internal_wait(status, INFINITE); } #ifndef PERL_IMPLICIT_CONTEXT @@ -3192,23 +3206,25 @@ create_command_line(char *cname, STRLEN clen, const char * const *args) if (!curlen) { do_quote = 1; } + else if (quote_next) { + /* see if it really is multiple arguments pretending to + * be one and force a set of quotes around it */ + if (*find_next_space(arg)) + do_quote = 1; + } else if (!(arg[0] == '"' && curlen > 1 && arg[curlen-1] == '"')) { STRLEN i = 0; while (i < curlen) { if (isSPACE(arg[i])) { do_quote = 1; + } + else if (arg[i] == '"') { + do_quote = 0; break; } i++; } } - else if (quote_next) { - /* ok, we know the argument already has quotes; see if it - * really is multiple arguments pretending to be one and - * force a set of quotes around it */ - if (*find_next_space(arg)) - do_quote = 1; - } } if (do_quote) @@ -3235,7 +3251,7 @@ create_command_line(char *cname, STRLEN clen, const char * const *args) extra_quotes = TRUE; } else { - /* single argument, force quoting if unquoted */ + /* single argument, force quoting if it has spaces */ quote_next = TRUE; } }