]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
- changed windows pclose to make sure we don't return before the
authorFredrik Lundh <fredrik@pythonware.com>
Wed, 26 Jul 2000 17:29:12 +0000 (17:29 +0000)
committerFredrik Lundh <fredrik@pythonware.com>
Wed, 26 Jul 2000 17:29:12 +0000 (17:29 +0000)
  underlying process has terminated
  (bug fix from David Bolen)

Modules/posixmodule.c

index 5c94e29ab7cfe29b0527996b0495ec6fec8c5c1e..fe63689eef96fb59f6e2a24423117ef6d134908b 100644 (file)
@@ -2595,31 +2595,43 @@ _PyPopen(char *cmdstring, int mode, int n)
  */
 static int _PyPclose(FILE *file)
 {
-       int result = 0;
+       int result;
        DWORD exit_code;
        HANDLE hProcess;
        PyObject *hProcessObj, *fileObj;
    
+       /* Close the file handle first, to ensure it can't block the
+        * child from exiting when we wait for it below.
+        */
+       result = fclose(file);
+
        if (_PyPopenProcs) {
                fileObj = PyLong_FromVoidPtr(file);
                if (fileObj) {
                        hProcessObj = PyDict_GetItem(_PyPopenProcs, fileObj);
                        if (hProcessObj) {
                                hProcess = PyLong_AsVoidPtr(hProcessObj);
-                               if (GetExitCodeProcess(hProcess, &exit_code)) {
+                               if (result != EOF &&
+                                   WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
+                                   GetExitCodeProcess(hProcess, &exit_code)) {
                                        /* Possible truncation here in 16-bit environments, but
                                         * real exit codes are just the lower byte in any event.
                                         */
                                        result = exit_code;
-                                       if (result == STILL_ACTIVE)
-                                               result = 0; /* Minimize confusion */
                                } else {
-                                       /* No good way to bubble up an error, so instead we just
-                                        * return the Windows last error shifted above standard
-                                        * exit codes.  This will truncate in 16-bits but should
-                                        * be fine in 32 and at least distinguishes the problem.
+                                       /* Indicate failure - this will cause the file object
+                                        * to raise an I/O error and translate the last Win32
+                                        * error code from errno.  We do have a problem with
+                                        * last errors that overlap the normal errno table,
+                                        * but that's a consistent problem with the file object.
                                         */
-                                       result = (GetLastError() << 8);
+                                       if (result != EOF) {
+                                               /* If the error wasn't from the fclose(), then
+                                                * set errno for the file object error handling.
+                                                */
+                                               errno = GetLastError();
+                                       }
+                                       result = -1;
                                }
 
                                /* Free up the native handle at this point */
@@ -2635,7 +2647,6 @@ static int _PyPclose(FILE *file)
                } /* if fileObj */
        } /* if _PyPopenProcs */
 
-       fclose(file);
        return result;
 }
 #else