- changed windows pclose to make sure we don't return before the

underlying process has terminated
  (bug fix from David Bolen)
This commit is contained in:
Fredrik Lundh 2000-07-26 17:29:12 +00:00
parent 0765fe3a05
commit 2031893842
1 changed files with 21 additions and 10 deletions

View File

@ -2595,31 +2595,43 @@ _PyPopen(char *cmdstring, int mode, int n)
*/ */
static int _PyPclose(FILE *file) static int _PyPclose(FILE *file)
{ {
int result = 0; int result;
DWORD exit_code; DWORD exit_code;
HANDLE hProcess; HANDLE hProcess;
PyObject *hProcessObj, *fileObj; 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) { if (_PyPopenProcs) {
fileObj = PyLong_FromVoidPtr(file); fileObj = PyLong_FromVoidPtr(file);
if (fileObj) { if (fileObj) {
hProcessObj = PyDict_GetItem(_PyPopenProcs, fileObj); hProcessObj = PyDict_GetItem(_PyPopenProcs, fileObj);
if (hProcessObj) { if (hProcessObj) {
hProcess = PyLong_AsVoidPtr(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 /* Possible truncation here in 16-bit environments, but
* real exit codes are just the lower byte in any event. * real exit codes are just the lower byte in any event.
*/ */
result = exit_code; result = exit_code;
if (result == STILL_ACTIVE)
result = 0; /* Minimize confusion */
} else { } else {
/* No good way to bubble up an error, so instead we just /* Indicate failure - this will cause the file object
* return the Windows last error shifted above standard * to raise an I/O error and translate the last Win32
* exit codes. This will truncate in 16-bits but should * error code from errno. We do have a problem with
* be fine in 32 and at least distinguishes the problem. * 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 */ /* Free up the native handle at this point */
@ -2635,7 +2647,6 @@ static int _PyPclose(FILE *file)
} /* if fileObj */ } /* if fileObj */
} /* if _PyPopenProcs */ } /* if _PyPopenProcs */
fclose(file);
return result; return result;
} }
#else #else