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)) {

Reply via email to