import os if os.name == 'nt': # The Subprocess module uses CreateProcess with bInheritHandles = TRUE # so that it can redirect stdout, stdin, and stderr. Unfortunately this # means that the subprocess also inherits all of our sockets. If # the process is long living, it will keep those sockets connected. # # These method patches use the kernel32.dll function SetHandleInformation # to make all new sockets uninheritable. # # TODO: Note that if another thread spawns a process in between the socket # creation and the call to SetHandleInformation, we're still out of luck. from msvcrt import get_osfhandle from ctypes import windll, WinError SetHandleInformation = windll.kernel32.SetHandleInformation def set_noninheritable(socket): if not SetHandleInformation(socket.fileno(), 1, 0): raise WinError() import socket original_socket = socket.socket _orig_connect = original_socket.connect _orig_connect_ex = original_socket.connect_ex _orig_accept = original_socket.accept def connect(self, address): res = _orig_connect(self, address) set_noninheritable(self) return res def connect_ex(self, address): res = _orig_connect_ex(self, address) set_noninheritable(self) return res def accept(self): conn, addr = _orig_accept(self) set_noninheritable(conn) return conn, addr original_socket.connect = connect original_socket.connect_ex = connect_ex original_socket.accept = accept