def test_pipe_overlapped(self):
     h1, h2 = windows_utils.pipe(overlapped=(True, True))
     try:
         ov1 = _overlapped.Overlapped()
         self.assertFalse(ov1.pending)
         self.assertEqual(ov1.error, 0)
         ov1.ReadFile(h1, 100)
         self.assertTrue(ov1.pending)
         self.assertEqual(ov1.error, _winapi.ERROR_IO_PENDING)
         ERROR_IO_INCOMPLETE = 996
         try:
             ov1.getresult()
         except OSError as e:
             self.assertEqual(e.winerror, ERROR_IO_INCOMPLETE)
         else:
             raise RuntimeError('expected ERROR_IO_INCOMPLETE')
         ov2 = _overlapped.Overlapped()
         self.assertFalse(ov2.pending)
         self.assertEqual(ov2.error, 0)
         ov2.WriteFile(h2, b'hello')
         self.assertIn(ov2.error, {0, _winapi.ERROR_IO_PENDING})
         res = _winapi.WaitForMultipleObjects([ov2.event], False, 100)
         self.assertEqual(res, _winapi.WAIT_OBJECT_0)
         self.assertFalse(ov1.pending)
         self.assertEqual(ov1.error, ERROR_IO_INCOMPLETE)
         self.assertFalse(ov2.pending)
         self.assertIn(ov2.error, {0, _winapi.ERROR_IO_PENDING})
         self.assertEqual(ov1.getresult(), b'hello')
     finally:
         _winapi.CloseHandle(h1)
         _winapi.CloseHandle(h2)
Esempio n. 2
0
    def Pipe(duplex=True, rnonblock=False, wnonblock=False):  # noqa
        '''
        Returns pair of connection objects at either end of a pipe
        '''
        address = arbitrary_address('AF_PIPE')
        if duplex:
            openmode = _winapi.PIPE_ACCESS_DUPLEX
            access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE
            obsize, ibsize = BUFSIZE, BUFSIZE
        else:
            openmode = _winapi.PIPE_ACCESS_INBOUND
            access = _winapi.GENERIC_WRITE
            obsize, ibsize = 0, BUFSIZE

        h1 = _winapi.CreateNamedPipe(
            address, openmode | _winapi.FILE_FLAG_OVERLAPPED
            | _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE, _winapi.PIPE_TYPE_MESSAGE
            | _winapi.PIPE_READMODE_MESSAGE | _winapi.PIPE_WAIT, 1, obsize,
            ibsize, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL)
        h2 = _winapi.CreateFile(address, access, 0, _winapi.NULL,
                                _winapi.OPEN_EXISTING,
                                _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL)
        _winapi.SetNamedPipeHandleState(h2, _winapi.PIPE_READMODE_MESSAGE,
                                        None, None)

        overlapped = _winapi.ConnectNamedPipe(h1, overlapped=True)
        _, err = overlapped.GetOverlappedResult(True)
        assert err == 0

        c1 = PipeConnection(duplicate(h1, inheritable=True), writable=duplex)
        c2 = PipeConnection(duplicate(h2, inheritable=True), readable=duplex)
        _winapi.CloseHandle(h1)
        _winapi.CloseHandle(h2)
        return c1, c2
Esempio n. 3
0
 def _get_handles(self, stdin, stdout, stderr):
     if stdin is None and stdout is None and stderr is None:
         return (-1, -1, -1, -1, -1, -1)
     (p2cread, p2cwrite) = (-1, -1)
     (c2pread, c2pwrite) = (-1, -1)
     (errread, errwrite) = (-1, -1)
     if stdin is None:
         p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE)
         (p2cread, _) = _winapi.CreatePipe(None, 0)
         p2cread = Handle(p2cread)
         _winapi.CloseHandle(_)
     elif stdin == PIPE:
         (p2cread, p2cwrite) = _winapi.CreatePipe(None, 0)
         (p2cread, p2cwrite) = (Handle(p2cread), Handle(p2cwrite))
     elif stdin == DEVNULL:
         p2cread = msvcrt.get_osfhandle(self._get_devnull())
     elif isinstance(stdin, int):
         p2cread = msvcrt.get_osfhandle(stdin)
     else:
         p2cread = msvcrt.get_osfhandle(stdin.fileno())
     p2cread = self._make_inheritable(p2cread)
     if stdout is None:
         c2pwrite = _winapi.GetStdHandle(_winapi.STD_OUTPUT_HANDLE)
         (_, c2pwrite) = _winapi.CreatePipe(None, 0)
         c2pwrite = Handle(c2pwrite)
         _winapi.CloseHandle(_)
     elif stdout == PIPE:
         (c2pread, c2pwrite) = _winapi.CreatePipe(None, 0)
         (c2pread, c2pwrite) = (Handle(c2pread), Handle(c2pwrite))
     elif stdout == DEVNULL:
         c2pwrite = msvcrt.get_osfhandle(self._get_devnull())
     elif isinstance(stdout, int):
         c2pwrite = msvcrt.get_osfhandle(stdout)
     else:
         c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
     c2pwrite = self._make_inheritable(c2pwrite)
     if stderr is None:
         errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE)
         (_, errwrite) = _winapi.CreatePipe(None, 0)
         errwrite = Handle(errwrite)
         _winapi.CloseHandle(_)
     elif stderr == PIPE:
         (errread, errwrite) = _winapi.CreatePipe(None, 0)
         (errread, errwrite) = (Handle(errread), Handle(errwrite))
     elif stderr == STDOUT:
         errwrite = c2pwrite
     elif stderr == DEVNULL:
         errwrite = msvcrt.get_osfhandle(self._get_devnull())
     elif isinstance(stderr, int):
         errwrite = msvcrt.get_osfhandle(stderr)
     else:
         errwrite = msvcrt.get_osfhandle(stderr.fileno())
     errwrite = self._make_inheritable(errwrite)
     return (p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite)
Esempio n. 4
0
    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)
Esempio n. 5
0
def cmdl(ctx, components, config, n_environments, exploit, show_ui):
    """Run RELAAX components.

    \b
    COMPONENTS:
    all              - run environments and servers (default)
    environment      - run environment
    servers          - run rlx-server, parameter-server, metrics-server and wsproxy
                       (if specified in config yaml)
    rlx-server       - run rlx-server
    parameter-server - run parameter-server
    metrics-server   - run metrics-server
    wsproxy          - run websockets proxy

    \b
    For example:
        - run environment, rlx-server, parameter-server, metrics-server, and wsproxy
        $relaax run all
        - run rlx-server, parameter-server, metrics-server, and wsproxy
        $relaax run servers
    """
    ctx.setup_logger(format='%(asctime)s %(name)s\t\t  | %(message)s')
    # Disable TF warnings
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
    os.environ["COMSPEC"] = "powershell.exe"
    # Execute command
    if sys.platform == 'win32':
        honcho.manager.KILL_WAIT = 120
        honcho.process.Popen = PopenPatched

        import _winapi
        import ctypes

        firstRun = False
        mutex = ctypes.windll.kernel32.CreateMutexA(None, False,
                                                    "RELAAX_WINDOWS_MUTEX")
        if _winapi.GetLastError() == 0:
            firstRun = True

        if firstRun:
            os.system("start powershell " + ' '.join(sys.argv))
            time.sleep(5)
            _winapi.CloseHandle(mutex)
        else:
            _winapi.CloseHandle(mutex)
            honcho.process.Popen = PopenPatched
            CmdlRun(ctx, set(components), config.name, n_environments, exploit,
                    show_ui).run_components()
    else:
        CmdlRun(ctx, set(components), config.name, n_environments, exploit,
                show_ui).run_components()
Esempio n. 6
0
            def __init__(self, name=None, create=False, size=0):
                if not size >= 0:
                    raise ValueError("'size' must be a positive integer")
                if create:
                    self._flags = _O_CREX | os.O_RDWR
                if name is None and not self._flags & os.O_EXCL:
                    raise ValueError("'name' can only be None if create=True")
                # Windows Named Shared Memory
                if create:
                    while True:
                        temp_name = _make_filename() if name is None else name
                        # Create and reserve shared memory block with this name
                        # until it can be attached to by mmap.
                        h_map = _winapi.CreateFileMapping(
                            _winapi.INVALID_HANDLE_VALUE, _winapi.NULL,
                            _winapi.PAGE_READWRITE, (size >> 32) & 0xFFFFFFFF,
                            size & 0xFFFFFFFF, temp_name)
                        try:
                            last_error_code = _winapi.GetLastError()
                            if last_error_code == _winapi.ERROR_ALREADY_EXISTS:
                                if name is not None:
                                    raise FileExistsError(
                                        errno.EEXIST,
                                        os.strerror(errno.EEXIST), name,
                                        _winapi.ERROR_ALREADY_EXISTS)
                                else:
                                    continue
                            self._mmap = mmap.mmap(-1, size, tagname=temp_name)
                        finally:
                            _winapi.CloseHandle(h_map)
                        self._name = temp_name
                        break

                else:
                    self._name = name
                    # Dynamically determine the existing named shared memory
                    # block's size which is likely a multiple of mmap.PAGESIZE.
                    h_map = _winapi.OpenFileMapping(_winapi.FILE_MAP_READ,
                                                    False, name)
                    try:
                        p_buf = _winapi.MapViewOfFile(h_map,
                                                      _winapi.FILE_MAP_READ, 0,
                                                      0, 0)
                    finally:
                        _winapi.CloseHandle(h_map)
                    size = _winapi.VirtualQuerySize(p_buf)
                    self._mmap = mmap.mmap(-1, size, tagname=name)

                self._size = size
                self._buf = memoryview(self._mmap)
Esempio n. 7
0
 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)
Esempio n. 8
0
 def _poll(self, timeout=None):
     if timeout is None:
         ms = INFINITE
     elif timeout < 0:
         raise ValueError("negative timeout")
     else:
         ms = int(timeout * 1000 + 0.5)
         if ms >= INFINITE:
             raise ValueError("timeout too big")
     while True:
         status = _overlapped.GetQueuedCompletionStatus(self._iocp, ms)
         if status is None:
             return
         err, transferred, key, address = status
         try:
             f, ov, obj, callback = self._cache.pop(address)
         except KeyError:
             # key is either zero, or it is used to return a pipe
             # handle which should be closed to avoid a leak.
             if key not in (0, _overlapped.INVALID_HANDLE_VALUE):
                 _winapi.CloseHandle(key)
             ms = 0
             continue
         if obj in self._stopped_serving:
             f.cancel()
         elif not f.cancelled():
             try:
                 value = callback(transferred, key, ov)
             except OSError as e:
                 f.set_exception(e)
                 self._results.append(f)
             else:
                 f.set_result(value)
                 self._results.append(f)
         ms = 0
Esempio n. 9
0
    def close(self):
        # Cancel remaining registered operations.
        for address, (fut, ov, obj, callback) in list(self._cache.items()):
            if obj is None:
                # The operation was started with connect_pipe() which
                # queues a task to Windows' thread pool.  This cannot
                # be cancelled, so just forget it.
                del self._cache[address]
            # FIXME: Tulip issue 196: remove this case, it should not happen
            elif fut.done() and not fut.cancelled():
                del self._cache[address]
            else:
                try:
                    fut.cancel()
                except OSError as exc:
                    if self._loop is not None:
                        context = {
                            'message': 'Cancelling a future failed',
                            'exception': exc,
                            'future': fut,
                        }
                        if fut._source_traceback:
                            context['source_traceback'] = fut._source_traceback
                        self._loop.call_exception_handler(context)

        while self._cache:
            if not self._poll(1):
                logger.debug('taking long time to close proactor')

        self._results = []
        if self._iocp is not None:
            _winapi.CloseHandle(self._iocp)
            self._iocp = None
 def test_pipe_handle(self):
     h, _ = windows_utils.pipe(overlapped=(True, True))
     _winapi.CloseHandle(_)
     p = windows_utils.PipeHandle(h)
     self.assertEqual(p.fileno(), h)
     self.assertEqual(p.handle, h)
     with warnings.catch_warnings():
         warnings.filterwarnings('ignore', '', ResourceWarning)
         del p
         support.gc_collect()
     try:
         _winapi.CloseHandle(h)
     except OSError as e:
         self.assertEqual(e.winerror, 6)
     else:
         raise RuntimeError('expected ERROR_INVALID_HANDLE')
Esempio n. 11
0
def _pid_alive(pid):
    """Check if the process with this PID is alive or not.

    Args:
        pid: The pid to check.

    Returns:
        This returns false if the process is dead. Otherwise, it returns true.
    """
    no_such_process = errno.EINVAL if sys.platform == "win32" else errno.ESRCH
    alive = True
    try:
        if sys.platform == "win32":
            SYNCHRONIZE = 0x00100000  # access mask defined in <winnt.h>
            handle = _winapi.OpenProcess(SYNCHRONIZE, False, pid)
            try:
                alive = (_winapi.WaitForSingleObject(handle, 0) !=
                         _winapi.WAIT_OBJECT_0)
            finally:
                _winapi.CloseHandle(handle)
        else:
            os.kill(pid, 0)
    except OSError as ex:
        if ex.errno != no_such_process:
            raise
        alive = False
    return alive
Esempio n. 12
0
def spawn_main(pipe_handle, parent_pid=None, tracker_fd=None):
    '''
    Run code specified by data received over pipe
    '''
    assert is_forking(sys.argv), "Not forking"
    if sys.platform == 'win32':
        import msvcrt
        import _winapi

        if parent_pid is not None:
            source_process = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE,
                                                 False, parent_pid)
        else:
            source_process = None
        try:
            new_handle = reduction.duplicate(pipe_handle,
                                             source_process=source_process)
        finally:
            if source_process is not None:
                _winapi.CloseHandle(source_process)
        fd = msvcrt.open_osfhandle(new_handle, os.O_RDONLY)
    else:
        from . import resource_tracker
        resource_tracker._resource_tracker._fd = tracker_fd
        fd = pipe_handle
    exitcode = _main(fd)
    sys.exit(exitcode)
Esempio n. 13
0
    def close(self):
        # Cancel remaining registered operations.
        for address, (fut, ov, obj, callback) in list(self._cache.items()):
            if fut.cancelled():
                # Nothing to do with cancelled futures
                pass
            elif isinstance(fut, _WaitCancelFuture):
                # _WaitCancelFuture must not be cancelled
                pass
            else:
                try:
                    fut.cancel()
                except OSError as exc:
                    if self._loop is not None:
                        context = {
                            'message': 'Cancelling a future failed',
                            'exception': exc,
                            'future': fut,
                        }
                        if fut._source_traceback:
                            context['source_traceback'] = fut._source_traceback
                        self._loop.call_exception_handler(context)

        while self._cache:
            if not self._poll(1):
                logger.debug('taking long time to close proactor')

        self._results = []
        if self._iocp is not None:
            _winapi.CloseHandle(self._iocp)
            self._iocp = None
    def test_pipe_handle(self):
        h, _ = windows_utils.pipe(overlapped=(True, True))
        _winapi.CloseHandle(_)
        p = windows_utils.PipeHandle(h)
        self.assertEqual(p.fileno(), h)
        self.assertEqual(p.handle, h)

        # check garbage collection of p closes handle
        del p
        support.gc_collect()
        try:
            _winapi.CloseHandle(h)
        except OSError as e:
            self.assertEqual(e.winerror, 6)  # ERROR_INVALID_HANDLE
        else:
            raise RuntimeError('expected ERROR_INVALID_HANDLE')
Esempio n. 15
0
 def __enter__(self) -> 'IPCServer':
     if sys.platform == 'win32':
         # NOTE: It is theoretically possible that this will hang forever if the
         # client never connects, though this can be "solved" by killing the server
         try:
             ov = _winapi.ConnectNamedPipe(self.connection, overlapped=True)
             # TODO: remove once typeshed supports Literal types
             assert isinstance(ov, _winapi.Overlapped)
         except OSError as e:
             # Don't raise if the client already exists, or the client already connected
             if e.winerror not in (_winapi.ERROR_PIPE_CONNECTED,
                                   _winapi.ERROR_NO_DATA):
                 raise
         else:
             try:
                 timeout = int(self.timeout *
                               1000) if self.timeout else _winapi.INFINITE
                 res = _winapi.WaitForSingleObject(ov.event, timeout)
                 assert res == _winapi.WAIT_OBJECT_0
             except BaseException:
                 ov.cancel()
                 _winapi.CloseHandle(self.connection)
                 raise
             _, err = ov.GetOverlappedResult(True)
             assert err == 0
     else:
         try:
             self.connection, _ = self.sock.accept()
         except socket.timeout as e:
             raise IPCException('The socket timed out') from e
     return self
Esempio n. 16
0
 async def accept(self):
     self._handle_queue.append(self._new_handle())
     handle = self._handle_queue.pop(0)
     try:
         ov = _winapi.ConnectNamedPipe(handle, overlapped=True)
     except OSError as e:
         if e.winerror != _winapi.ERROR_NO_DATA:
             raise
         # ERROR_NO_DATA can occur if a client has already connected,
         # written data and then disconnected -- see Issue 14725.
     else:
         try:
             # res = _winapi.WaitForMultipleObjects(
             #     [ov.event], False, INFINITE)
             await _wait_for_ov(ov)
         except:
             ov.cancel()
             _winapi.CloseHandle(handle)
             raise
         finally:
             _, err = ov.GetOverlappedResult(True)
             assert err == 0
     if self._wrap_ssl:
         return AsyncSslPipeConnection(handle, server_side=True)
     else:
         return AsyncPipeConnection(handle, server_side=True)
Esempio n. 17
0
 def __init__(self, args, stdin=None, stdout=None, stderr=None, **kwds):
     stdin_rfd = stdout_wfd = stderr_wfd = None
     stdin_wh = stdout_rh = stderr_rh = None
     if stdin == PIPE:
         stdin_rh, stdin_wh = pipe(overlapped=(False, True))
         stdin_rfd = msvcrt.open_osfhandle(stdin_rh, os.O_RDONLY)
     if stdout == PIPE:
         stdout_rh, stdout_wh = pipe(overlapped=(True, False))
         stdout_wfd = msvcrt.open_osfhandle(stdout_wh, 0)
     if stderr == PIPE:
         stderr_rh, stderr_wh = pipe(overlapped=(True, False))
         stderr_wfd = msvcrt.open_osfhandle(stderr_wh, 0)
     try:
         super().__init__(args, bufsize=0, universal_newlines=False,
                          stdin=stdin_rfd, stdout=stdout_wfd,
                          stderr=stderr_wfd, **kwds)
     except:
         for h in (stdin_wh, stdout_rh, stderr_rh):
             _winapi.CloseHandle(h)
         raise
     else:
         if stdin_wh is not None:
             self.stdin = PipeHandle(stdin_wh)
         if stdout_rh is not None:
             self.stdout = PipeHandle(stdout_rh)
         if stderr_rh is not None:
             self.stderr = PipeHandle(stderr_rh)
     finally:
         if stdin == PIPE:
             os.close(stdin_rfd)
         if stdout == PIPE:
             os.close(stdout_wfd)
         if stderr == PIPE:
             os.close(stderr_wfd)
Esempio n. 18
0
        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
Esempio n. 19
0
 def kill(self):
     if sys.platform == 'win32':
         import _winapi
         handle = _winapi.OpenProcess(1, False, self._process.pid)
         _winapi.TerminateProcess(handle, -1)
         _winapi.CloseHandle(handle)
     else:
         os.kill(self.process.pid, signal.SIGKILL)
Esempio n. 20
0
 def _unregister_wait_cb(self, fut):
     if self._event is not None:
         _winapi.CloseHandle(self._event)
         self._event = None
         self._event_fut = None
     self._proactor._unregister(self._ov)
     self._proactor = None
     super()._unregister_wait_cb(fut)
Esempio n. 21
0
def pipe(*, duplex=False, overlapped=(True, True), bufsize=BUFSIZE):
    """Like os.pipe() but with overlapped support and using handles not fds."""
    address = tempfile.mktemp(prefix=r'\\.\pipe\python-pipe-{:d}-{:d}-'.format(
        os.getpid(), next(_mmap_counter)))

    if duplex:
        openmode = _winapi.PIPE_ACCESS_DUPLEX
        access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE
        obsize, ibsize = bufsize, bufsize
    else:
        openmode = _winapi.PIPE_ACCESS_INBOUND
        access = _winapi.GENERIC_WRITE
        obsize, ibsize = 0, bufsize

    openmode |= _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE

    if overlapped[0]:
        openmode |= _winapi.FILE_FLAG_OVERLAPPED

    if overlapped[1]:
        flags_and_attribs = _winapi.FILE_FLAG_OVERLAPPED
    else:
        flags_and_attribs = 0

    h1 = h2 = None
    try:
        h1 = _winapi.CreateNamedPipe(address, openmode, _winapi.PIPE_WAIT, 1,
                                     obsize, ibsize,
                                     _winapi.NMPWAIT_WAIT_FOREVER,
                                     _winapi.NULL)

        h2 = _winapi.CreateFile(address, access, 0, _winapi.NULL,
                                _winapi.OPEN_EXISTING, flags_and_attribs,
                                _winapi.NULL)

        ov = _winapi.ConnectNamedPipe(h1, overlapped=True)
        ov.GetOverlappedResult(True)
        return h1, h2
    except:
        if h1 is not None:
            _winapi.CloseHandle(h1)
        if h2 is not None:
            _winapi.CloseHandle(h2)
        raise
Esempio n. 22
0
        def _poll(self, timeout=None):
            if timeout is None:
                ms = INFINITE
            elif timeout < 0:
                raise ValueError("negative timeout")
            else:
                # GetQueuedCompletionStatus() has a resolution of 1 millisecond,
                # round away from zero to wait *at least* timeout seconds.
                ms = math.ceil(timeout * 1e3)
                if ms >= INFINITE:
                    raise ValueError("timeout too big")

            while True:
                status = _overlapped.GetQueuedCompletionStatus(self._iocp, ms)
                if status is None:
                    break
                ms = 0

                err, transferred, key, address = status
                try:
                    f, ov, obj, callback = self._cache.pop(address)
                except KeyError:
                    if self._loop.get_debug():
                        self._loop.call_exception_handler({
                            'message':
                            ('GetQueuedCompletionStatus() returned an '
                             'unexpected event'),
                            'status':
                            ('err=%s transferred=%s key=%#x address=%#x' %
                             (err, transferred, key, address)),
                        })

                    # key is either zero, or it is used to return a pipe
                    # handle which should be closed to avoid a leak.
                    if key not in (0, _overlapped.INVALID_HANDLE_VALUE):
                        _winapi.CloseHandle(key)
                    continue

                if obj in self._stopped_serving:
                    f.cancel()
                # Don't call the callback if _register() already read the result or
                # if the overlapped has been cancelled
                elif not f.done():
                    try:
                        value = callback(transferred, key, ov)
                    except OSError as e:
                        f.set_exception(e)
                        self._results.append(f)
                    else:
                        f.set_result(value)
                        self._results.append(f)

            # Remove unregisted futures
            for ov in self._unregistered:
                self._cache.pop(ov.address, None)
            self._unregistered.clear()
Esempio n. 23
0
 def steal_handle(source_pid, handle):
     """Steal a handle from process identified by source_pid."""
     source_process_handle = _winapi.OpenProcess(_winapi.
         PROCESS_DUP_HANDLE, False, source_pid)
     try:
         return _winapi.DuplicateHandle(source_process_handle, handle,
             _winapi.GetCurrentProcess(), 0, False, _winapi.
             DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE)
     finally:
         _winapi.CloseHandle(source_process_handle)
Esempio n. 24
0
 def __init__(self, handle, access, pid=None):
     if pid is None:
         pid = os.getpid()
     proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, pid)
     try:
         self._handle = _winapi.DuplicateHandle(_winapi.
             GetCurrentProcess(), handle, proc, access, False, 0)
     finally:
         _winapi.CloseHandle(proc)
     self._access = access
     self._pid = pid
Esempio n. 25
0
    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)
Esempio n. 26
0
 def detach(self):
     """Get the handle.  This should only be called once."""
     if self._pid == os.getpid():
         return self._handle
     proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False,
         self._pid)
     try:
         return _winapi.DuplicateHandle(proc, self._handle, _winapi.
             GetCurrentProcess(), self._access, False, _winapi.
             DUPLICATE_CLOSE_SOURCE)
     finally:
         _winapi.CloseHandle(proc)
Esempio n. 27
0
 def detach(self):
     # retrieve handle from process which currently owns it
     if self._pid == os.getpid():
         return self._handle
     proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False,
                                self._pid)
     try:
         return _winapi.DuplicateHandle(
             proc, self._handle, _winapi.GetCurrentProcess(),
             self._access, False, _winapi.DUPLICATE_CLOSE_SOURCE)
     finally:
         _winapi.CloseHandle(proc)
Esempio n. 28
0
 def __init__(self, handle, access, pid=None):
     if pid is None:
         # We just duplicate the handle in the current process and
         # let the receiving process steal the handle.
         pid = os.getpid()
     proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False, pid)
     try:
         self._handle = _winapi.DuplicateHandle(
             _winapi.GetCurrentProcess(), handle, proc, access, False,
             0)
     finally:
         _winapi.CloseHandle(proc)
     self._access = access
     self._pid = pid
Esempio n. 29
0
 def detach(self):
     '''Get the handle.  This should only be called once.'''
     # retrieve handle from process which currently owns it
     if self._pid == os.getpid():
         # The handle has already been duplicated for this process.
         return self._handle
     # We must steal the handle from the process whose pid is self._pid.
     proc = _winapi.OpenProcess(_winapi.PROCESS_DUP_HANDLE, False,
                                self._pid)
     try:
         return _winapi.DuplicateHandle(
             proc, self._handle, _winapi.GetCurrentProcess(),
             self._access, False, _winapi.DUPLICATE_CLOSE_SOURCE)
     finally:
         _winapi.CloseHandle(proc)
Esempio n. 30
0
    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)