blob: 77633376eb56718f8928b8c3ade4c6d002310a41 [file] [log] [blame]
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001import unittest
2from test import test_support
3import subprocess
4import sys
Gregory P. Smithf0739cb2017-01-22 22:38:28 -08005import platform
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00006import signal
7import os
Gregory P. Smithcce211f2010-03-01 00:05:08 +00008import errno
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00009import tempfile
10import time
Tim Peters3761e8d2004-10-13 04:07:12 +000011import re
Ezio Melotti8f6a2872010-02-10 21:40:33 +000012import sysconfig
Victor Stinner2097b9e2017-06-27 00:00:51 +020013import textwrap
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000014
Benjamin Peterson8b59c232011-12-10 12:31:42 -050015try:
Gregory P. Smithf0739cb2017-01-22 22:38:28 -080016 import ctypes
17except ImportError:
18 ctypes = None
Victor Stinner2097b9e2017-06-27 00:00:51 +020019else:
20 import ctypes.util
Gregory P. Smithf0739cb2017-01-22 22:38:28 -080021
22try:
Benjamin Peterson8b59c232011-12-10 12:31:42 -050023 import resource
24except ImportError:
25 resource = None
Antoine Pitrou33fc7442013-08-30 23:38:13 +020026try:
27 import threading
28except ImportError:
29 threading = None
Benjamin Peterson8b59c232011-12-10 12:31:42 -050030
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000031mswindows = (sys.platform == "win32")
32
33#
34# Depends on the following external programs: Python
35#
36
37if mswindows:
Tim Peters3b01a702004-10-12 22:19:32 +000038 SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
39 'os.O_BINARY);')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000040else:
41 SETBINARY = ''
42
Florent Xicluna98e3fc32010-02-27 19:20:50 +000043
Florent Xiclunafc4d6d72010-03-23 14:36:45 +000044class BaseTestCase(unittest.TestCase):
Neal Norwitzb15ac312006-06-29 04:10:08 +000045 def setUp(self):
Tim Peters38ff36c2006-06-30 06:18:39 +000046 # Try to minimize the number of children we have so this test
47 # doesn't crash on some buildbots (Alphas in particular).
Florent Xicluna98e3fc32010-02-27 19:20:50 +000048 test_support.reap_children()
Neal Norwitzb15ac312006-06-29 04:10:08 +000049
Florent Xiclunaab5e17f2010-03-04 21:31:58 +000050 def tearDown(self):
51 for inst in subprocess._active:
52 inst.wait()
53 subprocess._cleanup()
54 self.assertFalse(subprocess._active, "subprocess._active not empty")
55
Florent Xicluna98e3fc32010-02-27 19:20:50 +000056 def assertStderrEqual(self, stderr, expected, msg=None):
57 # In a debug build, stuff like "[6580 refs]" is printed to stderr at
58 # shutdown time. That frustrates tests trying to check stderr produced
59 # from a spawned Python process.
60 actual = re.sub(r"\[\d+ refs\]\r?\n?$", "", stderr)
61 self.assertEqual(actual, expected, msg)
Neal Norwitzb15ac312006-06-29 04:10:08 +000062
Florent Xiclunafc4d6d72010-03-23 14:36:45 +000063
Gregory P. Smith9d3b6e92012-11-10 22:49:03 -080064class PopenTestException(Exception):
65 pass
66
67
68class PopenExecuteChildRaises(subprocess.Popen):
69 """Popen subclass for testing cleanup of subprocess.PIPE filehandles when
70 _execute_child fails.
71 """
72 def _execute_child(self, *args, **kwargs):
73 raise PopenTestException("Forced Exception for Test")
74
75
Florent Xiclunafc4d6d72010-03-23 14:36:45 +000076class ProcessTestCase(BaseTestCase):
77
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000078 def test_call_seq(self):
Tim Peters7b759da2004-10-12 22:29:54 +000079 # call() function with sequence argument
Tim Peters3b01a702004-10-12 22:19:32 +000080 rc = subprocess.call([sys.executable, "-c",
81 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000082 self.assertEqual(rc, 47)
83
Peter Astrand454f7672005-01-01 09:36:35 +000084 def test_check_call_zero(self):
85 # check_call() function with zero return code
86 rc = subprocess.check_call([sys.executable, "-c",
87 "import sys; sys.exit(0)"])
88 self.assertEqual(rc, 0)
89
90 def test_check_call_nonzero(self):
91 # check_call() function with non-zero return code
Florent Xicluna98e3fc32010-02-27 19:20:50 +000092 with self.assertRaises(subprocess.CalledProcessError) as c:
Peter Astrand454f7672005-01-01 09:36:35 +000093 subprocess.check_call([sys.executable, "-c",
94 "import sys; sys.exit(47)"])
Florent Xicluna98e3fc32010-02-27 19:20:50 +000095 self.assertEqual(c.exception.returncode, 47)
Peter Astrand454f7672005-01-01 09:36:35 +000096
Gregory P. Smith26576802008-12-05 02:27:01 +000097 def test_check_output(self):
98 # check_output() function with zero return code
99 output = subprocess.check_output(
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000100 [sys.executable, "-c", "print 'BDFL'"])
Ezio Melottiaa980582010-01-23 23:04:36 +0000101 self.assertIn('BDFL', output)
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000102
Gregory P. Smith26576802008-12-05 02:27:01 +0000103 def test_check_output_nonzero(self):
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000104 # check_call() function with non-zero return code
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000105 with self.assertRaises(subprocess.CalledProcessError) as c:
Gregory P. Smith26576802008-12-05 02:27:01 +0000106 subprocess.check_output(
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000107 [sys.executable, "-c", "import sys; sys.exit(5)"])
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000108 self.assertEqual(c.exception.returncode, 5)
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000109
Gregory P. Smith26576802008-12-05 02:27:01 +0000110 def test_check_output_stderr(self):
111 # check_output() function stderr redirected to stdout
112 output = subprocess.check_output(
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000113 [sys.executable, "-c", "import sys; sys.stderr.write('BDFL')"],
114 stderr=subprocess.STDOUT)
Ezio Melottiaa980582010-01-23 23:04:36 +0000115 self.assertIn('BDFL', output)
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000116
Gregory P. Smith26576802008-12-05 02:27:01 +0000117 def test_check_output_stdout_arg(self):
118 # check_output() function stderr redirected to stdout
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000119 with self.assertRaises(ValueError) as c:
Gregory P. Smith26576802008-12-05 02:27:01 +0000120 output = subprocess.check_output(
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000121 [sys.executable, "-c", "print 'will not be run'"],
122 stdout=sys.stdout)
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000123 self.fail("Expected ValueError when stdout arg supplied.")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000124 self.assertIn('stdout', c.exception.args[0])
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000125
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000126 def test_call_kwargs(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000127 # call() function with keyword args
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000128 newenv = os.environ.copy()
129 newenv["FRUIT"] = "banana"
130 rc = subprocess.call([sys.executable, "-c",
Florent Xiclunabab22a72010-03-04 19:40:48 +0000131 'import sys, os;'
132 'sys.exit(os.getenv("FRUIT")=="banana")'],
133 env=newenv)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000134 self.assertEqual(rc, 1)
135
Victor Stinner776e69b2011-06-01 01:03:00 +0200136 def test_invalid_args(self):
137 # Popen() called with invalid arguments should raise TypeError
138 # but Popen.__del__ should not complain (issue #12085)
Victor Stinnere9b185f2011-06-01 01:57:48 +0200139 with test_support.captured_stderr() as s:
Victor Stinner776e69b2011-06-01 01:03:00 +0200140 self.assertRaises(TypeError, subprocess.Popen, invalid_arg_name=1)
141 argcount = subprocess.Popen.__init__.__code__.co_argcount
142 too_many_args = [0] * (argcount + 1)
143 self.assertRaises(TypeError, subprocess.Popen, *too_many_args)
144 self.assertEqual(s.getvalue(), '')
145
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000146 def test_stdin_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000147 # .stdin is None when not redirected
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000148 p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
149 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brian Curtind117b562010-11-05 04:09:09 +0000150 self.addCleanup(p.stdout.close)
151 self.addCleanup(p.stderr.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000152 p.wait()
153 self.assertEqual(p.stdin, None)
154
155 def test_stdout_none(self):
Ezio Melottiefaad092013-03-11 00:34:33 +0200156 # .stdout is None when not redirected, and the child's stdout will
157 # be inherited from the parent. In order to test this we run a
158 # subprocess in a subprocess:
159 # this_test
160 # \-- subprocess created by this test (parent)
161 # \-- subprocess created by the parent subprocess (child)
162 # The parent doesn't specify stdout, so the child will use the
163 # parent's stdout. This test checks that the message printed by the
164 # child goes to the parent stdout. The parent also checks that the
165 # child's stdout is None. See #11963.
166 code = ('import sys; from subprocess import Popen, PIPE;'
167 'p = Popen([sys.executable, "-c", "print \'test_stdout_none\'"],'
168 ' stdin=PIPE, stderr=PIPE);'
169 'p.wait(); assert p.stdout is None;')
170 p = subprocess.Popen([sys.executable, "-c", code],
171 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
172 self.addCleanup(p.stdout.close)
Brian Curtind117b562010-11-05 04:09:09 +0000173 self.addCleanup(p.stderr.close)
Ezio Melottiefaad092013-03-11 00:34:33 +0200174 out, err = p.communicate()
175 self.assertEqual(p.returncode, 0, err)
176 self.assertEqual(out.rstrip(), 'test_stdout_none')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000177
178 def test_stderr_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000179 # .stderr is None when not redirected
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000180 p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
181 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
Brian Curtind117b562010-11-05 04:09:09 +0000182 self.addCleanup(p.stdout.close)
183 self.addCleanup(p.stdin.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000184 p.wait()
185 self.assertEqual(p.stderr, None)
186
Ezio Melotti8f6a2872010-02-10 21:40:33 +0000187 def test_executable_with_cwd(self):
Florent Xicluna63763702010-03-11 01:50:48 +0000188 python_dir = os.path.dirname(os.path.realpath(sys.executable))
Ezio Melotti8f6a2872010-02-10 21:40:33 +0000189 p = subprocess.Popen(["somethingyoudonthave", "-c",
190 "import sys; sys.exit(47)"],
191 executable=sys.executable, cwd=python_dir)
192 p.wait()
193 self.assertEqual(p.returncode, 47)
194
195 @unittest.skipIf(sysconfig.is_python_build(),
196 "need an installed Python. See #7774")
197 def test_executable_without_cwd(self):
198 # For a normal installation, it should work without 'cwd'
199 # argument. For test runs in the build directory, see #7774.
200 p = subprocess.Popen(["somethingyoudonthave", "-c",
201 "import sys; sys.exit(47)"],
Tim Peters3b01a702004-10-12 22:19:32 +0000202 executable=sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000203 p.wait()
204 self.assertEqual(p.returncode, 47)
205
206 def test_stdin_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000207 # stdin redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000208 p = subprocess.Popen([sys.executable, "-c",
209 'import sys; sys.exit(sys.stdin.read() == "pear")'],
210 stdin=subprocess.PIPE)
211 p.stdin.write("pear")
212 p.stdin.close()
213 p.wait()
214 self.assertEqual(p.returncode, 1)
215
216 def test_stdin_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000217 # stdin is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000218 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000219 d = tf.fileno()
220 os.write(d, "pear")
221 os.lseek(d, 0, 0)
222 p = subprocess.Popen([sys.executable, "-c",
223 'import sys; sys.exit(sys.stdin.read() == "pear")'],
224 stdin=d)
225 p.wait()
226 self.assertEqual(p.returncode, 1)
227
228 def test_stdin_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000229 # stdin is set to open file object
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000230 tf = tempfile.TemporaryFile()
231 tf.write("pear")
232 tf.seek(0)
233 p = subprocess.Popen([sys.executable, "-c",
234 'import sys; sys.exit(sys.stdin.read() == "pear")'],
235 stdin=tf)
236 p.wait()
237 self.assertEqual(p.returncode, 1)
238
239 def test_stdout_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000240 # stdout redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000241 p = subprocess.Popen([sys.executable, "-c",
242 'import sys; sys.stdout.write("orange")'],
243 stdout=subprocess.PIPE)
Brian Curtind117b562010-11-05 04:09:09 +0000244 self.addCleanup(p.stdout.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000245 self.assertEqual(p.stdout.read(), "orange")
246
247 def test_stdout_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000248 # stdout is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000249 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000250 d = tf.fileno()
251 p = subprocess.Popen([sys.executable, "-c",
252 'import sys; sys.stdout.write("orange")'],
253 stdout=d)
254 p.wait()
255 os.lseek(d, 0, 0)
256 self.assertEqual(os.read(d, 1024), "orange")
257
258 def test_stdout_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000259 # stdout is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000260 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000261 p = subprocess.Popen([sys.executable, "-c",
262 'import sys; sys.stdout.write("orange")'],
263 stdout=tf)
264 p.wait()
265 tf.seek(0)
266 self.assertEqual(tf.read(), "orange")
267
268 def test_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000269 # stderr redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000270 p = subprocess.Popen([sys.executable, "-c",
271 'import sys; sys.stderr.write("strawberry")'],
272 stderr=subprocess.PIPE)
Brian Curtind117b562010-11-05 04:09:09 +0000273 self.addCleanup(p.stderr.close)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000274 self.assertStderrEqual(p.stderr.read(), "strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000275
276 def test_stderr_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000277 # stderr is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000278 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000279 d = tf.fileno()
280 p = subprocess.Popen([sys.executable, "-c",
281 'import sys; sys.stderr.write("strawberry")'],
282 stderr=d)
283 p.wait()
284 os.lseek(d, 0, 0)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000285 self.assertStderrEqual(os.read(d, 1024), "strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000286
287 def test_stderr_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000288 # stderr is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000289 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000290 p = subprocess.Popen([sys.executable, "-c",
291 'import sys; sys.stderr.write("strawberry")'],
292 stderr=tf)
293 p.wait()
294 tf.seek(0)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000295 self.assertStderrEqual(tf.read(), "strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000296
Martin Panter1edccfa2016-05-13 01:54:44 +0000297 def test_stderr_redirect_with_no_stdout_redirect(self):
298 # test stderr=STDOUT while stdout=None (not set)
299
300 # - grandchild prints to stderr
301 # - child redirects grandchild's stderr to its stdout
302 # - the parent should get grandchild's stderr in child's stdout
303 p = subprocess.Popen([sys.executable, "-c",
304 'import sys, subprocess;'
305 'rc = subprocess.call([sys.executable, "-c",'
306 ' "import sys;"'
307 ' "sys.stderr.write(\'42\')"],'
308 ' stderr=subprocess.STDOUT);'
309 'sys.exit(rc)'],
310 stdout=subprocess.PIPE,
311 stderr=subprocess.PIPE)
312 stdout, stderr = p.communicate()
313 #NOTE: stdout should get stderr from grandchild
314 self.assertStderrEqual(stdout, b'42')
315 self.assertStderrEqual(stderr, b'') # should be empty
316 self.assertEqual(p.returncode, 0)
317
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000318 def test_stdout_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000319 # capture stdout and stderr to the same pipe
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000320 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000321 'import sys;'
322 'sys.stdout.write("apple");'
323 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000324 'sys.stderr.write("orange")'],
325 stdout=subprocess.PIPE,
326 stderr=subprocess.STDOUT)
Brian Curtind117b562010-11-05 04:09:09 +0000327 self.addCleanup(p.stdout.close)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000328 self.assertStderrEqual(p.stdout.read(), "appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000329
330 def test_stdout_stderr_file(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000331 # capture stdout and stderr to the same open file
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000332 tf = tempfile.TemporaryFile()
333 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000334 'import sys;'
335 'sys.stdout.write("apple");'
336 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000337 'sys.stderr.write("orange")'],
338 stdout=tf,
339 stderr=tf)
340 p.wait()
341 tf.seek(0)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000342 self.assertStderrEqual(tf.read(), "appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000343
Gustavo Niemeyerc36bede2006-09-07 00:48:33 +0000344 def test_stdout_filedes_of_stdout(self):
345 # stdout is set to 1 (#1531862).
Ezio Melotti9b9cd4c2013-03-11 03:21:08 +0200346 # To avoid printing the text on stdout, we do something similar to
Ezio Melottiefaad092013-03-11 00:34:33 +0200347 # test_stdout_none (see above). The parent subprocess calls the child
348 # subprocess passing stdout=1, and this test uses stdout=PIPE in
349 # order to capture and check the output of the parent. See #11963.
350 code = ('import sys, subprocess; '
351 'rc = subprocess.call([sys.executable, "-c", '
352 ' "import os, sys; sys.exit(os.write(sys.stdout.fileno(), '
Ezio Melotti9b9cd4c2013-03-11 03:21:08 +0200353 '\'test with stdout=1\'))"], stdout=1); '
354 'assert rc == 18')
Ezio Melottiefaad092013-03-11 00:34:33 +0200355 p = subprocess.Popen([sys.executable, "-c", code],
356 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
357 self.addCleanup(p.stdout.close)
358 self.addCleanup(p.stderr.close)
359 out, err = p.communicate()
360 self.assertEqual(p.returncode, 0, err)
Ezio Melotti9b9cd4c2013-03-11 03:21:08 +0200361 self.assertEqual(out.rstrip(), 'test with stdout=1')
Gustavo Niemeyerc36bede2006-09-07 00:48:33 +0000362
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000363 def test_cwd(self):
Guido van Rossume9a0e882007-12-20 17:28:10 +0000364 tmpdir = tempfile.gettempdir()
Peter Astrand195404f2004-11-12 15:51:48 +0000365 # We cannot use os.path.realpath to canonicalize the path,
366 # since it doesn't expand Tru64 {memb} strings. See bug 1063571.
367 cwd = os.getcwd()
368 os.chdir(tmpdir)
369 tmpdir = os.getcwd()
370 os.chdir(cwd)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000371 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000372 'import sys,os;'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000373 'sys.stdout.write(os.getcwd())'],
374 stdout=subprocess.PIPE,
375 cwd=tmpdir)
Brian Curtind117b562010-11-05 04:09:09 +0000376 self.addCleanup(p.stdout.close)
Fredrik Lundh59c05592004-10-13 06:55:40 +0000377 normcase = os.path.normcase
378 self.assertEqual(normcase(p.stdout.read()), normcase(tmpdir))
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000379
380 def test_env(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000381 newenv = os.environ.copy()
382 newenv["FRUIT"] = "orange"
383 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000384 'import sys,os;'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000385 'sys.stdout.write(os.getenv("FRUIT"))'],
386 stdout=subprocess.PIPE,
387 env=newenv)
Brian Curtind117b562010-11-05 04:09:09 +0000388 self.addCleanup(p.stdout.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000389 self.assertEqual(p.stdout.read(), "orange")
390
Serhiy Storchaka9dda2ca2017-06-24 11:49:00 +0300391 def test_invalid_cmd(self):
392 # null character in the command name
393 cmd = sys.executable + '\0'
394 with self.assertRaises(TypeError):
395 subprocess.Popen([cmd, "-c", "pass"])
396
397 # null character in the command argument
398 with self.assertRaises(TypeError):
399 subprocess.Popen([sys.executable, "-c", "pass#\0"])
400
401 def test_invalid_env(self):
402 # null character in the enviroment variable name
403 newenv = os.environ.copy()
404 newenv["FRUIT\0VEGETABLE"] = "cabbage"
405 with self.assertRaises(TypeError):
406 subprocess.Popen([sys.executable, "-c", "pass"], env=newenv)
407
408 # null character in the enviroment variable value
409 newenv = os.environ.copy()
410 newenv["FRUIT"] = "orange\0VEGETABLE=cabbage"
411 with self.assertRaises(TypeError):
412 subprocess.Popen([sys.executable, "-c", "pass"], env=newenv)
413
414 # equal character in the enviroment variable name
415 newenv = os.environ.copy()
416 newenv["FRUIT=ORANGE"] = "lemon"
417 with self.assertRaises(ValueError):
418 subprocess.Popen([sys.executable, "-c", "pass"], env=newenv)
419
420 # equal character in the enviroment variable value
421 newenv = os.environ.copy()
422 newenv["FRUIT"] = "orange=lemon"
423 p = subprocess.Popen([sys.executable, "-c",
424 'import sys, os;'
425 'sys.stdout.write(os.getenv("FRUIT"))'],
426 stdout=subprocess.PIPE,
427 env=newenv)
428 stdout, stderr = p.communicate()
429 self.assertEqual(stdout, "orange=lemon")
430
Peter Astrandcbac93c2005-03-03 20:24:28 +0000431 def test_communicate_stdin(self):
432 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000433 'import sys;'
434 'sys.exit(sys.stdin.read() == "pear")'],
Peter Astrandcbac93c2005-03-03 20:24:28 +0000435 stdin=subprocess.PIPE)
436 p.communicate("pear")
437 self.assertEqual(p.returncode, 1)
438
439 def test_communicate_stdout(self):
440 p = subprocess.Popen([sys.executable, "-c",
441 'import sys; sys.stdout.write("pineapple")'],
442 stdout=subprocess.PIPE)
443 (stdout, stderr) = p.communicate()
444 self.assertEqual(stdout, "pineapple")
445 self.assertEqual(stderr, None)
446
447 def test_communicate_stderr(self):
448 p = subprocess.Popen([sys.executable, "-c",
449 'import sys; sys.stderr.write("pineapple")'],
450 stderr=subprocess.PIPE)
451 (stdout, stderr) = p.communicate()
452 self.assertEqual(stdout, None)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000453 self.assertStderrEqual(stderr, "pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000454
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000455 def test_communicate(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000456 p = subprocess.Popen([sys.executable, "-c",
Gregory P. Smith4036fd42008-05-26 20:22:14 +0000457 'import sys,os;'
458 'sys.stderr.write("pineapple");'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000459 'sys.stdout.write(sys.stdin.read())'],
Tim Peters3b01a702004-10-12 22:19:32 +0000460 stdin=subprocess.PIPE,
461 stdout=subprocess.PIPE,
462 stderr=subprocess.PIPE)
Brian Curtin7fe045e2010-11-05 17:19:38 +0000463 self.addCleanup(p.stdout.close)
464 self.addCleanup(p.stderr.close)
465 self.addCleanup(p.stdin.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000466 (stdout, stderr) = p.communicate("banana")
467 self.assertEqual(stdout, "banana")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000468 self.assertStderrEqual(stderr, "pineapple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000469
Gregory P. Smith4036fd42008-05-26 20:22:14 +0000470 # This test is Linux specific for simplicity to at least have
471 # some coverage. It is not a platform specific bug.
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000472 @unittest.skipUnless(os.path.isdir('/proc/%d/fd' % os.getpid()),
473 "Linux specific")
474 # Test for the fd leak reported in http://bugs.python.org/issue2791.
475 def test_communicate_pipe_fd_leak(self):
476 fd_directory = '/proc/%d/fd' % os.getpid()
477 num_fds_before_popen = len(os.listdir(fd_directory))
Martin Panterad6a99c2016-09-10 10:38:22 +0000478 p = subprocess.Popen([sys.executable, "-c", "print('')"],
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000479 stdout=subprocess.PIPE)
480 p.communicate()
481 num_fds_after_communicate = len(os.listdir(fd_directory))
482 del p
483 num_fds_after_destruction = len(os.listdir(fd_directory))
484 self.assertEqual(num_fds_before_popen, num_fds_after_destruction)
485 self.assertEqual(num_fds_before_popen, num_fds_after_communicate)
Gregory P. Smith4036fd42008-05-26 20:22:14 +0000486
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000487 def test_communicate_returns(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000488 # communicate() should return None if no redirection is active
Tim Peters3b01a702004-10-12 22:19:32 +0000489 p = subprocess.Popen([sys.executable, "-c",
490 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000491 (stdout, stderr) = p.communicate()
492 self.assertEqual(stdout, None)
493 self.assertEqual(stderr, None)
494
495 def test_communicate_pipe_buf(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000496 # communicate() with writes larger than pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000497 # This test will probably deadlock rather than fail, if
Tim Peterse718f612004-10-12 21:51:32 +0000498 # communicate() does not work properly.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000499 x, y = os.pipe()
500 if mswindows:
501 pipe_buf = 512
502 else:
503 pipe_buf = os.fpathconf(x, "PC_PIPE_BUF")
504 os.close(x)
505 os.close(y)
506 p = subprocess.Popen([sys.executable, "-c",
Tim Peterse718f612004-10-12 21:51:32 +0000507 'import sys,os;'
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000508 'sys.stdout.write(sys.stdin.read(47));'
509 'sys.stderr.write("xyz"*%d);'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000510 'sys.stdout.write(sys.stdin.read())' % pipe_buf],
Tim Peters3b01a702004-10-12 22:19:32 +0000511 stdin=subprocess.PIPE,
512 stdout=subprocess.PIPE,
513 stderr=subprocess.PIPE)
Brian Curtin7fe045e2010-11-05 17:19:38 +0000514 self.addCleanup(p.stdout.close)
515 self.addCleanup(p.stderr.close)
516 self.addCleanup(p.stdin.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000517 string_to_write = "abc"*pipe_buf
518 (stdout, stderr) = p.communicate(string_to_write)
519 self.assertEqual(stdout, string_to_write)
520
521 def test_writes_before_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000522 # stdin.write before communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000523 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000524 'import sys,os;'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000525 'sys.stdout.write(sys.stdin.read())'],
Tim Peters3b01a702004-10-12 22:19:32 +0000526 stdin=subprocess.PIPE,
527 stdout=subprocess.PIPE,
528 stderr=subprocess.PIPE)
Brian Curtin7fe045e2010-11-05 17:19:38 +0000529 self.addCleanup(p.stdout.close)
530 self.addCleanup(p.stderr.close)
531 self.addCleanup(p.stdin.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000532 p.stdin.write("banana")
533 (stdout, stderr) = p.communicate("split")
534 self.assertEqual(stdout, "bananasplit")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000535 self.assertStderrEqual(stderr, "")
Tim Peterse718f612004-10-12 21:51:32 +0000536
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000537 def test_universal_newlines(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000538 p = subprocess.Popen([sys.executable, "-c",
Tim Peters3b01a702004-10-12 22:19:32 +0000539 'import sys,os;' + SETBINARY +
540 'sys.stdout.write("line1\\n");'
541 'sys.stdout.flush();'
542 'sys.stdout.write("line2\\r");'
543 'sys.stdout.flush();'
544 'sys.stdout.write("line3\\r\\n");'
545 'sys.stdout.flush();'
546 'sys.stdout.write("line4\\r");'
547 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000548 'sys.stdout.write("\\nline5");'
Tim Peters3b01a702004-10-12 22:19:32 +0000549 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000550 'sys.stdout.write("\\nline6");'],
551 stdout=subprocess.PIPE,
552 universal_newlines=1)
Brian Curtind117b562010-11-05 04:09:09 +0000553 self.addCleanup(p.stdout.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000554 stdout = p.stdout.read()
Neal Norwitza6d01ce2006-05-02 06:23:22 +0000555 if hasattr(file, 'newlines'):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000556 # Interpreter with universal newline support
Tim Peters3b01a702004-10-12 22:19:32 +0000557 self.assertEqual(stdout,
558 "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000559 else:
560 # Interpreter without universal newline support
Tim Peters3b01a702004-10-12 22:19:32 +0000561 self.assertEqual(stdout,
562 "line1\nline2\rline3\r\nline4\r\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000563
564 def test_universal_newlines_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000565 # universal newlines through communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000566 p = subprocess.Popen([sys.executable, "-c",
Tim Peters3b01a702004-10-12 22:19:32 +0000567 'import sys,os;' + SETBINARY +
568 'sys.stdout.write("line1\\n");'
569 'sys.stdout.flush();'
570 'sys.stdout.write("line2\\r");'
571 'sys.stdout.flush();'
572 'sys.stdout.write("line3\\r\\n");'
573 'sys.stdout.flush();'
574 'sys.stdout.write("line4\\r");'
575 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000576 'sys.stdout.write("\\nline5");'
Tim Peters3b01a702004-10-12 22:19:32 +0000577 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000578 'sys.stdout.write("\\nline6");'],
579 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
580 universal_newlines=1)
Brian Curtin7fe045e2010-11-05 17:19:38 +0000581 self.addCleanup(p.stdout.close)
582 self.addCleanup(p.stderr.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000583 (stdout, stderr) = p.communicate()
Neal Norwitza6d01ce2006-05-02 06:23:22 +0000584 if hasattr(file, 'newlines'):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000585 # Interpreter with universal newline support
Tim Peters3b01a702004-10-12 22:19:32 +0000586 self.assertEqual(stdout,
587 "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000588 else:
589 # Interpreter without universal newline support
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000590 self.assertEqual(stdout,
591 "line1\nline2\rline3\r\nline4\r\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000592
593 def test_no_leaking(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000594 # Make sure we leak no resources
Antoine Pitroub0b3bff2010-09-18 22:42:30 +0000595 if not mswindows:
Peter Astrandf7f1bb72005-03-03 20:47:37 +0000596 max_handles = 1026 # too much for most UNIX systems
597 else:
Antoine Pitroub0b3bff2010-09-18 22:42:30 +0000598 max_handles = 2050 # too much for (at least some) Windows setups
599 handles = []
600 try:
601 for i in range(max_handles):
602 try:
603 handles.append(os.open(test_support.TESTFN,
604 os.O_WRONLY | os.O_CREAT))
605 except OSError as e:
606 if e.errno != errno.EMFILE:
607 raise
608 break
609 else:
610 self.skipTest("failed to reach the file descriptor limit "
611 "(tried %d)" % max_handles)
612 # Close a couple of them (should be enough for a subprocess)
613 for i in range(10):
614 os.close(handles.pop())
615 # Loop creating some subprocesses. If one of them leaks some fds,
616 # the next loop iteration will fail by reaching the max fd limit.
617 for i in range(15):
618 p = subprocess.Popen([sys.executable, "-c",
619 "import sys;"
620 "sys.stdout.write(sys.stdin.read())"],
621 stdin=subprocess.PIPE,
622 stdout=subprocess.PIPE,
623 stderr=subprocess.PIPE)
624 data = p.communicate(b"lime")[0]
625 self.assertEqual(data, b"lime")
626 finally:
627 for h in handles:
628 os.close(h)
Mark Dickinson313dc9b2012-10-07 15:41:38 +0100629 test_support.unlink(test_support.TESTFN)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000630
631 def test_list2cmdline(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000632 self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
633 '"a b c" d e')
634 self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
635 'ab\\"c \\ d')
Gregory P. Smithe047e6d2008-01-19 20:49:02 +0000636 self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']),
637 'ab\\"c " \\\\" d')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000638 self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
639 'a\\\\\\b "de fg" h')
640 self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
641 'a\\\\\\"b c d')
642 self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
643 '"a\\\\b c" d e')
644 self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
645 '"a\\\\b\\ c" d e')
Peter Astrand10514a72007-01-13 22:35:35 +0000646 self.assertEqual(subprocess.list2cmdline(['ab', '']),
647 'ab ""')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000648
649
650 def test_poll(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000651 p = subprocess.Popen([sys.executable,
Tim Peters29b6b4f2004-10-13 03:43:40 +0000652 "-c", "import time; time.sleep(1)"])
653 count = 0
654 while p.poll() is None:
655 time.sleep(0.1)
656 count += 1
657 # We expect that the poll loop probably went around about 10 times,
658 # but, based on system scheduling we can't control, it's possible
659 # poll() never returned None. It "should be" very rare that it
660 # didn't go around at least twice.
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000661 self.assertGreaterEqual(count, 2)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000662 # Subsequent invocations should just return the returncode
663 self.assertEqual(p.poll(), 0)
664
665
666 def test_wait(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000667 p = subprocess.Popen([sys.executable,
668 "-c", "import time; time.sleep(2)"])
669 self.assertEqual(p.wait(), 0)
670 # Subsequent invocations should just return the returncode
671 self.assertEqual(p.wait(), 0)
Tim Peterse718f612004-10-12 21:51:32 +0000672
Peter Astrand738131d2004-11-30 21:04:45 +0000673
674 def test_invalid_bufsize(self):
675 # an invalid type of the bufsize argument should raise
676 # TypeError.
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000677 with self.assertRaises(TypeError):
Peter Astrand738131d2004-11-30 21:04:45 +0000678 subprocess.Popen([sys.executable, "-c", "pass"], "orange")
Peter Astrand738131d2004-11-30 21:04:45 +0000679
Georg Brandlf3715d22009-02-14 17:01:36 +0000680 def test_leaking_fds_on_error(self):
681 # see bug #5179: Popen leaks file descriptors to PIPEs if
682 # the child fails to execute; this will eventually exhaust
683 # the maximum number of open fds. 1024 seems a very common
684 # value for that limit, but Windows has 2048, so we loop
685 # 1024 times (each call leaked two fds).
686 for i in range(1024):
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000687 # Windows raises IOError. Others raise OSError.
688 with self.assertRaises(EnvironmentError) as c:
Georg Brandlf3715d22009-02-14 17:01:36 +0000689 subprocess.Popen(['nonexisting_i_hope'],
690 stdout=subprocess.PIPE,
691 stderr=subprocess.PIPE)
R David Murraycdd5fc92011-03-13 22:37:18 -0400692 # ignore errors that indicate the command was not found
693 if c.exception.errno not in (errno.ENOENT, errno.EACCES):
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000694 raise c.exception
Georg Brandlf3715d22009-02-14 17:01:36 +0000695
Antoine Pitrou33fc7442013-08-30 23:38:13 +0200696 @unittest.skipIf(threading is None, "threading required")
697 def test_double_close_on_error(self):
698 # Issue #18851
699 fds = []
700 def open_fds():
701 for i in range(20):
702 fds.extend(os.pipe())
703 time.sleep(0.001)
704 t = threading.Thread(target=open_fds)
705 t.start()
706 try:
707 with self.assertRaises(EnvironmentError):
708 subprocess.Popen(['nonexisting_i_hope'],
709 stdin=subprocess.PIPE,
710 stdout=subprocess.PIPE,
711 stderr=subprocess.PIPE)
712 finally:
713 t.join()
714 exc = None
715 for fd in fds:
716 # If a double close occurred, some of those fds will
717 # already have been closed by mistake, and os.close()
718 # here will raise.
719 try:
720 os.close(fd)
721 except OSError as e:
722 exc = e
723 if exc is not None:
724 raise exc
725
Tim Golden90374f52010-08-06 13:14:33 +0000726 def test_handles_closed_on_exception(self):
727 # If CreateProcess exits with an error, ensure the
728 # duplicate output handles are released
Berker Peksagb7c35152015-09-28 15:37:57 +0300729 ifhandle, ifname = tempfile.mkstemp()
730 ofhandle, ofname = tempfile.mkstemp()
731 efhandle, efname = tempfile.mkstemp()
Tim Golden90374f52010-08-06 13:14:33 +0000732 try:
733 subprocess.Popen (["*"], stdin=ifhandle, stdout=ofhandle,
734 stderr=efhandle)
735 except OSError:
736 os.close(ifhandle)
737 os.remove(ifname)
738 os.close(ofhandle)
739 os.remove(ofname)
740 os.close(efhandle)
741 os.remove(efname)
742 self.assertFalse(os.path.exists(ifname))
743 self.assertFalse(os.path.exists(ofname))
744 self.assertFalse(os.path.exists(efname))
745
Ross Lagerwall104c3f12011-04-05 15:24:34 +0200746 def test_communicate_epipe(self):
747 # Issue 10963: communicate() should hide EPIPE
748 p = subprocess.Popen([sys.executable, "-c", 'pass'],
749 stdin=subprocess.PIPE,
750 stdout=subprocess.PIPE,
751 stderr=subprocess.PIPE)
752 self.addCleanup(p.stdout.close)
753 self.addCleanup(p.stderr.close)
754 self.addCleanup(p.stdin.close)
755 p.communicate("x" * 2**20)
756
757 def test_communicate_epipe_only_stdin(self):
758 # Issue 10963: communicate() should hide EPIPE
759 p = subprocess.Popen([sys.executable, "-c", 'pass'],
760 stdin=subprocess.PIPE)
761 self.addCleanup(p.stdin.close)
762 time.sleep(2)
763 p.communicate("x" * 2**20)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000764
Gregory P. Smith9d3b6e92012-11-10 22:49:03 -0800765 # This test is Linux-ish specific for simplicity to at least have
766 # some coverage. It is not a platform specific bug.
767 @unittest.skipUnless(os.path.isdir('/proc/%d/fd' % os.getpid()),
768 "Linux specific")
769 def test_failed_child_execute_fd_leak(self):
770 """Test for the fork() failure fd leak reported in issue16327."""
771 fd_directory = '/proc/%d/fd' % os.getpid()
772 fds_before_popen = os.listdir(fd_directory)
773 with self.assertRaises(PopenTestException):
774 PopenExecuteChildRaises(
775 [sys.executable, '-c', 'pass'], stdin=subprocess.PIPE,
776 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
777
778 # NOTE: This test doesn't verify that the real _execute_child
779 # does not close the file descriptors itself on the way out
780 # during an exception. Code inspection has confirmed that.
781
782 fds_after_exception = os.listdir(fd_directory)
783 self.assertEqual(fds_before_popen, fds_after_exception)
784
785
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000786# context manager
787class _SuppressCoreFiles(object):
788 """Try to prevent core files from being created."""
789 old_limit = None
790
791 def __enter__(self):
792 """Try to save previous ulimit, then set it to (0, 0)."""
Benjamin Peterson8b59c232011-12-10 12:31:42 -0500793 if resource is not None:
794 try:
795 self.old_limit = resource.getrlimit(resource.RLIMIT_CORE)
796 resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
797 except (ValueError, resource.error):
798 pass
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000799
Ronald Oussoren21b44e02010-07-23 12:26:30 +0000800 if sys.platform == 'darwin':
801 # Check if the 'Crash Reporter' on OSX was configured
802 # in 'Developer' mode and warn that it will get triggered
803 # when it is.
804 #
805 # This assumes that this context manager is used in tests
806 # that might trigger the next manager.
807 value = subprocess.Popen(['/usr/bin/defaults', 'read',
808 'com.apple.CrashReporter', 'DialogType'],
809 stdout=subprocess.PIPE).communicate()[0]
810 if value.strip() == b'developer':
811 print "this tests triggers the Crash Reporter, that is intentional"
812 sys.stdout.flush()
813
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000814 def __exit__(self, *args):
815 """Return core file behavior to default."""
816 if self.old_limit is None:
817 return
Benjamin Peterson8b59c232011-12-10 12:31:42 -0500818 if resource is not None:
819 try:
820 resource.setrlimit(resource.RLIMIT_CORE, self.old_limit)
821 except (ValueError, resource.error):
822 pass
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000823
Victor Stinnerb78fed92011-07-05 14:50:35 +0200824 @unittest.skipUnless(hasattr(signal, 'SIGALRM'),
825 "Requires signal.SIGALRM")
Victor Stinnere7901312011-07-05 14:08:01 +0200826 def test_communicate_eintr(self):
827 # Issue #12493: communicate() should handle EINTR
828 def handler(signum, frame):
829 pass
830 old_handler = signal.signal(signal.SIGALRM, handler)
831 self.addCleanup(signal.signal, signal.SIGALRM, old_handler)
832
833 # the process is running for 2 seconds
834 args = [sys.executable, "-c", 'import time; time.sleep(2)']
835 for stream in ('stdout', 'stderr'):
836 kw = {stream: subprocess.PIPE}
837 with subprocess.Popen(args, **kw) as process:
838 signal.alarm(1)
839 # communicate() will be interrupted by SIGALRM
840 process.communicate()
841
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000842
Florent Xiclunabab22a72010-03-04 19:40:48 +0000843@unittest.skipIf(mswindows, "POSIX specific tests")
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000844class POSIXProcessTestCase(BaseTestCase):
Florent Xiclunaab5e17f2010-03-04 21:31:58 +0000845
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000846 def test_exceptions(self):
847 # caught & re-raised exceptions
848 with self.assertRaises(OSError) as c:
849 p = subprocess.Popen([sys.executable, "-c", ""],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000850 cwd="/this/path/does/not/exist")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000851 # The attribute child_traceback should contain "os.chdir" somewhere.
852 self.assertIn("os.chdir", c.exception.child_traceback)
Tim Peterse718f612004-10-12 21:51:32 +0000853
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000854 def test_run_abort(self):
855 # returncode handles signal termination
856 with _SuppressCoreFiles():
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000857 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000858 "import os; os.abort()"])
859 p.wait()
860 self.assertEqual(-p.returncode, signal.SIGABRT)
861
862 def test_preexec(self):
863 # preexec function
864 p = subprocess.Popen([sys.executable, "-c",
865 "import sys, os;"
866 "sys.stdout.write(os.getenv('FRUIT'))"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000867 stdout=subprocess.PIPE,
868 preexec_fn=lambda: os.putenv("FRUIT", "apple"))
Brian Curtind117b562010-11-05 04:09:09 +0000869 self.addCleanup(p.stdout.close)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000870 self.assertEqual(p.stdout.read(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000871
Gregory P. Smithf047ba82012-11-11 09:49:02 -0800872 class _TestExecuteChildPopen(subprocess.Popen):
873 """Used to test behavior at the end of _execute_child."""
874 def __init__(self, testcase, *args, **kwargs):
Gregory P. Smithf047ba82012-11-11 09:49:02 -0800875 self._testcase = testcase
876 subprocess.Popen.__init__(self, *args, **kwargs)
Gregory P. Smith211248b2012-11-11 02:00:49 -0800877
Gregory P. Smithf047ba82012-11-11 09:49:02 -0800878 def _execute_child(
879 self, args, executable, preexec_fn, close_fds, cwd, env,
Antoine Pitrou33fc7442013-08-30 23:38:13 +0200880 universal_newlines, startupinfo, creationflags, shell, to_close,
Gregory P. Smith211248b2012-11-11 02:00:49 -0800881 p2cread, p2cwrite,
882 c2pread, c2pwrite,
883 errread, errwrite):
884 try:
885 subprocess.Popen._execute_child(
Gregory P. Smithf047ba82012-11-11 09:49:02 -0800886 self, args, executable, preexec_fn, close_fds,
Gregory P. Smith211248b2012-11-11 02:00:49 -0800887 cwd, env, universal_newlines,
Antoine Pitrou33fc7442013-08-30 23:38:13 +0200888 startupinfo, creationflags, shell, to_close,
Gregory P. Smith211248b2012-11-11 02:00:49 -0800889 p2cread, p2cwrite,
890 c2pread, c2pwrite,
891 errread, errwrite)
892 finally:
893 # Open a bunch of file descriptors and verify that
894 # none of them are the same as the ones the Popen
895 # instance is using for stdin/stdout/stderr.
896 devzero_fds = [os.open("/dev/zero", os.O_RDONLY)
897 for _ in range(8)]
898 try:
899 for fd in devzero_fds:
Gregory P. Smithf047ba82012-11-11 09:49:02 -0800900 self._testcase.assertNotIn(
901 fd, (p2cwrite, c2pread, errread))
Gregory P. Smith211248b2012-11-11 02:00:49 -0800902 finally:
Richard Oudkerk045e4572013-06-10 16:27:45 +0100903 for fd in devzero_fds:
904 os.close(fd)
Gregory P. Smith211248b2012-11-11 02:00:49 -0800905
Gregory P. Smithf047ba82012-11-11 09:49:02 -0800906 @unittest.skipIf(not os.path.exists("/dev/zero"), "/dev/zero required.")
907 def test_preexec_errpipe_does_not_double_close_pipes(self):
908 """Issue16140: Don't double close pipes on preexec error."""
909
910 def raise_it():
911 raise RuntimeError("force the _execute_child() errpipe_data path.")
Gregory P. Smith211248b2012-11-11 02:00:49 -0800912
913 with self.assertRaises(RuntimeError):
Gregory P. Smithf047ba82012-11-11 09:49:02 -0800914 self._TestExecuteChildPopen(
915 self, [sys.executable, "-c", "pass"],
916 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
917 stderr=subprocess.PIPE, preexec_fn=raise_it)
Gregory P. Smith211248b2012-11-11 02:00:49 -0800918
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000919 def test_args_string(self):
920 # args is a string
Berker Peksagb7c35152015-09-28 15:37:57 +0300921 f, fname = tempfile.mkstemp()
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000922 os.write(f, "#!/bin/sh\n")
923 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
924 sys.executable)
925 os.close(f)
926 os.chmod(fname, 0o700)
927 p = subprocess.Popen(fname)
928 p.wait()
929 os.remove(fname)
930 self.assertEqual(p.returncode, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000931
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000932 def test_invalid_args(self):
933 # invalid arguments should raise ValueError
934 self.assertRaises(ValueError, subprocess.call,
935 [sys.executable, "-c",
936 "import sys; sys.exit(47)"],
937 startupinfo=47)
938 self.assertRaises(ValueError, subprocess.call,
939 [sys.executable, "-c",
940 "import sys; sys.exit(47)"],
941 creationflags=47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000942
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000943 def test_shell_sequence(self):
944 # Run command through the shell (sequence)
945 newenv = os.environ.copy()
946 newenv["FRUIT"] = "apple"
947 p = subprocess.Popen(["echo $FRUIT"], shell=1,
948 stdout=subprocess.PIPE,
949 env=newenv)
Brian Curtind117b562010-11-05 04:09:09 +0000950 self.addCleanup(p.stdout.close)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000951 self.assertEqual(p.stdout.read().strip(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000952
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000953 def test_shell_string(self):
954 # Run command through the shell (string)
955 newenv = os.environ.copy()
956 newenv["FRUIT"] = "apple"
957 p = subprocess.Popen("echo $FRUIT", shell=1,
958 stdout=subprocess.PIPE,
959 env=newenv)
Brian Curtind117b562010-11-05 04:09:09 +0000960 self.addCleanup(p.stdout.close)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000961 self.assertEqual(p.stdout.read().strip(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000962
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000963 def test_call_string(self):
964 # call() function with string argument on UNIX
Berker Peksagb7c35152015-09-28 15:37:57 +0300965 f, fname = tempfile.mkstemp()
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000966 os.write(f, "#!/bin/sh\n")
967 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
968 sys.executable)
969 os.close(f)
970 os.chmod(fname, 0700)
971 rc = subprocess.call(fname)
972 os.remove(fname)
973 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000974
Stefan Krahe9a6a7d2010-07-19 14:41:08 +0000975 def test_specific_shell(self):
976 # Issue #9265: Incorrect name passed as arg[0].
977 shells = []
978 for prefix in ['/bin', '/usr/bin/', '/usr/local/bin']:
979 for name in ['bash', 'ksh']:
980 sh = os.path.join(prefix, name)
981 if os.path.isfile(sh):
982 shells.append(sh)
983 if not shells: # Will probably work for any shell but csh.
984 self.skipTest("bash or ksh required for this test")
985 sh = '/bin/sh'
986 if os.path.isfile(sh) and not os.path.islink(sh):
987 # Test will fail if /bin/sh is a symlink to csh.
988 shells.append(sh)
989 for sh in shells:
990 p = subprocess.Popen("echo $0", executable=sh, shell=True,
991 stdout=subprocess.PIPE)
Brian Curtind117b562010-11-05 04:09:09 +0000992 self.addCleanup(p.stdout.close)
Stefan Krahe9a6a7d2010-07-19 14:41:08 +0000993 self.assertEqual(p.stdout.read().strip(), sh)
994
Florent Xiclunac0838642010-03-07 15:27:39 +0000995 def _kill_process(self, method, *args):
Florent Xiclunacecef392010-03-05 19:31:21 +0000996 # Do not inherit file handles from the parent.
997 # It should fix failures on some platforms.
Antoine Pitroua6166da2010-09-20 11:20:44 +0000998 p = subprocess.Popen([sys.executable, "-c", """if 1:
999 import sys, time
1000 sys.stdout.write('x\\n')
1001 sys.stdout.flush()
1002 time.sleep(30)
1003 """],
1004 close_fds=True,
1005 stdin=subprocess.PIPE,
1006 stdout=subprocess.PIPE,
1007 stderr=subprocess.PIPE)
1008 # Wait for the interpreter to be completely initialized before
1009 # sending any signal.
1010 p.stdout.read(1)
1011 getattr(p, method)(*args)
Florent Xiclunac0838642010-03-07 15:27:39 +00001012 return p
1013
Charles-François Natalief2bd672013-01-12 16:52:20 +01001014 @unittest.skipIf(sys.platform.startswith(('netbsd', 'openbsd')),
1015 "Due to known OS bug (issue #16762)")
Antoine Pitrouf60845b2012-03-11 19:29:12 +01001016 def _kill_dead_process(self, method, *args):
1017 # Do not inherit file handles from the parent.
1018 # It should fix failures on some platforms.
1019 p = subprocess.Popen([sys.executable, "-c", """if 1:
1020 import sys, time
1021 sys.stdout.write('x\\n')
1022 sys.stdout.flush()
1023 """],
1024 close_fds=True,
1025 stdin=subprocess.PIPE,
1026 stdout=subprocess.PIPE,
1027 stderr=subprocess.PIPE)
1028 # Wait for the interpreter to be completely initialized before
1029 # sending any signal.
1030 p.stdout.read(1)
1031 # The process should end after this
1032 time.sleep(1)
1033 # This shouldn't raise even though the child is now dead
1034 getattr(p, method)(*args)
1035 p.communicate()
1036
Florent Xiclunac0838642010-03-07 15:27:39 +00001037 def test_send_signal(self):
1038 p = self._kill_process('send_signal', signal.SIGINT)
Florent Xiclunafc4d6d72010-03-23 14:36:45 +00001039 _, stderr = p.communicate()
Florent Xicluna3c919cf2010-03-23 19:19:16 +00001040 self.assertIn('KeyboardInterrupt', stderr)
Florent Xicluna446ff142010-03-23 15:05:30 +00001041 self.assertNotEqual(p.wait(), 0)
Christian Heimese74c8f22008-04-19 02:23:57 +00001042
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001043 def test_kill(self):
Florent Xiclunac0838642010-03-07 15:27:39 +00001044 p = self._kill_process('kill')
Florent Xicluna446ff142010-03-23 15:05:30 +00001045 _, stderr = p.communicate()
1046 self.assertStderrEqual(stderr, '')
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001047 self.assertEqual(p.wait(), -signal.SIGKILL)
Christian Heimese74c8f22008-04-19 02:23:57 +00001048
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001049 def test_terminate(self):
Florent Xiclunac0838642010-03-07 15:27:39 +00001050 p = self._kill_process('terminate')
Florent Xicluna446ff142010-03-23 15:05:30 +00001051 _, stderr = p.communicate()
1052 self.assertStderrEqual(stderr, '')
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001053 self.assertEqual(p.wait(), -signal.SIGTERM)
Tim Peterse718f612004-10-12 21:51:32 +00001054
Antoine Pitrouf60845b2012-03-11 19:29:12 +01001055 def test_send_signal_dead(self):
1056 # Sending a signal to a dead process
1057 self._kill_dead_process('send_signal', signal.SIGINT)
1058
1059 def test_kill_dead(self):
1060 # Killing a dead process
1061 self._kill_dead_process('kill')
1062
1063 def test_terminate_dead(self):
1064 # Terminating a dead process
1065 self._kill_dead_process('terminate')
1066
Antoine Pitrou91ce0d92011-01-03 18:45:09 +00001067 def check_close_std_fds(self, fds):
1068 # Issue #9905: test that subprocess pipes still work properly with
1069 # some standard fds closed
1070 stdin = 0
1071 newfds = []
1072 for a in fds:
1073 b = os.dup(a)
1074 newfds.append(b)
1075 if a == 0:
1076 stdin = b
1077 try:
1078 for fd in fds:
1079 os.close(fd)
1080 out, err = subprocess.Popen([sys.executable, "-c",
1081 'import sys;'
1082 'sys.stdout.write("apple");'
1083 'sys.stdout.flush();'
1084 'sys.stderr.write("orange")'],
1085 stdin=stdin,
1086 stdout=subprocess.PIPE,
1087 stderr=subprocess.PIPE).communicate()
1088 err = test_support.strip_python_stderr(err)
1089 self.assertEqual((out, err), (b'apple', b'orange'))
1090 finally:
1091 for b, a in zip(newfds, fds):
1092 os.dup2(b, a)
1093 for b in newfds:
1094 os.close(b)
1095
1096 def test_close_fd_0(self):
1097 self.check_close_std_fds([0])
1098
1099 def test_close_fd_1(self):
1100 self.check_close_std_fds([1])
1101
1102 def test_close_fd_2(self):
1103 self.check_close_std_fds([2])
1104
1105 def test_close_fds_0_1(self):
1106 self.check_close_std_fds([0, 1])
1107
1108 def test_close_fds_0_2(self):
1109 self.check_close_std_fds([0, 2])
1110
1111 def test_close_fds_1_2(self):
1112 self.check_close_std_fds([1, 2])
1113
1114 def test_close_fds_0_1_2(self):
1115 # Issue #10806: test that subprocess pipes still work properly with
1116 # all standard fds closed.
1117 self.check_close_std_fds([0, 1, 2])
1118
Ross Lagerwalld8e39012011-07-27 18:54:53 +02001119 def check_swap_fds(self, stdin_no, stdout_no, stderr_no):
1120 # open up some temporary files
Berker Peksagb7c35152015-09-28 15:37:57 +03001121 temps = [tempfile.mkstemp() for i in range(3)]
Ross Lagerwalld8e39012011-07-27 18:54:53 +02001122 temp_fds = [fd for fd, fname in temps]
1123 try:
1124 # unlink the files -- we won't need to reopen them
1125 for fd, fname in temps:
1126 os.unlink(fname)
1127
1128 # save a copy of the standard file descriptors
1129 saved_fds = [os.dup(fd) for fd in range(3)]
1130 try:
1131 # duplicate the temp files over the standard fd's 0, 1, 2
1132 for fd, temp_fd in enumerate(temp_fds):
1133 os.dup2(temp_fd, fd)
1134
1135 # write some data to what will become stdin, and rewind
1136 os.write(stdin_no, b"STDIN")
1137 os.lseek(stdin_no, 0, 0)
1138
1139 # now use those files in the given order, so that subprocess
1140 # has to rearrange them in the child
1141 p = subprocess.Popen([sys.executable, "-c",
1142 'import sys; got = sys.stdin.read();'
1143 'sys.stdout.write("got %s"%got); sys.stderr.write("err")'],
1144 stdin=stdin_no,
1145 stdout=stdout_no,
1146 stderr=stderr_no)
1147 p.wait()
1148
1149 for fd in temp_fds:
1150 os.lseek(fd, 0, 0)
1151
1152 out = os.read(stdout_no, 1024)
1153 err = test_support.strip_python_stderr(os.read(stderr_no, 1024))
1154 finally:
1155 for std, saved in enumerate(saved_fds):
1156 os.dup2(saved, std)
1157 os.close(saved)
1158
1159 self.assertEqual(out, b"got STDIN")
1160 self.assertEqual(err, b"err")
1161
1162 finally:
1163 for fd in temp_fds:
1164 os.close(fd)
1165
1166 # When duping fds, if there arises a situation where one of the fds is
1167 # either 0, 1 or 2, it is possible that it is overwritten (#12607).
1168 # This tests all combinations of this.
1169 def test_swap_fds(self):
1170 self.check_swap_fds(0, 1, 2)
1171 self.check_swap_fds(0, 2, 1)
1172 self.check_swap_fds(1, 0, 2)
1173 self.check_swap_fds(1, 2, 0)
1174 self.check_swap_fds(2, 0, 1)
1175 self.check_swap_fds(2, 1, 0)
1176
Gregory P. Smith312efbc2010-12-14 15:02:53 +00001177 def test_wait_when_sigchild_ignored(self):
1178 # NOTE: sigchild_ignore.py may not be an effective test on all OSes.
1179 sigchild_ignore = test_support.findfile("sigchild_ignore.py",
1180 subdir="subprocessdata")
1181 p = subprocess.Popen([sys.executable, sigchild_ignore],
1182 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
1183 stdout, stderr = p.communicate()
1184 self.assertEqual(0, p.returncode, "sigchild_ignore.py exited"
1185 " non-zero with this error:\n%s" % stderr)
1186
Charles-François Natali100df0f2011-08-18 17:56:02 +02001187 def test_zombie_fast_process_del(self):
1188 # Issue #12650: on Unix, if Popen.__del__() was called before the
1189 # process exited, it wouldn't be added to subprocess._active, and would
1190 # remain a zombie.
1191 # spawn a Popen, and delete its reference before it exits
1192 p = subprocess.Popen([sys.executable, "-c",
1193 'import sys, time;'
1194 'time.sleep(0.2)'],
1195 stdout=subprocess.PIPE,
1196 stderr=subprocess.PIPE)
Nadeem Vawda86059362011-08-19 05:22:24 +02001197 self.addCleanup(p.stdout.close)
1198 self.addCleanup(p.stderr.close)
Charles-François Natali100df0f2011-08-18 17:56:02 +02001199 ident = id(p)
1200 pid = p.pid
1201 del p
1202 # check that p is in the active processes list
1203 self.assertIn(ident, [id(o) for o in subprocess._active])
1204
Charles-François Natali100df0f2011-08-18 17:56:02 +02001205 def test_leak_fast_process_del_killed(self):
1206 # Issue #12650: on Unix, if Popen.__del__() was called before the
1207 # process exited, and the process got killed by a signal, it would never
1208 # be removed from subprocess._active, which triggered a FD and memory
1209 # leak.
1210 # spawn a Popen, delete its reference and kill it
1211 p = subprocess.Popen([sys.executable, "-c",
1212 'import time;'
1213 'time.sleep(3)'],
1214 stdout=subprocess.PIPE,
1215 stderr=subprocess.PIPE)
Nadeem Vawda86059362011-08-19 05:22:24 +02001216 self.addCleanup(p.stdout.close)
1217 self.addCleanup(p.stderr.close)
Charles-François Natali100df0f2011-08-18 17:56:02 +02001218 ident = id(p)
1219 pid = p.pid
1220 del p
1221 os.kill(pid, signal.SIGKILL)
1222 # check that p is in the active processes list
1223 self.assertIn(ident, [id(o) for o in subprocess._active])
1224
1225 # let some time for the process to exit, and create a new Popen: this
1226 # should trigger the wait() of p
1227 time.sleep(0.2)
1228 with self.assertRaises(EnvironmentError) as c:
1229 with subprocess.Popen(['nonexisting_i_hope'],
1230 stdout=subprocess.PIPE,
1231 stderr=subprocess.PIPE) as proc:
1232 pass
1233 # p should have been wait()ed on, and removed from the _active list
1234 self.assertRaises(OSError, os.waitpid, pid, 0)
1235 self.assertNotIn(ident, [id(o) for o in subprocess._active])
1236
Charles-François Natali2a34eb32011-08-25 21:20:54 +02001237 def test_pipe_cloexec(self):
1238 # Issue 12786: check that the communication pipes' FDs are set CLOEXEC,
1239 # and are not inherited by another child process.
1240 p1 = subprocess.Popen([sys.executable, "-c",
1241 'import os;'
1242 'os.read(0, 1)'
1243 ],
1244 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
1245 stderr=subprocess.PIPE)
1246
1247 p2 = subprocess.Popen([sys.executable, "-c", """if True:
1248 import os, errno, sys
1249 for fd in %r:
1250 try:
1251 os.close(fd)
1252 except OSError as e:
1253 if e.errno != errno.EBADF:
1254 raise
1255 else:
1256 sys.exit(1)
1257 sys.exit(0)
1258 """ % [f.fileno() for f in (p1.stdin, p1.stdout,
1259 p1.stderr)]
1260 ],
1261 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
1262 stderr=subprocess.PIPE, close_fds=False)
1263 p1.communicate('foo')
1264 _, stderr = p2.communicate()
1265
1266 self.assertEqual(p2.returncode, 0, "Unexpected error: " + repr(stderr))
1267
Victor Stinner2097b9e2017-06-27 00:00:51 +02001268 @unittest.skipIf(not ctypes, 'ctypes module required')
1269 @unittest.skipIf(not sys.executable, 'Test requires sys.executable')
Gregory P. Smithf0739cb2017-01-22 22:38:28 -08001270 def test_child_terminated_in_stopped_state(self):
1271 """Test wait() behavior when waitpid returns WIFSTOPPED; issue29335."""
1272 PTRACE_TRACEME = 0 # From glibc and MacOS (PT_TRACE_ME).
Victor Stinner2097b9e2017-06-27 00:00:51 +02001273 libc_name = ctypes.util.find_library('c')
Gregory P. Smithf0739cb2017-01-22 22:38:28 -08001274 libc = ctypes.CDLL(libc_name)
1275 if not hasattr(libc, 'ptrace'):
Victor Stinner2097b9e2017-06-27 00:00:51 +02001276 raise unittest.SkipTest('ptrace() required')
1277
1278 code = textwrap.dedent("""
Gregory P. Smithf0739cb2017-01-22 22:38:28 -08001279 import ctypes
Victor Stinner2d775582017-06-27 15:37:19 +02001280 from test.support import _crash_python
Victor Stinner2097b9e2017-06-27 00:00:51 +02001281
Gregory P. Smithf0739cb2017-01-22 22:38:28 -08001282 libc = ctypes.CDLL({libc_name!r})
1283 libc.ptrace({PTRACE_TRACEME}, 0, 0)
Victor Stinner2097b9e2017-06-27 00:00:51 +02001284 """.format(libc_name=libc_name, PTRACE_TRACEME=PTRACE_TRACEME))
1285
1286 child = subprocess.Popen([sys.executable, '-c', code])
1287 if child.wait() != 0:
1288 raise unittest.SkipTest('ptrace() failed - unable to test')
1289
1290 code += textwrap.dedent("""
Victor Stinner2d775582017-06-27 15:37:19 +02001291 # Crash the process
1292 _crash_python()
Victor Stinner2097b9e2017-06-27 00:00:51 +02001293 """)
1294 child = subprocess.Popen([sys.executable, '-c', code])
Gregory P. Smithf0739cb2017-01-22 22:38:28 -08001295 try:
1296 returncode = child.wait()
Victor Stinner2097b9e2017-06-27 00:00:51 +02001297 except:
Gregory P. Smithf0739cb2017-01-22 22:38:28 -08001298 child.kill() # Clean up the hung stopped process.
Victor Stinner2097b9e2017-06-27 00:00:51 +02001299 raise
Gregory P. Smithf0739cb2017-01-22 22:38:28 -08001300 self.assertNotEqual(0, returncode)
1301 self.assertLess(returncode, 0) # signal death, likely SIGSEGV.
1302
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001303
Florent Xiclunabab22a72010-03-04 19:40:48 +00001304@unittest.skipUnless(mswindows, "Windows specific tests")
Florent Xiclunafc4d6d72010-03-23 14:36:45 +00001305class Win32ProcessTestCase(BaseTestCase):
Florent Xiclunaab5e17f2010-03-04 21:31:58 +00001306
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001307 def test_startupinfo(self):
1308 # startupinfo argument
1309 # We uses hardcoded constants, because we do not want to
1310 # depend on win32all.
1311 STARTF_USESHOWWINDOW = 1
1312 SW_MAXIMIZE = 3
1313 startupinfo = subprocess.STARTUPINFO()
1314 startupinfo.dwFlags = STARTF_USESHOWWINDOW
1315 startupinfo.wShowWindow = SW_MAXIMIZE
1316 # Since Python is a console process, it won't be affected
1317 # by wShowWindow, but the argument should be silently
1318 # ignored
1319 subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001320 startupinfo=startupinfo)
1321
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001322 def test_creationflags(self):
1323 # creationflags argument
1324 CREATE_NEW_CONSOLE = 16
1325 sys.stderr.write(" a DOS box should flash briefly ...\n")
1326 subprocess.call(sys.executable +
1327 ' -c "import time; time.sleep(0.25)"',
1328 creationflags=CREATE_NEW_CONSOLE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001329
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001330 def test_invalid_args(self):
1331 # invalid arguments should raise ValueError
1332 self.assertRaises(ValueError, subprocess.call,
1333 [sys.executable, "-c",
1334 "import sys; sys.exit(47)"],
1335 preexec_fn=lambda: 1)
1336 self.assertRaises(ValueError, subprocess.call,
1337 [sys.executable, "-c",
1338 "import sys; sys.exit(47)"],
1339 stdout=subprocess.PIPE,
1340 close_fds=True)
1341
1342 def test_close_fds(self):
1343 # close file descriptors
1344 rc = subprocess.call([sys.executable, "-c",
1345 "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001346 close_fds=True)
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001347 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001348
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001349 def test_shell_sequence(self):
1350 # Run command through the shell (sequence)
1351 newenv = os.environ.copy()
1352 newenv["FRUIT"] = "physalis"
1353 p = subprocess.Popen(["set"], shell=1,
1354 stdout=subprocess.PIPE,
1355 env=newenv)
Brian Curtin7fe045e2010-11-05 17:19:38 +00001356 self.addCleanup(p.stdout.close)
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001357 self.assertIn("physalis", p.stdout.read())
Peter Astrand81a191b2007-05-26 22:18:20 +00001358
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001359 def test_shell_string(self):
1360 # Run command through the shell (string)
1361 newenv = os.environ.copy()
1362 newenv["FRUIT"] = "physalis"
1363 p = subprocess.Popen("set", shell=1,
1364 stdout=subprocess.PIPE,
1365 env=newenv)
Brian Curtin7fe045e2010-11-05 17:19:38 +00001366 self.addCleanup(p.stdout.close)
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001367 self.assertIn("physalis", p.stdout.read())
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001368
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001369 def test_call_string(self):
1370 # call() function with string argument on Windows
1371 rc = subprocess.call(sys.executable +
1372 ' -c "import sys; sys.exit(47)"')
1373 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001374
Florent Xiclunac0838642010-03-07 15:27:39 +00001375 def _kill_process(self, method, *args):
Florent Xicluna400efc22010-03-07 17:12:23 +00001376 # Some win32 buildbot raises EOFError if stdin is inherited
Antoine Pitroudee00972010-09-24 19:00:29 +00001377 p = subprocess.Popen([sys.executable, "-c", """if 1:
1378 import sys, time
1379 sys.stdout.write('x\\n')
1380 sys.stdout.flush()
1381 time.sleep(30)
1382 """],
1383 stdin=subprocess.PIPE,
1384 stdout=subprocess.PIPE,
1385 stderr=subprocess.PIPE)
Brian Curtin7fe045e2010-11-05 17:19:38 +00001386 self.addCleanup(p.stdout.close)
1387 self.addCleanup(p.stderr.close)
1388 self.addCleanup(p.stdin.close)
Antoine Pitroudee00972010-09-24 19:00:29 +00001389 # Wait for the interpreter to be completely initialized before
1390 # sending any signal.
1391 p.stdout.read(1)
1392 getattr(p, method)(*args)
Florent Xicluna446ff142010-03-23 15:05:30 +00001393 _, stderr = p.communicate()
1394 self.assertStderrEqual(stderr, '')
Antoine Pitroudee00972010-09-24 19:00:29 +00001395 returncode = p.wait()
Florent Xiclunafaf17532010-03-08 10:59:33 +00001396 self.assertNotEqual(returncode, 0)
Florent Xiclunac0838642010-03-07 15:27:39 +00001397
Antoine Pitrouf60845b2012-03-11 19:29:12 +01001398 def _kill_dead_process(self, method, *args):
1399 p = subprocess.Popen([sys.executable, "-c", """if 1:
1400 import sys, time
1401 sys.stdout.write('x\\n')
1402 sys.stdout.flush()
1403 sys.exit(42)
1404 """],
1405 stdin=subprocess.PIPE,
1406 stdout=subprocess.PIPE,
1407 stderr=subprocess.PIPE)
1408 self.addCleanup(p.stdout.close)
1409 self.addCleanup(p.stderr.close)
1410 self.addCleanup(p.stdin.close)
1411 # Wait for the interpreter to be completely initialized before
1412 # sending any signal.
1413 p.stdout.read(1)
1414 # The process should end after this
1415 time.sleep(1)
1416 # This shouldn't raise even though the child is now dead
1417 getattr(p, method)(*args)
1418 _, stderr = p.communicate()
1419 self.assertStderrEqual(stderr, b'')
1420 rc = p.wait()
1421 self.assertEqual(rc, 42)
1422
Florent Xiclunac0838642010-03-07 15:27:39 +00001423 def test_send_signal(self):
1424 self._kill_process('send_signal', signal.SIGTERM)
Christian Heimese74c8f22008-04-19 02:23:57 +00001425
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001426 def test_kill(self):
Florent Xiclunac0838642010-03-07 15:27:39 +00001427 self._kill_process('kill')
Christian Heimese74c8f22008-04-19 02:23:57 +00001428
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001429 def test_terminate(self):
Florent Xiclunac0838642010-03-07 15:27:39 +00001430 self._kill_process('terminate')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001431
Antoine Pitrouf60845b2012-03-11 19:29:12 +01001432 def test_send_signal_dead(self):
1433 self._kill_dead_process('send_signal', signal.SIGTERM)
1434
1435 def test_kill_dead(self):
1436 self._kill_dead_process('kill')
1437
1438 def test_terminate_dead(self):
1439 self._kill_dead_process('terminate')
1440
Gregory P. Smithdd7ca242009-07-04 01:49:29 +00001441
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001442@unittest.skipUnless(getattr(subprocess, '_has_poll', False),
1443 "poll system call not supported")
1444class ProcessTestCaseNoPoll(ProcessTestCase):
1445 def setUp(self):
1446 subprocess._has_poll = False
1447 ProcessTestCase.setUp(self)
Gregory P. Smithdd7ca242009-07-04 01:49:29 +00001448
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001449 def tearDown(self):
1450 subprocess._has_poll = True
1451 ProcessTestCase.tearDown(self)
Gregory P. Smithdd7ca242009-07-04 01:49:29 +00001452
1453
Gregory P. Smithcce211f2010-03-01 00:05:08 +00001454class HelperFunctionTests(unittest.TestCase):
Gregory P. Smithc1baf4a2010-03-01 02:53:24 +00001455 @unittest.skipIf(mswindows, "errno and EINTR make no sense on windows")
Gregory P. Smithcce211f2010-03-01 00:05:08 +00001456 def test_eintr_retry_call(self):
1457 record_calls = []
1458 def fake_os_func(*args):
1459 record_calls.append(args)
1460 if len(record_calls) == 2:
1461 raise OSError(errno.EINTR, "fake interrupted system call")
1462 return tuple(reversed(args))
1463
1464 self.assertEqual((999, 256),
1465 subprocess._eintr_retry_call(fake_os_func, 256, 999))
1466 self.assertEqual([(256, 999)], record_calls)
1467 # This time there will be an EINTR so it will loop once.
1468 self.assertEqual((666,),
1469 subprocess._eintr_retry_call(fake_os_func, 666))
1470 self.assertEqual([(256, 999), (666,), (666,)], record_calls)
1471
Tim Golden8e4756c2010-08-12 11:00:35 +00001472@unittest.skipUnless(mswindows, "mswindows only")
1473class CommandsWithSpaces (BaseTestCase):
1474
1475 def setUp(self):
1476 super(CommandsWithSpaces, self).setUp()
Berker Peksagb7c35152015-09-28 15:37:57 +03001477 f, fname = tempfile.mkstemp(".py", "te st")
Tim Golden8e4756c2010-08-12 11:00:35 +00001478 self.fname = fname.lower ()
1479 os.write(f, b"import sys;"
1480 b"sys.stdout.write('%d %s' % (len(sys.argv), [a.lower () for a in sys.argv]))"
1481 )
1482 os.close(f)
1483
1484 def tearDown(self):
1485 os.remove(self.fname)
1486 super(CommandsWithSpaces, self).tearDown()
1487
1488 def with_spaces(self, *args, **kwargs):
1489 kwargs['stdout'] = subprocess.PIPE
1490 p = subprocess.Popen(*args, **kwargs)
Brian Curtin7fe045e2010-11-05 17:19:38 +00001491 self.addCleanup(p.stdout.close)
Tim Golden8e4756c2010-08-12 11:00:35 +00001492 self.assertEqual(
1493 p.stdout.read ().decode("mbcs"),
1494 "2 [%r, 'ab cd']" % self.fname
1495 )
1496
1497 def test_shell_string_with_spaces(self):
1498 # call() function with string argument with spaces on Windows
Brian Curtine8c49202010-08-13 21:01:52 +00001499 self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname,
1500 "ab cd"), shell=1)
Tim Golden8e4756c2010-08-12 11:00:35 +00001501
1502 def test_shell_sequence_with_spaces(self):
1503 # call() function with sequence argument with spaces on Windows
Brian Curtine8c49202010-08-13 21:01:52 +00001504 self.with_spaces([sys.executable, self.fname, "ab cd"], shell=1)
Tim Golden8e4756c2010-08-12 11:00:35 +00001505
1506 def test_noshell_string_with_spaces(self):
1507 # call() function with string argument with spaces on Windows
1508 self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname,
1509 "ab cd"))
1510
1511 def test_noshell_sequence_with_spaces(self):
1512 # call() function with sequence argument with spaces on Windows
1513 self.with_spaces([sys.executable, self.fname, "ab cd"])
1514
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001515def test_main():
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001516 unit_tests = (ProcessTestCase,
1517 POSIXProcessTestCase,
1518 Win32ProcessTestCase,
Gregory P. Smithcce211f2010-03-01 00:05:08 +00001519 ProcessTestCaseNoPoll,
Tim Golden8e4756c2010-08-12 11:00:35 +00001520 HelperFunctionTests,
1521 CommandsWithSpaces)
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001522
Gregory P. Smithdd7ca242009-07-04 01:49:29 +00001523 test_support.run_unittest(*unit_tests)
Florent Xicluna98e3fc32010-02-27 19:20:50 +00001524 test_support.reap_children()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001525
1526if __name__ == "__main__":
1527 test_main()