]> granicus.if.org Git - python/commitdiff
In subprocess, wrap pipe fds before launching the child. Hopefully this
authorAntoine Pitrou <solipsis@pitrou.net>
Tue, 4 Jan 2011 19:07:07 +0000 (19:07 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Tue, 4 Jan 2011 19:07:07 +0000 (19:07 +0000)
will fix intermittent failures on some buildbots (issue #8458).

Lib/subprocess.py

index 5c5e9f27a97b560315704a58683fc8ffa04480c8..c02fb525ec57af9f3cf93e86d7158a3778ba2cf6 100644 (file)
@@ -699,13 +699,9 @@ class Popen(object):
          c2pread, c2pwrite,
          errread, errwrite) = self._get_handles(stdin, stdout, stderr)
 
-        self._execute_child(args, executable, preexec_fn, close_fds,
-                            pass_fds, cwd, env, universal_newlines,
-                            startupinfo, creationflags, shell,
-                            p2cread, p2cwrite,
-                            c2pread, c2pwrite,
-                            errread, errwrite,
-                            restore_signals, start_new_session)
+        # We wrap OS handles *before* launching the child, otherwise a
+        # quickly terminating child could make our fds unwrappable
+        # (see #8458).
 
         if mswindows:
             if p2cwrite != -1:
@@ -730,6 +726,24 @@ class Popen(object):
             if universal_newlines:
                 self.stderr = io.TextIOWrapper(self.stderr)
 
+        try:
+            self._execute_child(args, executable, preexec_fn, close_fds,
+                                pass_fds, cwd, env, universal_newlines,
+                                startupinfo, creationflags, shell,
+                                p2cread, p2cwrite,
+                                c2pread, c2pwrite,
+                                errread, errwrite,
+                                restore_signals, start_new_session)
+        except:
+            # Cleanup if the child failed starting
+            for f in filter(None, [self.stdin, self.stdout, self.stderr]):
+                try:
+                    f.close()
+                except EnvironmentError:
+                    # Ignore EBADF or other errors
+                    pass
+            raise
+
 
     def _translate_newlines(self, data, encoding):
         data = data.replace(b"\r\n", b"\n").replace(b"\r", b"\n")