diff options
author | Fredrik Lundh <fredrik@pythonware.com> | 2000-07-26 17:29:12 (GMT) |
---|---|---|
committer | Fredrik Lundh <fredrik@pythonware.com> | 2000-07-26 17:29:12 (GMT) |
commit | 2031893842fe8dfb4f166d7221006c70c62448b7 (patch) | |
tree | f6b26bdf8185f09de3bf15fda49008ec60c233f1 | |
parent | 0765fe3a053a67f52fedbe8e9adb8410cb931957 (diff) | |
download | cpython-2031893842fe8dfb4f166d7221006c70c62448b7.zip cpython-2031893842fe8dfb4f166d7221006c70c62448b7.tar.gz cpython-2031893842fe8dfb4f166d7221006c70c62448b7.tar.bz2 |
- changed windows pclose to make sure we don't return before the
underlying process has terminated
(bug fix from David Bolen)
-rw-r--r-- | Modules/posixmodule.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 5c94e29..fe63689 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -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 |