예제 #1
0
def spawnv_passfds(path, args, passfds):
    import _posixsubprocess

    passfds = sorted(passfds)
    errpipe_read, errpipe_write = os.pipe()
    try:
        return _posixsubprocess.fork_exec(
            args,
            [os.fsencode(path)],
            True,
            passfds,
            None,
            None,
            -1,
            -1,
            -1,
            -1,
            -1,
            -1,
            errpipe_read,
            errpipe_write,
            False,
            False,
            None,
        )
    finally:
        os.close(errpipe_read)
        os.close(errpipe_write)
예제 #2
0
 def spawnv_passfds(path, args, passfds):
     passfds = sorted(passfds)
     errpipe_read, errpipe_write = os.pipe()
     try:
         return _posixsubprocess.fork_exec(
             args,
             [fsencode(path)],
             True,
             tuple(passfds),
             None,
             None,
             -1,
             -1,
             -1,
             -1,
             -1,
             -1,
             errpipe_read,
             errpipe_write,
             False,
             False,
             None,
         )
     finally:
         os.close(errpipe_read)
         os.close(errpipe_write)
예제 #3
0
def spawnv_passfds(path, args, passfds):
    import _posixsubprocess
    passfds = tuple(sorted(map(int, passfds)))
    errpipe_read, errpipe_write = os.pipe()
    # iOS: just return fork_exec, don't close the threads.
    if (sys.platform == 'darwin' and os.uname().machine.startswith('iP')):
        return _posixsubprocess.fork_exec(args, [os.fsencode(path)], True,
                                          passfds, None, None, -1, -1, -1, -1,
                                          -1, -1, errpipe_read, errpipe_write,
                                          False, False, None, None, None, -1,
                                          None)
    try:
        return _posixsubprocess.fork_exec(args, [os.fsencode(path)], True,
                                          passfds, None, None, -1, -1, -1, -1,
                                          -1, -1, errpipe_read, errpipe_write,
                                          False, False, None, None, None, -1,
                                          None)
    finally:
        os.close(errpipe_read)
        os.close(errpipe_write)
예제 #4
0
def spawnv_passfds(path, args, passfds):
    import _posixsubprocess
    passfds = tuple(sorted(map(int, passfds)))
    errpipe_read, errpipe_write = os.pipe()
    try:
        return _posixsubprocess.fork_exec(args, [os.fsencode(path)], True,
                                          passfds, None, None, -1, -1, -1, -1,
                                          -1, -1, errpipe_read, errpipe_write,
                                          False, False, None)
    finally:
        os.close(errpipe_read)
        os.close(errpipe_write)
예제 #5
0
 def spawnv_passfds(path, args, passfds):
     passfds = sorted(passfds)
     errpipe_read, errpipe_write = os.pipe()
     try:
         args = [
             args, [fsencode(path)], True,
             tuple(passfds), None, None, -1, -1, -1, -1, -1, -1,
             errpipe_read, errpipe_write, False, False
         ]
         if sys.version_info >= (3, 9):
             args.extend(
                 (None, None, None, -1))  # group, extra_groups, user, umask
         args.append(None)  # preexec_fn
         return _posixsubprocess.fork_exec(*args)
     finally:
         os.close(errpipe_read)
         os.close(errpipe_write)
예제 #6
0
def spawnv_passfds(path, args, passfds):
    passfds = sorted(passfds)
    errpipe_read, errpipe_write = os.pipe()
    try:
        if sys.version_info >= (3, 3):
            import _posixsubprocess
            return _posixsubprocess.fork_exec(
                args, [os.fsencode(path)], True, passfds, None, None,
                -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write,
                False, False, None)
        else:
            from .reduction import _mk_inheritable
            _pass = []
            for fd in passfds:
                _pass += [_mk_inheritable(fd)]
            from .fork_exec import fork_exec
            fork_exec(args, _pass)
    finally:
        os.close(errpipe_read)
        os.close(errpipe_write)
예제 #7
0
파일: util.py 프로젝트: vermeerlee/cpython
def spawnv_passfds(path, args, passfds):
    if sys.platform == 'vxworks':
        import _vxwapi
    else:
        import _posixsubprocess
    passfds = tuple(sorted(map(int, passfds)))
    errpipe_read, errpipe_write = os.pipe()
    try:
        if sys.platform == 'vxworks':
            return _vxwapi.rtp_spawn(args, [os.fsencode(path)], True, passfds,
                                     None, None, -1, -1, -1, -1, -1, -1,
                                     errpipe_read, errpipe_write, False, False,
                                     None)
        else:
            return _posixsubprocess.fork_exec(args, [os.fsencode(path)], True,
                                              passfds, None, None, -1, -1, -1,
                                              -1, -1, -1, errpipe_read,
                                              errpipe_write, False, False,
                                              None, None, None, -1, None)
    finally:
        os.close(errpipe_read)
        os.close(errpipe_write)
예제 #8
0
def spawnv_passfds(path, args, passfds):
    import _posixsubprocess, fcntl
    passfds = sorted(passfds)
    tmp = []
    # temporarily unset CLOEXEC on passed fds
    for fd in passfds:
        flag = fcntl.fcntl(fd, fcntl.F_GETFD)
        if flag & fcntl.FD_CLOEXEC:
            fcntl.fcntl(fd, fcntl.F_SETFD, flag & ~fcntl.FD_CLOEXEC)
            tmp.append((fd, flag))
    errpipe_read, errpipe_write = _posixsubprocess.cloexec_pipe()
    try:
        return _posixsubprocess.fork_exec(
            args, [os.fsencode(path)], True, passfds, None, None,
            -1, -1, -1, -1, -1, -1, errpipe_read, errpipe_write,
            False, False, None)
    finally:
        os.close(errpipe_read)
        os.close(errpipe_write)
        # reset CLOEXEC where necessary
        for fd, flag in tmp:
            fcntl.fcntl(fd, fcntl.F_SETFD, flag)
예제 #9
0
 def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, start_new_session):
     if isinstance(args, (str, bytes)):
         args = [args]
     else:
         args = list(args)
     if shell:
         args = ['/bin/sh', '-c'] + args
         if executable:
             args[0] = executable
     if executable is None:
         executable = args[0]
     orig_executable = executable
     (errpipe_read, errpipe_write) = _create_pipe()
     try:
         try:
             if env is not None:
                 env_list = [os.fsencode(k) + b'=' + os.fsencode(v) for (k, v) in env.items()]
             else:
                 env_list = None
             executable = os.fsencode(executable)
             if os.path.dirname(executable):
                 executable_list = (executable,)
             else:
                 executable_list = tuple(os.path.join(os.fsencode(dir), executable) for dir in os.get_exec_path(env))
             fds_to_keep = set(pass_fds)
             fds_to_keep.add(errpipe_write)
             self.pid = _posixsubprocess.fork_exec(args, executable_list, close_fds, sorted(fds_to_keep), cwd, env_list, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, restore_signals, start_new_session, preexec_fn)
             self._child_created = True
         finally:
             os.close(errpipe_write)
         devnull_fd = getattr(self, '_devnull', None)
         if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd:
             os.close(p2cread)
         if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd:
             os.close(c2pwrite)
         if errwrite != -1 and errread != -1 and errwrite != devnull_fd:
             os.close(errwrite)
         if devnull_fd is not None:
             os.close(devnull_fd)
         self._closed_child_pipe_fds = True
         errpipe_data = bytearray()
         while True:
             part = _eintr_retry_call(os.read, errpipe_read, 50000)
             errpipe_data += part
             if not part or len(errpipe_data) > 50000:
                 break
     finally:
         os.close(errpipe_read)
     if errpipe_data:
         try:
             _eintr_retry_call(os.waitpid, self.pid, 0)
         except OSError as e:
             while e.errno != errno.ECHILD:
                 raise
         try:
             (exception_name, hex_errno, err_msg) = errpipe_data.split(b':', 2)
         except ValueError:
             exception_name = b'RuntimeError'
             hex_errno = b'0'
             err_msg = b'Bad exception data from child: ' + repr(errpipe_data)
         child_exception_type = getattr(builtins, exception_name.decode('ascii'), RuntimeError)
         err_msg = err_msg.decode(errors='surrogatepass')
         if issubclass(child_exception_type, OSError) and hex_errno:
             errno_num = int(hex_errno, 16)
             child_exec_never_called = err_msg == 'noexec'
             if child_exec_never_called:
                 err_msg = ''
             if errno_num != 0:
                 err_msg = os.strerror(errno_num)
                 if errno_num == errno.ENOENT:
                     if child_exec_never_called:
                         err_msg += ': ' + repr(cwd)
                     else:
                         err_msg += ': ' + repr(orig_executable)
             raise child_exception_type(errno_num, err_msg)
         raise child_exception_type(err_msg)
예제 #10
0
        def _execute_child(self, 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):
            if isinstance(args, types.StringTypes):
                args = [args]
            else:
                args = list(args)
            if shell:
                args = ['/bin/sh', '-c'] + args
                if executable:
                    args[0] = executable
            if executable is None:
                executable = args[0]
            errpipe_read, errpipe_write = _create_pipe()
            try:
                try:
                    if _posixsubprocess:
                        fs_encoding = sys.getfilesystemencoding()

                        def fs_encode(s):
                            if isinstance(s, str):
                                return s
                            else:
                                return s.encode(fs_encoding, 'strict')

                        if env is not None:
                            env_list = [ fs_encode(k) + '=' + fs_encode(v) for k, v in env.items() ]
                        else:
                            env_list = None
                        if os.path.dirname(executable):
                            executable_list = (fs_encode(executable),)
                        else:
                            path_list = _get_exec_path(env)
                            executable_list = (os.path.join(dir, executable) for dir in path_list)
                            executable_list = tuple((fs_encode(exe) for exe in executable_list))
                        fds_to_keep = set(pass_fds)
                        fds_to_keep.add(errpipe_write)
                        self.pid = _posixsubprocess.fork_exec(args, executable_list, close_fds, sorted(fds_to_keep), cwd, env_list, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, restore_signals, start_new_session, preexec_fn)
                        self._child_created = True
                    else:
                        gc_was_enabled = gc.isenabled()
                        gc.disable()
                        try:
                            self.pid = os.fork()
                        except:
                            if gc_was_enabled:
                                gc.enable()
                            raise

                        self._child_created = True
                        if self.pid == 0:
                            try:
                                if p2cwrite != -1:
                                    os.close(p2cwrite)
                                if c2pread != -1:
                                    os.close(c2pread)
                                if errread != -1:
                                    os.close(errread)
                                os.close(errpipe_read)
                                if c2pwrite == 0:
                                    c2pwrite = os.dup(c2pwrite)
                                if errwrite == 0 or errwrite == 1:
                                    errwrite = os.dup(errwrite)

                                def _dup2(a, b):
                                    if a == b:
                                        _set_cloexec(a, False)
                                    elif a != -1:
                                        os.dup2(a, b)

                                _dup2(p2cread, 0)
                                _dup2(c2pwrite, 1)
                                _dup2(errwrite, 2)
                                closed = set()
                                for fd in [p2cread, c2pwrite, errwrite]:
                                    if fd > 2 and fd not in closed:
                                        os.close(fd)
                                        closed.add(fd)

                                if close_fds:
                                    if pass_fds:
                                        fds_to_keep = set(pass_fds)
                                        fds_to_keep.add(errpipe_write)
                                        self._close_all_but_a_sorted_few_fds(sorted(fds_to_keep))
                                    else:
                                        self._close_fds(but=errpipe_write)
                                if cwd is not None:
                                    os.chdir(cwd)
                                if restore_signals:
                                    signals = ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ')
                                    for sig in signals:
                                        if hasattr(signal, sig):
                                            signal.signal(getattr(signal, sig), signal.SIG_DFL)

                                if start_new_session and hasattr(os, 'setsid'):
                                    os.setsid()
                                if preexec_fn:
                                    preexec_fn()
                                if env is None:
                                    os.execvp(executable, args)
                                else:
                                    os.execvpe(executable, args, env)
                            except:
                                try:
                                    exc_type, exc_value = sys.exc_info()[:2]
                                    if isinstance(exc_value, OSError):
                                        errno_num = exc_value.errno
                                    else:
                                        errno_num = 0
                                    message = '%s:%x:%s' % (exc_type.__name__, errno_num, exc_value)
                                    os.write(errpipe_write, message)
                                except Exception:
                                    pass

                            os._exit(255)
                        if gc_was_enabled:
                            gc.enable()
                finally:
                    os.close(errpipe_write)

                if p2cread != -1 and p2cwrite != -1:
                    os.close(p2cread)
                if c2pwrite != -1 and c2pread != -1:
                    os.close(c2pwrite)
                if errwrite != -1 and errread != -1:
                    os.close(errwrite)
                data = ''
                while True:
                    part = _eintr_retry_call(os.read, errpipe_read, 50000)
                    data += part
                    if not part or len(data) > 50000:
                        break

            finally:
                os.close(errpipe_read)

            if data != '':
                try:
                    _eintr_retry_call(os.waitpid, self.pid, 0)
                except OSError as e:
                    if e.errno != errno.ECHILD:
                        raise

                try:
                    exception_name, hex_errno, err_msg = data.split(':', 2)
                except ValueError:
                    print 'Bad exception data:', repr(data)
                    exception_name = 'RuntimeError'
                    hex_errno = '0'
                    err_msg = 'Unknown'

                child_exception_type = getattr(exceptions, exception_name, RuntimeError)
                for fd in (p2cwrite, c2pread, errread):
                    if fd != -1:
                        os.close(fd)

                if issubclass(child_exception_type, OSError) and hex_errno:
                    errno_num = int(hex_errno, 16)
                    if errno_num != 0:
                        err_msg = os.strerror(errno_num)
                        if errno_num == errno.ENOENT:
                            err_msg += ': ' + repr(args[0])
                    raise child_exception_type(errno_num, err_msg)
                try:
                    exception = child_exception_type(err_msg)
                except Exception:
                    exception = RuntimeError('Could not re-raise %r exception from the child with error message %r' % (child_exception_type, err_msg))

                raise exception