Cleanup for stow ---STOW
[dotfiles/.git] / .local / lib / python2.7 / site-packages / trollius / windows_utils.py
diff --git a/.local/lib/python2.7/site-packages/trollius/windows_utils.py b/.local/lib/python2.7/site-packages/trollius/windows_utils.py
new file mode 100644 (file)
index 0000000..288d547
--- /dev/null
@@ -0,0 +1,238 @@
+"""
+Various Windows specific bits and pieces
+"""
+from __future__ import absolute_import
+
+import sys
+
+if sys.platform != 'win32':  # pragma: no cover
+    raise ImportError('win32 only')
+
+import itertools
+import msvcrt
+import os
+import socket
+import subprocess
+import tempfile
+import warnings
+
+import six
+
+from . import py33_winapi as _winapi
+from . import compat
+from .py33_exceptions import wrap_error, BlockingIOError, InterruptedError
+
+
+__all__ = ['socketpair', 'pipe', 'Popen', 'PIPE', 'PipeHandle']
+
+
+# Constants/globals
+
+
+BUFSIZE = 8192
+PIPE = subprocess.PIPE
+STDOUT = subprocess.STDOUT
+_mmap_counter = itertools.count()
+
+
+if hasattr(socket, 'socketpair'):
+    # Since Python 3.5, socket.socketpair() is now also available on Windows
+    socketpair = socket.socketpair
+else:
+    # Replacement for socket.socketpair()
+    def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
+        """A socket pair usable as a self-pipe, for Windows.
+
+        Origin: https://gist.github.com/4325783, by Geert Jansen.
+        Public domain.
+        """
+        if family == socket.AF_INET:
+            host = '127.0.0.1'
+        elif family == socket.AF_INET6:
+            host = '::1'
+        else:
+            raise ValueError("Only AF_INET and AF_INET6 socket address "
+                             "families are supported")
+        if type != socket.SOCK_STREAM:
+            raise ValueError("Only SOCK_STREAM socket type is supported")
+        if proto != 0:
+            raise ValueError("Only protocol zero is supported")
+
+        # We create a connected TCP socket. Note the trick with setblocking(0)
+        # that prevents us from having to create a thread.
+        lsock = socket.socket(family, type, proto)
+        try:
+            lsock.bind((host, 0))
+            lsock.listen(1)
+            # On IPv6, ignore flow_info and scope_id
+            addr, port = lsock.getsockname()[:2]
+            csock = socket.socket(family, type, proto)
+            try:
+                csock.setblocking(False)
+                try:
+                    wrap_error(csock.connect, (addr, port))
+                except (BlockingIOError, InterruptedError):
+                    pass
+                csock.setblocking(True)
+                ssock, _ = lsock.accept()
+            except:
+                csock.close()
+                raise
+        finally:
+            lsock.close()
+        return (ssock, csock)
+
+
+# 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-' %
+                              (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)
+        if hasattr(ov, 'GetOverlappedResult'):
+            # _winapi module of Python 3.3
+            ov.GetOverlappedResult(True)
+        else:
+            # _overlapped module
+            wrap_error(ov.getresult, 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(object):
+    """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 = 'handle=%r' % self._handle
+        else:
+            handle = 'closed'
+        return '<%s %s>' % (self.__class__.__name__, handle)
+
+    @property
+    def handle(self):
+        return self._handle
+
+    def fileno(self):
+        if self._handle is None:
+            raise ValueError("I/O operatioon 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):
+        if self._handle is not None:
+            if six.PY3:
+                warnings.warn("unclosed %r" % self, ResourceWarning)
+            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(Popen, self).__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)