integrate change#18377 from maint-5.6 branch
Gurusamy Sarathy [Tue, 31 Dec 2002 04:07:56 +0000 (04:07 +0000)]
       change#17566 needs to be more defensive about win32_dup2()
       itself calling SetStdHandle() (at least MSVCRT does this)
p4raw-link: @18377 on //depot/maint-5.6/perl: 0da6bbac9a33d465c32cde5247be045d49864a2d
p4raw-link: @17566 on //depot/maint-5.6/perl: c7efefc2a43b65746e10207fe89bc47b7f7c27ea

p4raw-id: //depot/perl@18378
p4raw-integrated: from //depot/maint-5.6/perl@18376 'merge in'
win32/win32.c (@18329..)

win32/win32.c

index 44642e6..c03c3be 100644 (file)
@@ -2750,6 +2750,12 @@ win32_popen(const char *command, const char *mode)
     if ((oldfd = win32_dup(stdfd)) == -1)
         goto cleanup;
 
+    /* save the old std handle (this needs to happen before the
+     * dup2(), since that might call SetStdHandle() too) */
+    OP_REFCNT_LOCK;
+    lock_held = 1;
+    old_h = GetStdHandle(nhandle);
+
     /* make stdfd go to child end of pipe (implicitly closes stdfd) */
     /* stdfd will be inherited by the child */
     if (win32_dup2(p[child], stdfd) == -1)
@@ -2758,10 +2764,7 @@ win32_popen(const char *command, const char *mode)
     /* close the child end in parent */
     win32_close(p[child]);
 
-    /* save the old std handle, and set the std handle */
-    OP_REFCNT_LOCK;
-    lock_held = 1;
-    old_h = GetStdHandle(nhandle);
+    /* set the new std handle (in case dup2() above didn't) */
     SetStdHandle(nhandle, (HANDLE)_get_osfhandle(stdfd));
 
     /* start the child */
@@ -2770,17 +2773,18 @@ win32_popen(const char *command, const char *mode)
        if ((childpid = do_spawn_nowait((char*)command)) == -1)
            goto cleanup;
 
-       /* restore the old std handle */
+       /* revert stdfd to whatever it was before */
+       if (win32_dup2(oldfd, stdfd) == -1)
+           goto cleanup;
+
+       /* restore the old std handle (this needs to happen after the
+        * dup2(), since that might call SetStdHandle() too */
        if (lock_held) {
            SetStdHandle(nhandle, old_h);
            OP_REFCNT_UNLOCK;
            lock_held = 0;
        }
 
-       /* revert stdfd to whatever it was before */
-       if (win32_dup2(oldfd, stdfd) == -1)
-           goto cleanup;
-
        /* close saved handle */
        win32_close(oldfd);