Ejemplo n.º 1
0
    def _read_lines(self):
        overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True)
        # PyPy: changed to wait=True since otherwise the buffer is not yet ready
        bytes_read, res = overlapped.GetOverlappedResult(True)
        if res != 0:
            return ()

        output = overlapped.getbuffer()
        output = output.decode('oem', 'replace')
        output = self._buffer + output
        lines = output.splitlines(True)

        # bpo-36670: typeperf only writes a newline *before* writing a value,
        # not after. Sometimes, the written line in incomplete (ex: only
        # timestamp, without the process queue length). Only pass the last line
        # to the parser if it's a valid value, otherwise store it in
        # self._buffer.
        try:
            self._parse_line(lines[-1])
        except ValueError:
            self._buffer = lines.pop(-1)
        else:
            self._buffer = ''

        return lines
Ejemplo n.º 2
0
 def _recv_bytes(self, maxsize=None):
     if self._got_empty_message:
         self._got_empty_message = False
         return io.BytesIO()
     else:
         bsize = 128 if maxsize is None else min(maxsize, 128)
         try:
             ov, err = _winapi.ReadFile(self._handle,
                                        bsize,
                                        overlapped=True)
             try:
                 if err == _winapi.ERROR_IO_PENDING:
                     waitres = _winapi.WaitForMultipleObjects(
                         [ov.event], False, INFINITE)
                     assert waitres == WAIT_OBJECT_0
             except:
                 ov.cancel()
                 raise
             finally:
                 nread, err = ov.GetOverlappedResult(True)
                 if err == 0:
                     f = io.BytesIO()
                     f.write(ov.getbuffer())
                     return f
                 elif err == _winapi.ERROR_MORE_DATA:
                     return self._get_more_data(ov, maxsize)
         except OSError as e:
             if e.winerror == _winapi.ERROR_BROKEN_PIPE:
                 raise EOFError
             else:
                 raise
     raise RuntimeError(
         "shouldn't get here; expected KeyboardInterrupt")
    def read_output(self):
        overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True)
        bytes_read, res = overlapped.GetOverlappedResult(False)
        if res != 0:
            return

        output = overlapped.getbuffer()
        return output.decode('oem', 'replace')
Ejemplo n.º 4
0
    def read_output(self):
        import _winapi

        overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True)
        bytes_read, res = overlapped.GetOverlappedResult(False)
        if res != 0:
            return

        return overlapped.getbuffer().decode()
Ejemplo n.º 5
0
    def read_output(self):
        overlapped, _ = _winapi.ReadFile(self.pipe, BUFSIZE, True)
        bytes_read, res = overlapped.GetOverlappedResult(False)
        if res != 0:
            return

        # self._buffer stores an incomplete line
        output = self._buffer + overlapped.getbuffer()
        output, _, self._buffer = output.rpartition(b'\n')
        return output.decode('oem', 'replace')
Ejemplo n.º 6
0
 def read(self) -> bytes:
     """Read bytes from an IPC connection until its empty."""
     bdata = bytearray()
     while True:
         if sys.platform == 'win32':
             more, _ = _winapi.ReadFile(self.connection, self.READ_SIZE)
         else:
             more = self.connection.recv(self.READ_SIZE)
         if not more:
             break
         bdata.extend(more)
     return bytes(bdata)
Ejemplo n.º 7
0
 def _get_more_data(self, ov, maxsize):
     buf = ov.getbuffer()
     f = io.BytesIO()
     f.write(buf)
     left = _winapi.PeekNamedPipe(self._handle)[1]
     assert left > 0
     if maxsize is not None and len(buf) + left > maxsize:
         self._bad_message_length()
     ov, err = _winapi.ReadFile(self._handle, left, overlapped=True)
     rbytes, err = ov.GetOverlappedResult(True)
     assert err == 0
     assert rbytes == left
     f.write(ov.getbuffer())
     return f
Ejemplo n.º 8
0
 async def _poll(self):
     if (self._got_empty_message
             or _winapi.PeekNamedPipe(self._handle)[0] != 0):
         return True
     ov = None
     try:
         try:
             ov, err = _winapi.ReadFile(self._handle, 0, True)
         except OSError as e:
             ov, err = None, e.winerror
             if err not in _ready_errors:
                 raise
         if err == _winapi.ERROR_IO_PENDING:
             # ov_list.append(ov)
             # waithandle_to_obj[ov.event] = o
             await _wait_for_ov(ov)
         else:
             # If o.fileno() is an overlapped pipe handle and
             # err == 0 then there is a zero length message
             # in the pipe, but it HAS NOT been consumed...
             if ov and sys.getwindowsversion()[:2] >= (6, 2):
                 # ... except on Windows 8 and later, where
                 # the message HAS been consumed.
                 try:
                     _, err = ov.GetOverlappedResult(False)
                 except OSError as e:
                     err = e.winerror
                 if not err:
                     self._got_empty_message = True
     finally:
         if ov is not None:
             ov.cancel()
             try:
                 _, err = ov.GetOverlappedResult(True)
             except OSError as e:
                 err = e.winerror
                 if err not in _ready_errors:
                     raise
             if err != _winapi.ERROR_OPERATION_ABORTED:
                 # o = waithandle_to_obj[ov.event]
                 # ready_objects.add(o)
                 if err == 0:
                     # If o.fileno() is an overlapped pipe handle then
                     # a zero length message HAS been consumed.
                     self._got_empty_message = True
     return True
Ejemplo n.º 9
0
 def read(self, size: int = 100000) -> bytes:
     """Read bytes from an IPC connection until its empty."""
     bdata = bytearray()
     if sys.platform == 'win32':
         while True:
             ov, err = _winapi.ReadFile(self.connection,
                                        size,
                                        overlapped=True)
             # TODO: remove once typeshed supports Literal types
             assert isinstance(ov, _winapi.Overlapped)
             assert isinstance(err, int)
             try:
                 if err == _winapi.ERROR_IO_PENDING:
                     timeout = int(
                         self.timeout *
                         1000) if self.timeout else _winapi.INFINITE
                     res = _winapi.WaitForSingleObject(ov.event, timeout)
                     if res != _winapi.WAIT_OBJECT_0:
                         raise IPCException(
                             "Bad result from I/O wait: {}".format(res))
             except BaseException:
                 ov.cancel()
                 raise
             _, err = ov.GetOverlappedResult(True)
             more = ov.getbuffer()
             if more:
                 bdata.extend(more)
             if err == 0:
                 # we are done!
                 break
             elif err == _winapi.ERROR_MORE_DATA:
                 # read again
                 continue
             elif err == _winapi.ERROR_OPERATION_ABORTED:
                 raise IPCException("ReadFile operation aborted.")
     else:
         while True:
             more = self.connection.recv(size)
             if not more:
                 break
             bdata.extend(more)
     return bytes(bdata)
Ejemplo n.º 10
0
    def wait(object_list, timeout=None):
        '''
        Wait till an object in object_list is ready/readable.

        Returns list of those objects in object_list which are ready/readable.
        '''
        if timeout is None:
            timeout = INFINITE
        elif timeout < 0:
            timeout = 0
        else:
            timeout = int(timeout * 1000 + 0.5)

        object_list = list(object_list)
        waithandle_to_obj = {}
        ov_list = []
        ready_objects = set()
        ready_handles = set()

        try:
            for o in object_list:
                try:
                    fileno = getattr(o, 'fileno')
                except AttributeError:
                    waithandle_to_obj[o.__index__()] = o
                else:
                    # start an overlapped read of length zero
                    try:
                        ov, err = _winapi.ReadFile(fileno(), 0, True)
                    except OSError as e:
                        ov, err = None, e.winerror
                        if err not in _ready_errors:
                            raise
                    if err == _winapi.ERROR_IO_PENDING:
                        ov_list.append(ov)
                        waithandle_to_obj[ov.event] = o
                    else:
                        # If o.fileno() is an overlapped pipe handle and
                        # err == 0 then there is a zero length message
                        # in the pipe, but it HAS NOT been consumed...
                        if ov and sys.getwindowsversion()[:2] >= (6, 2):
                            # ... except on Windows 8 and later, where
                            # the message HAS been consumed.
                            try:
                                _, err = ov.GetOverlappedResult(False)
                            except OSError as e:
                                err = e.winerror
                            if not err and hasattr(o, '_got_empty_message'):
                                o._got_empty_message = True
                        ready_objects.add(o)
                        timeout = 0

            ready_handles = _exhaustive_wait(waithandle_to_obj.keys(), timeout)
        finally:
            # request that overlapped reads stop
            for ov in ov_list:
                ov.cancel()

            # wait for all overlapped reads to stop
            for ov in ov_list:
                try:
                    _, err = ov.GetOverlappedResult(True)
                except OSError as e:
                    err = e.winerror
                    if err not in _ready_errors:
                        raise
                if err != _winapi.ERROR_OPERATION_ABORTED:
                    o = waithandle_to_obj[ov.event]
                    ready_objects.add(o)
                    if err == 0:
                        # If o.fileno() is an overlapped pipe handle then
                        # a zero length message HAS been consumed.
                        if hasattr(o, '_got_empty_message'):
                            o._got_empty_message = True

        ready_objects.update(waithandle_to_obj[h] for h in ready_handles)
        return [o for o in object_list if o in ready_objects]
Ejemplo n.º 11
0
    def dispatch(self):
        rc = None
        draining = False
        while rc is None or draining:
            if rc is None:
                rc = self.proc.poll()

            all_fileobj = []
            if self.stdout is not None:
                all_fileobj.append(self.stdout)
            if self.stderr is not None:
                all_fileobj.append(self.stderr)

            if rc is None and self.io_handlers._hasInput(
            ) and self.stdin is not None:
                all_fileobj.append(self.stdio)

            draining = False
            while rc is None or draining:
                all_handles = [
                    msvcrt.get_osfhandle(fileobj.fileno())
                    for fileobj in all_fileobj
                ]
                result = _winapi.WaitForMultipleObjects(all_handles, 0, 10)
                print('result %r' % (result, ))
                if result == _winapi.WAIT_TIMEOUT:
                    break

                handle = all_handles[result]
                fileobj = all_fileobj[result]

                if fileobj == self.stdout:
                    try:
                        text, err = _winapi.ReadFile(handle, 128, 0)

                        if len(text) > 0:
                            draining = True
                            self.io_handlers._handleStdOut(
                                text.decode(sys.getdefaultencoding()))

                    except BrokenPipeError:
                        self.stdout = None

                elif fileobj == self.stderr:
                    try:
                        text, err = _winapi.ReadFile(handle, 1024, 0)
                        assert err == 0
                        if len(text) > 0:
                            draining = True
                            self.io_handlers._handleStdErr(
                                text.decode(sys.getdefaultencoding()))

                    except BrokenPipeError:
                        self.stderr = None

                elif fileobj == self.stdin:
                    written, err = _winapi.WriteFile(
                        handle,
                        self.io_handlers._getInput().encode(
                            sys.getdefaultencoding()), False)

            self.io_handlers._dispatch()

        return rc
Ejemplo n.º 12
0
    def wait(object_list, timeout=None):
        """
        Wait till an object in object_list is ready/readable.

        Returns list of those objects in object_list which are ready/readable.
        """
        if timeout is None:
            timeout = INFINITE
        elif timeout < 0:
            timeout = 0
        else:
            timeout = int(timeout * 1000 + 0.5)
        object_list = list(object_list)
        waithandle_to_obj = {}
        ov_list = []
        ready_objects = set()
        ready_handles = set()
        try:
            for o in object_list:
                try:
                    fileno = getattr(o, 'fileno')
                except AttributeError:
                    waithandle_to_obj[o.__index__()] = o
                else:
                    try:
                        ov, err = _winapi.ReadFile(fileno(), 0, True)
                    except OSError as e:
                        ov, err = None, e.winerror
                        if err not in _ready_errors:
                            raise
                    if err == _winapi.ERROR_IO_PENDING:
                        ov_list.append(ov)
                        waithandle_to_obj[ov.event] = o
                    else:
                        if ov and sys.getwindowsversion()[:2] >= (6, 2):
                            try:
                                _, err = ov.GetOverlappedResult(False)
                            except OSError as e:
                                err = e.winerror
                            if not err and hasattr(o, '_got_empty_message'):
                                o._got_empty_message = True
                        ready_objects.add(o)
                        timeout = 0
            ready_handles = _exhaustive_wait(waithandle_to_obj.keys(), timeout)
        finally:
            for ov in ov_list:
                ov.cancel()
            for ov in ov_list:
                try:
                    _, err = ov.GetOverlappedResult(True)
                except OSError as e:
                    err = e.winerror
                    if err not in _ready_errors:
                        raise
                if err != _winapi.ERROR_OPERATION_ABORTED:
                    o = waithandle_to_obj[ov.event]
                    ready_objects.add(o)
                    if err == 0:
                        if hasattr(o, '_got_empty_message'):
                            o._got_empty_message = True
        ready_objects.update(waithandle_to_obj[h] for h in ready_handles)
        return [o for o in object_list if o in ready_objects]
 def readMessage(fileHandle):
     return winAPI.ReadFile(fileHandle, 4096)