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
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')
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()
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')
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)
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
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
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)
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]
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
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)