@@ -393,22 +393,22 @@ class pywintypes:
393393 # POSIX defines PIPE_BUF as >= 512.
394394 _PIPE_BUF = getattr (select , 'PIPE_BUF' , 512 )
395395
396+ _FD_CLOEXEC = getattr (fcntl , 'FD_CLOEXEC' , 1 )
397+
398+ def _set_cloexec (fd , cloexec ):
399+ old = fcntl .fcntl (fd , fcntl .F_GETFD )
400+ if cloexec :
401+ fcntl .fcntl (fd , fcntl .F_SETFD , old | _FD_CLOEXEC )
402+ else :
403+ fcntl .fcntl (fd , fcntl .F_SETFD , old & ~ _FD_CLOEXEC )
404+
396405 if _posixsubprocess :
397406 _create_pipe = _posixsubprocess .cloexec_pipe
398407 else :
399408 def _create_pipe ():
400- try :
401- cloexec_flag = fcntl .FD_CLOEXEC
402- except AttributeError :
403- cloexec_flag = 1
404-
405409 fds = os .pipe ()
406-
407- old = fcntl .fcntl (fds [0 ], fcntl .F_GETFD )
408- fcntl .fcntl (fds [0 ], fcntl .F_SETFD , old | cloexec_flag )
409- old = fcntl .fcntl (fds [1 ], fcntl .F_GETFD )
410- fcntl .fcntl (fds [1 ], fcntl .F_SETFD , old | cloexec_flag )
411-
410+ _set_cloexec (fds [0 ], True )
411+ _set_cloexec (fds [1 ], True )
412412 return fds
413413
414414__all__ = ["Popen" , "PIPE" , "STDOUT" , "call" , "check_call" , "getstatusoutput" ,
@@ -1194,23 +1194,25 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
11941194 os .close (errpipe_read )
11951195
11961196 # Dup fds for child
1197- if p2cread != - 1 :
1198- os .dup2 (p2cread , 0 )
1199- if c2pwrite != - 1 :
1200- os .dup2 (c2pwrite , 1 )
1201- if errwrite != - 1 :
1202- os .dup2 (errwrite , 2 )
1197+ def _dup2 (a , b ):
1198+ # dup2() removes the CLOEXEC flag but
1199+ # we must do it ourselves if dup2()
1200+ # would be a no-op (issue #10806).
1201+ if a == b :
1202+ _set_cloexec (a , False )
1203+ elif a != - 1 :
1204+ os .dup2 (a , b )
1205+ _dup2 (p2cread , 0 )
1206+ _dup2 (c2pwrite , 1 )
1207+ _dup2 (errwrite , 2 )
12031208
12041209 # Close pipe fds. Make sure we don't close the
12051210 # same fd more than once, or standard fds.
1206- if p2cread != - 1 and p2cread not in (0 ,):
1207- os .close (p2cread )
1208- if (c2pwrite != - 1 and
1209- c2pwrite not in (p2cread , 1 )):
1210- os .close (c2pwrite )
1211- if (errwrite != - 1 and
1212- errwrite not in (p2cread , c2pwrite , 2 )):
1213- os .close (errwrite )
1211+ closed = set ()
1212+ for fd in [p2cread , c2pwrite , errwrite ]:
1213+ if fd > 2 and fd not in closed :
1214+ os .close (fd )
1215+ closed .add (fd )
12141216
12151217 # Close all other fds, if asked for
12161218 if close_fds :
0 commit comments