The apr_file_dup2() function in apr/file_io/win32/filedup.c calls
_commit() for standard file handles 0, 1 and 2.
The _commit() function will assert with the message "Invalid file
descriptor. File possibly closed by a different thread" or return a
value of -1 if the file handle refers to a device.
The assert will appear if APR is compiled in debug mode.
This can be seen by running "testall.exe testdup".
But if file redirection is used (such as "testall.exe testdup > outfile
2>&1"), then the test completes successfully.
I have attached a patch that corrects this problem by checking _isatty().
Credit goes to Jeff Trawick for catching this problem in the first place.
Thanks,
Mike Rumph
Index: file_io/win32/filedup.c
===================================================================
--- file_io/win32/filedup.c (revision 1539426)
+++ file_io/win32/filedup.c (working copy)
@@ -88,7 +88,9 @@
*/
fflush(stderr);
setvbuf(stderr, NULL, _IONBF, 0);
- _commit(2 /* stderr */);
+ if (!_isatty(2)) {
+ _commit(2 /* stderr */);
+ }
/* Clone a handle can _close() without harming the source handle,
* open an MSVCRT-based pseudo-fd for the file handle, then dup2
@@ -118,7 +120,9 @@
/* For the process flow see the stderr case above */
fflush(stdout);
setvbuf(stdout, NULL, _IONBF, 0);
- _commit(1 /* stdout */);
+ if (!_isatty(1)) {
+ _commit(1 /* stdout */);
+ }
if (!DuplicateHandle(hproc, old_file->filehand, hproc, &newhand,
0, FALSE, DUPLICATE_SAME_ACCESS)) {
@@ -134,7 +138,9 @@
/* For the process flow see the stderr case above */
fflush(stdin);
setvbuf(stdin, NULL, _IONBF, 0);
- _commit(0 /* stdin */);
+ if (!_isatty(0)) {
+ _commit(0 /* stdin */);
+ }
if (!DuplicateHandle(hproc, old_file->filehand, hproc, &newhand,
0, FALSE, DUPLICATE_SAME_ACCESS)) {