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)
Example #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 test_popen(self):
     command = """if 1:
         import sys
         s = sys.stdin.readline()
         sys.stdout.write(s.upper())
         sys.stderr.write('stderr')
         """
     msg = b'blah\n'
     p = windows_utils.Popen([sys.executable, '-c', command],
                             stdin=windows_utils.PIPE,
                             stdout=windows_utils.PIPE,
                             stderr=windows_utils.PIPE)
     for f in [p.stdin, p.stdout, p.stderr]:
         self.assertIsInstance(f, windows_utils.PipeHandle)
     ovin = _overlapped.Overlapped()
     ovout = _overlapped.Overlapped()
     overr = _overlapped.Overlapped()
     ovin.WriteFile(p.stdin.handle, msg)
     ovout.ReadFile(p.stdout.handle, 100)
     overr.ReadFile(p.stderr.handle, 100)
     events = [ovin.event, ovout.event, overr.event]
     res = _winapi.WaitForMultipleObjects(events, True, 10000)
     self.assertEqual(res, _winapi.WAIT_OBJECT_0)
     self.assertFalse(ovout.pending)
     self.assertFalse(overr.pending)
     self.assertFalse(ovin.pending)
     self.assertEqual(ovin.getresult(), len(msg))
     out = ovout.getresult().rstrip()
     err = overr.getresult().rstrip()
     self.assertGreater(len(out), 0)
     self.assertGreater(len(err), 0)
     self.assertTrue(msg.upper().rstrip().startswith(out))
     self.assertTrue(b'stderr'.startswith(err))
     with p:
         pass
Example #4
0
 def _send_bytes(self, buf):
     ov, err = _winapi.WriteFile(self._handle, buf, 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:
         nwritten, err = ov.GetOverlappedResult(True)
     assert err == 0
     assert nwritten == len(buf)
Example #5
0
    def test_popen(self):
        command = r"""if 1:
            import sys
            s = sys.stdin.readline()
            sys.stdout.write(s.upper())
            sys.stderr.write('stderr')
            """
        msg = b"blah\n"

        p = windows_utils.Popen(
            [sys.executable, '-c', command],
            stdin=windows_utils.PIPE,
            stdout=windows_utils.PIPE,
            stderr=windows_utils.PIPE
        )

        for f in [p.stdin, p.stdout, p.stderr]:
            self.assertIsInstance(f, windows_utils.PipeHandle)

        ovin = _overlapped.Overlapped()
        ovout = _overlapped.Overlapped()
        overr = _overlapped.Overlapped()

        ovin.WriteFile(p.stdin.handle, msg)
        ovout.ReadFile(p.stdout.handle, 100)
        overr.ReadFile(p.stderr.handle, 100)

        events = [ovin.event, ovout.event, overr.event]
        # Super-long timeout for slow buildbots.
        res = _winapi.WaitForMultipleObjects(events, True, 10000)
        self.assertEqual(res, _winapi.WAIT_OBJECT_0)
        self.assertFalse(ovout.pending)
        self.assertFalse(overr.pending)
        self.assertFalse(ovin.pending)

        self.assertEqual(ovin.getresult(), len(msg))
        out = ovout.getresult().rstrip()
        err = overr.getresult().rstrip()

        self.assertGreater(len(out), 0)
        self.assertGreater(len(err), 0)
        # allow for partial reads...
        self.assertTrue(msg.upper().rstrip().startswith(out))
        self.assertTrue(b"stderr".startswith(err))

        # The context manager calls wait() and closes resources
        with p:
            pass
Example #6
0
 def _exhaustive_wait(handles, timeout):
     L = list(handles)
     ready = []
     while L:
         res = _winapi.WaitForMultipleObjects(L, False, timeout)
         if res == WAIT_TIMEOUT:
             break
         elif WAIT_OBJECT_0 <= res < WAIT_OBJECT_0 + len(L):
             res -= WAIT_OBJECT_0
         elif WAIT_ABANDONED_0 <= res < WAIT_ABANDONED_0 + len(L):
             res -= WAIT_ABANDONED_0
         else:
             raise RuntimeError('Should not get here')
         ready.append(L[res])
         L = L[res + 1:]
         timeout = 0
     return ready
Example #7
0
 def _exhaustive_wait(handles, timeout):
     # Return ALL handles which are currently signalled.  (Only
     # returning the first signalled might create starvation issues.)
     L = list(handles)
     ready = []
     while L:
         res = _winapi.WaitForMultipleObjects(L, False, timeout)
         if res == WAIT_TIMEOUT:
             break
         elif WAIT_OBJECT_0 <= res < WAIT_OBJECT_0 + len(L):
             res -= WAIT_OBJECT_0
         elif WAIT_ABANDONED_0 <= res < WAIT_ABANDONED_0 + len(L):
             res -= WAIT_ABANDONED_0
         else:
             raise RuntimeError('Should not get here')
         ready.append(L[res])
         L = L[res + 1:]
         timeout = 0
     return ready
Example #8
0
 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
     else:
         try:
             res = _winapi.WaitForMultipleObjects([ov.event], False,
                                                  INFINITE)
         except:
             ov.cancel()
             _winapi.CloseHandle(handle)
             raise
         finally:
             _, err = ov.GetOverlappedResult(True)
             assert err == 0
     return PipeConnection(handle)
Example #9
0
 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:
             _winapi.WaitForMultipleObjects([ov.event], False, INFINITE)
         except:
             ov.cancel()
             _winapi.CloseHandle(handle)
             raise
         finally:
             _, err = ov.GetOverlappedResult(True)
             assert err == 0
     return PipeConnection(handle)
Example #10
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