def __init__(self, process_obj): prep_data = spawn.get_preparation_data(process_obj._name) rhandle, whandle = _winapi.CreatePipe(None, 0) wfd = msvcrt.open_osfhandle(whandle, 0) cmd = spawn.get_command_line(parent_pid=os.getpid(), pipe_handle= rhandle) cmd = ' '.join('"%s"' % x for x in cmd) with open(wfd, 'wb', closefd=True) as to_child: try: hp, ht, pid, tid = _winapi.CreateProcess(spawn. get_executable(), cmd, None, None, False, 0, None, None, None) _winapi.CloseHandle(ht) except: _winapi.CloseHandle(rhandle) raise self.pid = pid self.returncode = None self._handle = hp self.sentinel = int(hp) util.Finalize(self, _winapi.CloseHandle, (self.sentinel,)) set_spawning_popen(self) try: reduction.dump(prep_data, to_child) reduction.dump(process_obj, to_child) finally: set_spawning_popen(None)
def __init__(self, process_obj): cmd = ' '.join('"%s"' % x for x in get_command_line()) prep_data = get_preparation_data(process_obj._name) # create pipe for communication with child rfd, wfd = os.pipe() # get handle for read end of the pipe and make it inheritable rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True) os.close(rfd) with open(wfd, 'wb', closefd=True) as to_child: # start process try: hp, ht, pid, tid = _winapi.CreateProcess( _python_exe, cmd + (' %s' % rhandle), None, None, 1, 0, None, None, None) _winapi.CloseHandle(ht) finally: close(rhandle) # set attributes of self self.pid = pid self.returncode = None self._handle = hp self.sentinel = int(hp) # send information to child Popen._tls.process_handle = int(hp) try: dump(prep_data, to_child, HIGHEST_PROTOCOL) dump(process_obj, to_child, HIGHEST_PROTOCOL) finally: del Popen._tls.process_handle
def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_start_new_session): if not isinstance(args, str): args = list2cmdline(args) if startupinfo is None: startupinfo = STARTUPINFO() if -1 not in (p2cread, c2pwrite, errwrite): startupinfo.hStdInput = p2cread startupinfo.hStdOutput = c2pwrite startupinfo.hStdError = errwrite if shell: startupinfo.wShowWindow = _winapi.SW_HIDE comspec = os.environ.get('COMSPEC', 'cmd.exe') args = '{} /c "{}"'.format(comspec, args) if _winapi.GetVersion() >= 2147483648 or os.path.basename(comspec).lower() == 'command.com': w9xpopen = self._find_w9xpopen() args = '"%s" %s' % (w9xpopen, args) creationflags |= _winapi.CREATE_NEW_CONSOLE try: (hp, ht, pid, tid) = _winapi.CreateProcess(executable, args, None, None, int(not close_fds), creationflags, env, cwd, startupinfo) except pywintypes.error as e: raise WindowsError(*e.args) finally: if p2cread != -1: p2cread.Close() if c2pwrite != -1: c2pwrite.Close() if errwrite != -1: errwrite.Close() if hasattr(self, '_devnull'): os.close(self._devnull) self._child_created = True self._handle = Handle(hp) self.pid = pid _winapi.CloseHandle(ht)
def __init__(self, process_obj): prep_data = spawn.get_preparation_data(process_obj._name) # read end of pipe will be duplicated by the child process # -- see spawn_main() in spawn.py. # # bpo-33929: Previously, the read end of pipe was "stolen" by the child # process, but it leaked a handle if the child process had been # terminated before it could steal the handle from the parent process. rhandle, whandle = _winapi.CreatePipe(None, 0) wfd = msvcrt.open_osfhandle(whandle, 0) cmd = spawn.get_command_line(parent_pid=os.getpid(), pipe_handle=rhandle) cmd = ' '.join('"%s"' % x for x in cmd) python_exe = spawn.get_executable() # bpo-35797: When running in a venv, we bypass the redirect # executor and launch our base Python. if WINENV and _path_eq(python_exe, sys.executable): python_exe = sys._base_executable env = os.environ.copy() env["__PYVENV_LAUNCHER__"] = sys.executable else: env = os.environ.copy() env['Y_PYTHON_ENTRY_POINT'] = ':main' with open(wfd, 'wb', closefd=True) as to_child: # start process try: hp, ht, pid, tid = _winapi.CreateProcess( python_exe, cmd, None, None, False, 0, env, None, None) _winapi.CloseHandle(ht) except: _winapi.CloseHandle(rhandle) raise # set attributes of self self.pid = pid self.returncode = None self._handle = hp self.sentinel = int(hp) self.finalizer = util.Finalize(self, _close_handles, (self.sentinel, int(rhandle))) # send information to child set_spawning_popen(self) try: reduction.dump(prep_data, to_child) reduction.dump(process_obj, to_child) finally: set_spawning_popen(None)
def __init__(self, process_obj): prep_data = spawn.get_preparation_data(process_obj._name) # read end of pipe will be duplicated by the child process # -- see spawn_main() in spawn.py. # # bpo-33929: Previously, the read end of pipe was "stolen" by the child # process, but it leaked a handle if the child process had been # terminated before it could steal the handle from the parent process. rhandle, whandle = _winapi.CreatePipe(None, 0) wfd = msvcrt.open_osfhandle(whandle, 0) cmd = spawn.get_command_line(parent_pid=os.getpid(), pipe_handle=rhandle) cmd = ' '.join('"%s"' % x for x in cmd) with open(wfd, 'wb', closefd=True) as to_child: # start process try: hp, ht, pid, tid = _winapi.CreateProcess( spawn.get_executable(), cmd, None, None, False, 0, None, None, None) _winapi.CloseHandle(ht) except: _winapi.CloseHandle(rhandle) raise # set attributes of self self.pid = pid self.returncode = None self._handle = hp self.sentinel = int(hp) self.finalizer = util.Finalize(self, _close_handles, (self.sentinel, int(rhandle))) # send information to child set_spawning_popen(self) try: reduction.dump(prep_data, to_child) reduction.dump(process_obj, to_child) finally: set_spawning_popen(None)
def spawnv_passfds(path, args, passfds): passfds = sorted(passfds) if sys.platform != "win32": errpipe_read, errpipe_write = os.pipe() try: from .reduction import _mk_inheritable from .fork_exec import fork_exec _pass = [_mk_inheritable(fd) for fd in passfds] return fork_exec(args, _pass) finally: os.close(errpipe_read) os.close(errpipe_write) else: cmd = ' '.join(f'"{x}"' for x in args) try: hp, ht, pid, tid = _winapi.CreateProcess( path, cmd, None, None, True, 0, None, None, None) _winapi.CloseHandle(ht) except BaseException: pass return pid
def __init__(self, process_obj): prep_data = spawn.get_preparation_data(process_obj._name) # read end of pipe will be "stolen" by the child process # -- see spawn_main() in spawn.py. rhandle, whandle = _winapi.CreatePipe(None, 0) wfd = msvcrt.open_osfhandle(whandle, 0) cmd = spawn.get_command_line(parent_pid=os.getpid(), pipe_handle=rhandle) cmd = ' '.join('"%s"' % x for x in cmd) with open(wfd, 'wb', closefd=True) as to_child: # start process try: hp, ht, pid, tid = _winapi.CreateProcess( spawn.get_executable(), cmd, None, None, False, 0, None, None, None) _winapi.CloseHandle(ht) except: _winapi.CloseHandle(rhandle) raise # set attributes of self self.pid = pid self.returncode = None self._handle = hp self.sentinel = int(hp) util.Finalize(self, _winapi.CloseHandle, (self.sentinel, )) # send information to child popen.set_spawning_popen(self) try: reduction.dump(prep_data, to_child) reduction.dump(process_obj, to_child) finally: popen.set_spawning_popen(None)
def __init__(self, process_obj): prep_data = spawn.get_preparation_data( process_obj._name, getattr(process_obj, "init_main_module", True)) # read end of pipe will be "stolen" by the child process # -- see spawn_main() in spawn.py. rfd, wfd = os.pipe() rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True) os.close(rfd) cmd = get_command_line(parent_pid=os.getpid(), pipe_handle=rhandle) cmd = ' '.join(f'"{x}"' for x in cmd) python_exe = spawn.get_executable() # copy the environment variables to set in the child process child_env = os.environ.copy() child_env.update(process_obj.env) # bpo-35797: When running in a venv, we bypass the redirect # executor and launch our base Python. if WINENV and _path_eq(python_exe, sys.executable): python_exe = sys._base_executable child_env["__PYVENV_LAUNCHER__"] = sys.executable try: with open(wfd, 'wb') as to_child: # start process try: # This flag allows to pass inheritable handles from the # parent to the child process in a python2-3 compatible way # (see # https://github.com/tomMoral/loky/pull/204#discussion_r290719629 # for more detail). When support for Python 2 is dropped, # the cleaner multiprocessing.reduction.steal_handle should # be used instead. inherit = True hp, ht, pid, tid = _winapi.CreateProcess( python_exe, cmd, None, None, inherit, 0, child_env, None, None) _winapi.CloseHandle(ht) except BaseException: _winapi.CloseHandle(rhandle) raise # set attributes of self self.pid = pid self.returncode = None self._handle = hp self.sentinel = int(hp) util.Finalize(self, _winapi.CloseHandle, (self.sentinel, )) # send information to child set_spawning_popen(self) try: reduction.dump(prep_data, to_child) reduction.dump(process_obj, to_child) finally: set_spawning_popen(None) except IOError as exc: # IOError 22 happens when the launched subprocess terminated before # wfd.close is called. Thus we can safely ignore it. if exc.errno != 22: raise util.debug( f"While starting {process_obj._name}, ignored a IOError 22")
def _execute_child_compat(self, args, executable, preexec_fn, close_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite): if not isinstance(args, str): args = subprocess.list2cmdline(args) # Always or in the create new process group creationflags |= winprocess.CREATE_NEW_PROCESS_GROUP if startupinfo is None: startupinfo = winprocess.STARTUPINFO() if None not in (p2cread, c2pwrite, errwrite): startupinfo.dwFlags |= winprocess.STARTF_USESTDHANDLES startupinfo.hStdInput = int(p2cread) startupinfo.hStdOutput = int(c2pwrite) startupinfo.hStdError = int(errwrite) if shell: startupinfo.dwFlags |= winprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = winprocess.SW_HIDE comspec = os.environ.get("COMSPEC", "cmd.exe") args = comspec + " /c " + args # determine if we can create create a job canCreateJob = winprocess.CanCreateJobObject() # set process creation flags creationflags |= winprocess.CREATE_SUSPENDED creationflags |= winprocess.CREATE_UNICODE_ENVIRONMENT if canCreateJob: creationflags |= winprocess.CREATE_BREAKAWAY_FROM_JOB # create the process hp, ht, pid, tid = _winapi.CreateProcess( executable, args, None, None, # No special security 1, # Must inherit handles! creationflags, env, cwd, startupinfo) self._child_created = True self._handle = int(hp) self._thread = ht self.pid = pid self.tid = tid if canCreateJob: # We create a new job for this process, so that we can kill # the process and any sub-processes self._job = winprocess.CreateJobObject() winprocess.AssignProcessToJobObject(self._job, int(hp)) else: self._job = None winprocess.ResumeThread(int(ht)) _winapi.CloseHandle(ht) if p2cread is not None and p2cread != -1: p2cread.Close() if c2pwrite is not None and c2pwrite != -1: c2pwrite.Close() if errwrite is not None and errwrite != -1: errwrite.Close() time.sleep(.1)