Beispiel #1
0
    def PipeClient(address):
        '''
        Return a connection object connected to the pipe given by `address`
        '''
        t = _init_timeout()
        while 1:
            try:
                _winapi.WaitNamedPipe(address, 1000)
                h = _winapi.CreateFile(
                    address, _winapi.GENERIC_READ | _winapi.GENERIC_WRITE, 0,
                    _winapi.NULL, _winapi.OPEN_EXISTING,
                    _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL)
            except OSError as e:
                if e.winerror not in (
                        _winapi.ERROR_SEM_TIMEOUT,
                        _winapi.ERROR_PIPE_BUSY) or _check_timeout(t):
                    raise
            else:
                break
        else:
            raise

        _winapi.SetNamedPipeHandleState(h, _winapi.PIPE_READMODE_MESSAGE, None,
                                        None)
        return PipeConnection(h)
Beispiel #2
0
    def __init__(self, ipc_socket, callback=None, quit_callback=None):
        """Create the wrapper.

        *ipc_socket* is the pipe name. (Not including \\\\.\\pipe\\)
        *callback(json_data)* is the function for recieving events.
        *quit_callback* is called when the socket connection dies.
        """
        ipc_socket = "\\\\.\\pipe\\" + ipc_socket
        self.callback = callback
        self.quit_callback = quit_callback

        access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE
        limit = 5  # Connection may fail at first. Try 5 times.
        for _ in range(limit):
            try:
                pipe_handle = _winapi.CreateFile(ipc_socket, access, 0,
                                                 _winapi.NULL,
                                                 _winapi.OPEN_EXISTING,
                                                 _winapi.FILE_FLAG_OVERLAPPED,
                                                 _winapi.NULL)
                break
            except OSError:
                time.sleep(1)
        else:
            raise MPVError("Cannot connect to pipe.")
        self.socket = PipeConnection(pipe_handle)

        if self.callback is None:
            self.callback = lambda data: None

        threading.Thread.__init__(self)
Beispiel #3
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
    def start(self):
        # Create a named pipe which allows for asynchronous IO in Windows
        pipe_name =  r'\\.\pipe\typeperf_output_' + str(uuid.uuid4())

        open_mode =  _winapi.PIPE_ACCESS_INBOUND
        open_mode |= _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE
        open_mode |= _winapi.FILE_FLAG_OVERLAPPED

        # This is the read end of the pipe, where we will be grabbing output
        self.pipe = _winapi.CreateNamedPipe(
            pipe_name, open_mode, _winapi.PIPE_WAIT,
            1, BUFSIZE, BUFSIZE, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL
        )
        # The write end of the pipe which is passed to the created process
        pipe_write_end = _winapi.CreateFile(
            pipe_name, _winapi.GENERIC_WRITE, 0, _winapi.NULL,
            _winapi.OPEN_EXISTING, 0, _winapi.NULL
        )
        # Open up the handle as a python file object so we can pass it to
        # subprocess
        command_stdout = msvcrt.open_osfhandle(pipe_write_end, 0)

        # Connect to the read end of the pipe in overlap/async mode
        overlap = _winapi.ConnectNamedPipe(self.pipe, overlapped=True)
        overlap.GetOverlappedResult(True)

        # Spawn off the load monitor
        counter_name = self._get_counter_name()
        command = ['typeperf', counter_name, '-si', str(SAMPLING_INTERVAL)]
        self.popen = subprocess.Popen(' '.join(command), stdout=command_stdout, cwd=support.SAVEDCWD)

        # Close our copy of the write end of the pipe
        os.close(command_stdout)
    async def connect(self):
        '''
        Return a connection object connected to the pipe given by `address`
        '''
        if self._conn is None:
            delay = CONNECT_PIPE_INIT_DELAY
            while True:
                # Unfortunately there is no way to do an overlapped connect to
                # a pipe.  Call CreateFile() in a loop until it doesn't fail with
                # ERROR_PIPE_BUSY.
                try:
                    h = _winapi.CreateFile(
                        self._address,
                        _winapi.GENERIC_READ | _winapi.GENERIC_WRITE, 0,
                        _winapi.NULL, _winapi.OPEN_EXISTING,
                        _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL)
                    break
                except OSError as e:
                    if e.winerror not in (_winapi.ERROR_SEM_TIMEOUT,
                                          _winapi.ERROR_PIPE_BUSY):
                        raise

                # ConnectPipe() failed with ERROR_PIPE_BUSY: retry later
                delay = min(delay * 2, CONNECT_PIPE_MAX_DELAY)
                await asyncio.sleep(delay)
            _winapi.SetNamedPipeHandleState(h, _winapi.PIPE_READMODE_MESSAGE,
                                            None, None)
            if self._wrap_ssl:
                self._conn = AsyncSslPipeConnection(h)
            else:
                self._conn = AsyncPipeConnection(h)
        return self._conn
Beispiel #6
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
Beispiel #7
0
    def Pipe(duplex=True):
        '''
        返回管道两端的一对连接对象
        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,
            # default security descriptor: the handle cannot be inherited
            _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(h1, writable=duplex)
        c2 = PipeConnection(h2, readable=duplex)

        return c1, c2
Beispiel #8
0
 def __init__(self, name: str, timeout: Optional[float]) -> None:
     super().__init__(name, timeout)
     if sys.platform == 'win32':
         timeout = int(
             self.timeout *
             1000) if self.timeout else _winapi.NMPWAIT_WAIT_FOREVER
         try:
             _winapi.WaitNamedPipe(self.name, timeout)
         except FileNotFoundError as e:
             raise IPCException(
                 f"The NamedPipe at {self.name} was not found.") from e
         except OSError as e:
             if e.winerror == _winapi.ERROR_SEM_TIMEOUT:
                 raise IPCException(
                     "Timed out waiting for connection.") from e
             else:
                 raise
         try:
             self.connection = _winapi.CreateFile(
                 self.name,
                 _winapi.GENERIC_READ | _winapi.GENERIC_WRITE,
                 0,
                 _winapi.NULL,
                 _winapi.OPEN_EXISTING,
                 _winapi.FILE_FLAG_OVERLAPPED,
                 _winapi.NULL,
             )
         except OSError as e:
             if e.winerror == _winapi.ERROR_PIPE_BUSY:
                 raise IPCException("The connection is busy.") from e
             else:
                 raise
         _winapi.SetNamedPipeHandleState(self.connection,
                                         _winapi.PIPE_READMODE_MESSAGE,
                                         None, None)
     else:
         self.connection = socket.socket(socket.AF_UNIX)
         self.connection.settimeout(timeout)
         self.connection.connect(name)
Beispiel #9
0
 def __init__(self, name: str, timeout: Optional[int]) -> None:
     super().__init__(name)
     if sys.platform == 'win32':
         timeout = timeout or 0xFFFFFFFF  # NMPWAIT_WAIT_FOREVER
         try:
             _winapi.WaitNamedPipe(self.name, timeout)
         except FileNotFoundError:
             raise IPCException("The NamedPipe at {} was not found.".format(self.name))
         except WindowsError as e:
             if e.winerror == _winapi.ERROR_SEM_TIMEOUT:
                 raise IPCException("Timed out waiting for connection.")
             else:
                 raise
         try:
             self.connection = _winapi.CreateFile(
                 self.name,
                 _winapi.GENERIC_READ | _winapi.GENERIC_WRITE,
                 0,
                 _winapi.NULL,
                 _winapi.OPEN_EXISTING,
                 0,
                 _winapi.NULL,
             )
         except WindowsError as e:
             if e.winerror == _winapi.ERROR_PIPE_BUSY:
                 raise IPCException("The connection is busy.")
             else:
                 raise
         _winapi.SetNamedPipeHandleState(self.connection,
                                         _winapi.PIPE_READMODE_MESSAGE,
                                         None,
                                         None)
     else:
         self.connection = socket.socket(socket.AF_UNIX)
         self.connection.settimeout(timeout)
         self.connection.connect(name)
 def initializeConnection():
     return winAPI.CreateFile("\\\\.\\pipe\\Demo",
                              winAPI.GENERIC_READ | winAPI.GENERIC_WRITE, 0,
                              0, winAPI.OPEN_EXISTING, 0, 0)