diff options
Diffstat (limited to 'Lib/asyncio/windows_utils.py')
-rw-r--r-- | Lib/asyncio/windows_utils.py | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/Lib/asyncio/windows_utils.py b/Lib/asyncio/windows_utils.py deleted file mode 100644 index ef277fa..0000000 --- a/Lib/asyncio/windows_utils.py +++ /dev/null @@ -1,173 +0,0 @@ -"""Various Windows specific bits and pieces.""" - -import sys - -if sys.platform != 'win32': # pragma: no cover - raise ImportError('win32 only') - -import _winapi -import itertools -import msvcrt -import os -import subprocess -import tempfile -import warnings - - -__all__ = 'pipe', 'Popen', 'PIPE', 'PipeHandle' - - -# Constants/globals - - -BUFSIZE = 8192 -PIPE = subprocess.PIPE -STDOUT = subprocess.STDOUT -_mmap_counter = itertools.count() - - -# Replacement for os.pipe() using handles instead of fds - - -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 - - -# Wrapper for a pipe handle - - -class PipeHandle: - """Wrapper for an overlapped pipe handle which is vaguely file-object like. - - The IOCP event loop can use these instead of socket objects. - """ - def __init__(self, handle): - self._handle = handle - - def __repr__(self): - if self._handle is not None: - handle = f'handle={self._handle!r}' - else: - handle = 'closed' - return f'<{self.__class__.__name__} {handle}>' - - @property - def handle(self): - return self._handle - - def fileno(self): - if self._handle is None: - raise ValueError("I/O operation on closed pipe") - return self._handle - - def close(self, *, CloseHandle=_winapi.CloseHandle): - if self._handle is not None: - CloseHandle(self._handle) - self._handle = None - - def __del__(self, _warn=warnings.warn): - if self._handle is not None: - _warn(f"unclosed {self!r}", ResourceWarning, source=self) - self.close() - - def __enter__(self): - return self - - def __exit__(self, t, v, tb): - self.close() - - -# Replacement for subprocess.Popen using overlapped pipe handles - - -class Popen(subprocess.Popen): - """Replacement for subprocess.Popen using overlapped pipe handles. - - The stdin, stdout, stderr are None or instances of PipeHandle. - """ - def __init__(self, args, stdin=None, stdout=None, stderr=None, **kwds): - assert not kwds.get('universal_newlines') - assert kwds.get('bufsize', 0) == 0 - 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), duplex=True) - stdin_rfd = msvcrt.open_osfhandle(stdin_rh, os.O_RDONLY) - else: - stdin_rfd = stdin - if stdout == PIPE: - stdout_rh, stdout_wh = pipe(overlapped=(True, False)) - stdout_wfd = msvcrt.open_osfhandle(stdout_wh, 0) - else: - stdout_wfd = stdout - if stderr == PIPE: - stderr_rh, stderr_wh = pipe(overlapped=(True, False)) - stderr_wfd = msvcrt.open_osfhandle(stderr_wh, 0) - elif stderr == STDOUT: - stderr_wfd = stdout_wfd - else: - stderr_wfd = stderr - try: - super().__init__(args, stdin=stdin_rfd, stdout=stdout_wfd, - stderr=stderr_wfd, **kwds) - except: - for h in (stdin_wh, stdout_rh, stderr_rh): - if h is not None: - _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) |