summaryrefslogtreecommitdiff
path: root/Lib/subprocess.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/subprocess.py')
-rw-r--r--Lib/subprocess.py33
1 files changed, 20 insertions, 13 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 56e05a3774..5aee34df54 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -289,6 +289,7 @@ mswindows = (sys.platform == "win32")
import io
import os
import traceback
+import gc
# Exception classes used by this module.
class CalledProcessError(Exception):
@@ -397,8 +398,8 @@ def list2cmdline(seq):
2) A string surrounded by double quotation marks is
interpreted as a single argument, regardless of white space
- contained within. A quoted string can be embedded in an
- argument.
+ or pipe characters contained within. A quoted string can be
+ embedded in an argument.
3) A double quotation mark preceded by a backslash is
interpreted as a literal double quotation mark.
@@ -424,7 +425,7 @@ def list2cmdline(seq):
if result:
result.append(' ')
- needquote = (" " in arg) or ("\t" in arg) or arg == ""
+ needquote = (" " in arg) or ("\t" in arg) or ("|" in arg) or not arg
if needquote:
result.append('"')
@@ -433,7 +434,7 @@ def list2cmdline(seq):
# Don't know if we need to double yet.
bs_buf.append(c)
elif c == '"':
- # Double backspaces.
+ # Double backslashes.
result.append('\\' * len(bs_buf)*2)
bs_buf = []
result.append('\\"')
@@ -444,7 +445,7 @@ def list2cmdline(seq):
bs_buf = []
result.append(c)
- # Add remaining backspaces, if any.
+ # Add remaining backslashes, if any.
if bs_buf:
result.extend(bs_buf)
@@ -887,13 +888,8 @@ class Popen(object):
def _close_fds(self, but):
- for i in range(3, MAXFD):
- if i == but:
- continue
- try:
- os.close(i)
- except:
- pass
+ os.closerange(3, but)
+ os.closerange(but + 1, MAXFD)
def _execute_child(self, args, executable, preexec_fn, close_fds,
@@ -921,7 +917,16 @@ class Popen(object):
errpipe_read, errpipe_write = os.pipe()
self._set_cloexec_flag(errpipe_write)
- self.pid = os.fork()
+ gc_was_enabled = gc.isenabled()
+ # Disable gc to avoid bug where gc -> file_dealloc ->
+ # write to stderr -> hang. http://bugs.python.org/issue1336
+ gc.disable()
+ try:
+ self.pid = os.fork()
+ except:
+ if gc_was_enabled:
+ gc.enable()
+ raise
self._child_created = True
if self.pid == 0:
# Child
@@ -982,6 +987,8 @@ class Popen(object):
os._exit(255)
# Parent
+ if gc_was_enabled:
+ gc.enable()
os.close(errpipe_write)
if p2cread is not None and p2cwrite is not None:
os.close(p2cread)