summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFredrik Lundh <fredrik@pythonware.com>2000-07-26 17:29:12 (GMT)
committerFredrik Lundh <fredrik@pythonware.com>2000-07-26 17:29:12 (GMT)
commit2031893842fe8dfb4f166d7221006c70c62448b7 (patch)
treef6b26bdf8185f09de3bf15fda49008ec60c233f1
parent0765fe3a053a67f52fedbe8e9adb8410cb931957 (diff)
downloadcpython-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.c31
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