on windows, the return values from wait() and waitpid() don't
[p5sagit/p5-mst-13.2.git] / win32 / win32.c
index 6e33616..56ebdaf 100644 (file)
@@ -53,7 +53,6 @@
 #else
 #include <utime.h>
 #endif
-
 #ifdef __GNUC__
 /* Mingw32 defaults to globing command line 
  * So we turn it off like this:
@@ -1645,13 +1644,17 @@ win32_waitpid(int pid, int *status, int flags)
        long child = find_pseudo_pid(-pid);
        if (child >= 0) {
            HANDLE hThread = w32_pseudo_child_handles[child];
-           DWORD waitcode = WaitForSingleObject(hThread, INFINITE);
-           if (waitcode != WAIT_FAILED) {
+           DWORD timeout = (flags & WNOHANG) ? 0 : INFINITE;
+           DWORD waitcode = WaitForSingleObject(hThread, timeout);
+           if (waitcode == WAIT_TIMEOUT) {
+               return 0;
+           }
+           else if (waitcode != WAIT_FAILED) {
                if (GetExitCodeThread(hThread, &waitcode)) {
                    *status = (int)((waitcode & 0xff) << 8);
                    retval = (int)w32_pseudo_child_pids[child];
                    remove_dead_pseudo_process(child);
-                   return retval;
+                   return -retval;
                }
            }
            else
@@ -1663,14 +1666,18 @@ win32_waitpid(int pid, int *status, int flags)
        long child = find_pid(pid);
        if (child >= 0) {
            HANDLE hProcess = w32_child_handles[child];
-           DWORD waitcode = WaitForSingleObject(hProcess, INFINITE);
-           if (waitcode != WAIT_FAILED) {
-               if (GetExitCodeProcess(hProcess, &waitcode)) {
-                   *status = (int)((waitcode & 0xff) << 8);
-                   retval = (int)w32_child_pids[child];
-                   remove_dead_process(child);
-                   return retval;
-               }
+           DWORD timeout = (flags & WNOHANG) ? 0 : INFINITE;
+           DWORD waitcode = WaitForSingleObject(hProcess, timeout);
+           if (waitcode == WAIT_TIMEOUT) {
+               return 0;
+           }
+           else if (waitcode != WAIT_FAILED) {
+                if (GetExitCodeProcess(hProcess, &waitcode)) {
+                    *status = (int)((waitcode & 0xff) << 8);
+                    retval = (int)w32_child_pids[child];
+                    remove_dead_process(child);
+                    return retval;
+                }
            }
            else
                errno = ECHILD;
@@ -1713,7 +1720,7 @@ win32_wait(int *status)
                *status = (int)((exitcode & 0xff) << 8);
                retval = (int)w32_pseudo_child_pids[i];
                remove_dead_pseudo_process(i);
-               return retval;
+               return -retval;
            }
        }
     }
@@ -2393,9 +2400,9 @@ win32_popen(const char *command, const char *mode)
        /* close saved handle */
        win32_close(oldfd);
 
-       MUTEX_LOCK(&PL_fdpid_mutex);
+       LOCK_FDPID_MUTEX;
        sv_setiv(*av_fetch(w32_fdpid, p[parent], TRUE), childpid);
-       MUTEX_UNLOCK(&PL_fdpid_mutex);
+       UNLOCK_FDPID_MUTEX;
 
        /* set process id so that it can be returned by perl's open() */
        PL_forkprocess = childpid;
@@ -2431,9 +2438,9 @@ win32_pclose(FILE *pf)
     int childpid, status;
     SV *sv;
 
-    MUTEX_LOCK(&PL_fdpid_mutex);
+    LOCK_FDPID_MUTEX;
     sv = *av_fetch(w32_fdpid, win32_fileno(pf), TRUE);
-    MUTEX_UNLOCK(&PL_fdpid_mutex);
+
     if (SvIOK(sv))
        childpid = SvIVX(sv);
     else
@@ -2446,6 +2453,7 @@ win32_pclose(FILE *pf)
 
     win32_fclose(pf);
     SvIVX(sv) = 0;
+    UNLOCK_FDPID_MUTEX;
 
     if (win32_waitpid(childpid, &status, 0) == -1)
         return -1;