Skip to content

Commit 95aaeee

Browse files
committed
Add a subprocess test of remapping standard file descriptors (issue #1187).
1 parent 4d41968 commit 95aaeee

1 file changed

Lines changed: 48 additions & 0 deletions

File tree

Lib/test/test_subprocess.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,54 @@ def test_close_fds_0_1_2(self):
955955
# all standard fds closed.
956956
self.check_close_std_fds([0, 1, 2])
957957

958+
def test_remapping_std_fds(self):
959+
# open up some temporary files
960+
temps = [mkstemp() for i in range(3)]
961+
try:
962+
temp_fds = [fd for fd, fname in temps]
963+
964+
# unlink the files -- we won't need to reopen them
965+
for fd, fname in temps:
966+
os.unlink(fname)
967+
968+
# write some data to what will become stdin, and rewind
969+
os.write(temp_fds[1], b"STDIN")
970+
os.lseek(temp_fds[1], 0, 0)
971+
972+
# move the standard file descriptors out of the way
973+
saved_fds = [os.dup(fd) for fd in range(3)]
974+
try:
975+
# duplicate the file objects over the standard fd's
976+
for fd, temp_fd in enumerate(temp_fds):
977+
os.dup2(temp_fd, fd)
978+
979+
# now use those files in the "wrong" order, so that subprocess
980+
# has to rearrange them in the child
981+
p = subprocess.Popen([sys.executable, "-c",
982+
'import sys; got = sys.stdin.read();'
983+
'sys.stdout.write("got %s"%got); sys.stderr.write("err")'],
984+
stdin=temp_fds[1],
985+
stdout=temp_fds[2],
986+
stderr=temp_fds[0])
987+
p.wait()
988+
finally:
989+
# restore the original fd's underneath sys.stdin, etc.
990+
for std, saved in enumerate(saved_fds):
991+
os.dup2(saved, std)
992+
os.close(saved)
993+
994+
for fd in temp_fds:
995+
os.lseek(fd, 0, 0)
996+
997+
out = os.read(temp_fds[2], 1024)
998+
err = support.strip_python_stderr(os.read(temp_fds[0], 1024))
999+
self.assertEqual(out, b"got STDIN")
1000+
self.assertEqual(err, b"err")
1001+
1002+
finally:
1003+
for fd in temp_fds:
1004+
os.close(fd)
1005+
9581006
def test_surrogates_error_message(self):
9591007
def prepare():
9601008
raise ValueError("surrogate:\uDCff")

0 commit comments

Comments
 (0)