Index: Misc/NEWS =================================================================== --- Misc/NEWS (revision 87602) +++ Misc/NEWS (working copy) @@ -20,6 +20,9 @@ Library ------- +- Issue 9905: In subprocess, don't close standard file descriptors. Patch + by Ross Lagerwall. + - Issue 6285: IDLE no longer crashes on missing help file; patch by Scott David Daniels. Index: Lib/test/test_subprocess.py =================================================================== --- Lib/test/test_subprocess.py (revision 87602) +++ Lib/test/test_subprocess.py (working copy) @@ -897,6 +897,27 @@ self.assertStderrEqual(stderr, b'') self.assertEqual(p.wait(), -signal.SIGKILL) + def test_issue9905(self): + o0 = os.dup(0) + o2 = os.dup(2) + try: + os.close(0) + os.close(2) + res = subprocess.Popen([sys.executable, "-c", + 'import sys;' + 'sys.stdout.write("apple");' + 'sys.stdout.flush();' + 'sys.stderr.write("orange")'], + stdin=o0, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE).communicate() + self.assertEqual(res, (b'apple', b'orange')) + finally: + os.dup2(o0, 0) + os.dup2(o2, 2) + os.close(o0) + os.close(o2) + def test_terminate(self): p = self._kill_process('terminate') _, stderr = p.communicate() Index: Lib/subprocess.py =================================================================== --- Lib/subprocess.py (revision 87602) +++ Lib/subprocess.py (working copy) @@ -1203,13 +1203,13 @@ # Close pipe fds. Make sure we don't close the # same fd more than once, or standard fds. - if p2cread != -1 and p2cread not in (0,): + if p2cread != -1 and p2cread not in (0, 1, 2): os.close(p2cread) if (c2pwrite != -1 and - c2pwrite not in (p2cread, 1)): + c2pwrite not in (p2cread, 0, 1, 2)): os.close(c2pwrite) if (errwrite != -1 and - errwrite not in (p2cread, c2pwrite, 2)): + errwrite not in (p2cread, c2pwrite, 0, 1, 2)): os.close(errwrite) # Close all other fds, if asked for Index: Modules/_posixsubprocess.c =================================================================== --- Modules/_posixsubprocess.c (revision 87602) +++ Modules/_posixsubprocess.c (working copy) @@ -82,14 +82,16 @@ /* Close pipe fds. Make sure we don't close the same fd more than */ /* once, or standard fds. */ - if (p2cread != -1 && p2cread != 0) { + if (p2cread != -1 && p2cread != 0 && p2cread != 1 && p2cread != 2) { POSIX_CALL(close(p2cread)); } - if (c2pwrite != -1 && c2pwrite != p2cread && c2pwrite != 1) { + if (c2pwrite != -1 && c2pwrite != p2cread && c2pwrite != 0 && + c2pwrite != 1 && c2pwrite != 2) { POSIX_CALL(close(c2pwrite)); } if (errwrite != -1 && errwrite != p2cread && - errwrite != c2pwrite && errwrite != 2) { + errwrite != c2pwrite && errwrite != 0 && + errwrite != 1 &&errwrite != 2) { POSIX_CALL(close(errwrite)); }