@@ -1034,91 +1034,102 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
10341034 # The first char specifies the exception type: 0 means
10351035 # OSError, 1 means some other error.
10361036 errpipe_read , errpipe_write = os .pipe ()
1037- self ._set_cloexec_flag (errpipe_write )
1038-
1039- gc_was_enabled = gc .isenabled ()
1040- # Disable gc to avoid bug where gc -> file_dealloc ->
1041- # write to stderr -> hang. http://bugs.python.org/issue1336
1042- gc .disable ()
10431037 try :
1044- self .pid = os .fork ()
1045- except :
1046- if gc_was_enabled :
1047- gc .enable ()
1048- raise
1049- self ._child_created = True
1050- if self .pid == 0 :
1051- # Child
10521038 try :
1053- # Close parent's pipe ends
1054- if p2cwrite is not None :
1055- os .close (p2cwrite )
1056- if c2pread is not None :
1057- os .close (c2pread )
1058- if errread is not None :
1059- os .close (errread )
1060- os .close (errpipe_read )
1061-
1062- # Dup fds for child
1063- if p2cread is not None :
1064- os .dup2 (p2cread , 0 )
1065- if c2pwrite is not None :
1066- os .dup2 (c2pwrite , 1 )
1067- if errwrite is not None :
1068- os .dup2 (errwrite , 2 )
1069-
1070- # Close pipe fds. Make sure we don't close the same
1071- # fd more than once, or standard fds.
1072- if p2cread is not None and p2cread not in (0 ,):
1073- os .close (p2cread )
1074- if c2pwrite is not None and c2pwrite not in (p2cread , 1 ):
1075- os .close (c2pwrite )
1076- if (errwrite is not None and
1077- errwrite not in (p2cread , c2pwrite , 2 )):
1078- os .close (errwrite )
1079-
1080- # Close all other fds, if asked for
1081- if close_fds :
1082- self ._close_fds (but = errpipe_write )
1083-
1084- if cwd is not None :
1085- os .chdir (cwd )
1086-
1087- if preexec_fn :
1088- preexec_fn ()
1089-
1090- if env is None :
1091- os .execvp (executable , args )
1092- else :
1093- os .execvpe (executable , args , env )
1094-
1095- except :
1096- exc_type , exc_value , tb = sys .exc_info ()
1097- # Save the traceback and attach it to the exception object
1098- exc_lines = traceback .format_exception (exc_type ,
1099- exc_value ,
1100- tb )
1101- exc_value .child_traceback = '' .join (exc_lines )
1102- os .write (errpipe_write , pickle .dumps (exc_value ))
1103-
1104- # This exitcode won't be reported to applications, so it
1105- # really doesn't matter what we return.
1106- os ._exit (255 )
1107-
1108- # Parent
1109- if gc_was_enabled :
1110- gc .enable ()
1111- os .close (errpipe_write )
1112- if p2cread is not None and p2cwrite is not None :
1113- os .close (p2cread )
1114- if c2pwrite is not None and c2pread is not None :
1115- os .close (c2pwrite )
1116- if errwrite is not None and errread is not None :
1117- os .close (errwrite )
1118-
1119- # Wait for exec to fail or succeed; possibly raising exception
1120- data = os .read (errpipe_read , 1048576 ) # Exceptions limited to 1 MB
1121- os .close (errpipe_read )
1039+ self ._set_cloexec_flag (errpipe_write )
1040+
1041+ gc_was_enabled = gc .isenabled ()
1042+ # Disable gc to avoid bug where gc -> file_dealloc ->
1043+ # write to stderr -> hang. http://bugs.python.org/issue1336
1044+ gc .disable ()
1045+ try :
1046+ self .pid = os .fork ()
1047+ except :
1048+ if gc_was_enabled :
1049+ gc .enable ()
1050+ raise
1051+ self ._child_created = True
1052+ if self .pid == 0 :
1053+ # Child
1054+ try :
1055+ # Close parent's pipe ends
1056+ if p2cwrite is not None :
1057+ os .close (p2cwrite )
1058+ if c2pread is not None :
1059+ os .close (c2pread )
1060+ if errread is not None :
1061+ os .close (errread )
1062+ os .close (errpipe_read )
1063+
1064+ # Dup fds for child
1065+ if p2cread is not None :
1066+ os .dup2 (p2cread , 0 )
1067+ if c2pwrite is not None :
1068+ os .dup2 (c2pwrite , 1 )
1069+ if errwrite is not None :
1070+ os .dup2 (errwrite , 2 )
1071+
1072+ # Close pipe fds. Make sure we don't close the
1073+ # same fd more than once, or standard fds.
1074+ if p2cread is not None and p2cread not in (0 ,):
1075+ os .close (p2cread )
1076+ if c2pwrite is not None and \
1077+ c2pwrite not in (p2cread , 1 ):
1078+ os .close (c2pwrite )
1079+ if (errwrite is not None and
1080+ errwrite not in (p2cread , c2pwrite , 2 )):
1081+ os .close (errwrite )
1082+
1083+ # Close all other fds, if asked for
1084+ if close_fds :
1085+ self ._close_fds (but = errpipe_write )
1086+
1087+ if cwd is not None :
1088+ os .chdir (cwd )
1089+
1090+ if preexec_fn :
1091+ preexec_fn ()
1092+
1093+ if env is None :
1094+ os .execvp (executable , args )
1095+ else :
1096+ os .execvpe (executable , args , env )
1097+
1098+ except :
1099+ exc_type , exc_value , tb = sys .exc_info ()
1100+ # Save the traceback and attach it to the exception
1101+ # object
1102+ exc_lines = traceback .format_exception (exc_type ,
1103+ exc_value ,
1104+ tb )
1105+ exc_value .child_traceback = '' .join (exc_lines )
1106+ os .write (errpipe_write , pickle .dumps (exc_value ))
1107+
1108+ # This exitcode won't be reported to applications, so
1109+ # it really doesn't matter what we return.
1110+ os ._exit (255 )
1111+
1112+ # Parent
1113+ if gc_was_enabled :
1114+ gc .enable ()
1115+ finally :
1116+ # be sure the FD is closed no matter what
1117+ os .close (errpipe_write )
1118+
1119+ if p2cread is not None and p2cwrite is not None :
1120+ os .close (p2cread )
1121+ if c2pwrite is not None and c2pread is not None :
1122+ os .close (c2pwrite )
1123+ if errwrite is not None and errread is not None :
1124+ os .close (errwrite )
1125+
1126+ # Wait for exec to fail or succeed; possibly raising an
1127+ # exception (limited to 1 MB)
1128+ data = os .read (errpipe_read , 1048576 )
1129+ finally :
1130+ # be sure the FD is closed no matter what
1131+ os .close (errpipe_read )
1132+
11221133 if data :
11231134 os .waitpid (self .pid , 0 )
11241135 child_exception = pickle .loads (data )
0 commit comments