"""Various Windows specific bits and pieces."""import sysif sys.platform != 'win32': # pragma: no coverraise ImportError('win32 only')import _winapiimport itertoolsimport msvcrtimport osimport subprocessimport tempfileimport warnings__all__ = 'pipe', 'Popen', 'PIPE', 'PipeHandle'# Constants/globalsBUFSIZE = 8192PIPE = subprocess.PIPESTDOUT = subprocess.STDOUT_mmap_counter = itertools.count()# Replacement for os.pipe() using handles instead of fdsdef 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_DUPLEXaccess = _winapi.GENERIC_READ | _winapi.GENERIC_WRITEobsize, ibsize = bufsize, bufsizeelse:openmode = _winapi.PIPE_ACCESS_INBOUNDaccess = _winapi.GENERIC_WRITEobsize, ibsize = 0, bufsizeopenmode |= _winapi.FILE_FLAG_FIRST_PIPE_INSTANCEif overlapped[0]:openmode |= _winapi.FILE_FLAG_OVERLAPPEDif overlapped[1]:flags_and_attribs = _winapi.FILE_FLAG_OVERLAPPEDelse:flags_and_attribs = 0h1 = h2 = Nonetry: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, h2except:if h1 is not None:_winapi.CloseHandle(h1)if h2 is not None:_winapi.CloseHandle(h2)raise# Wrapper for a pipe handleclass 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 = handledef __repr__(self):if self._handle is not None:handle = f'handle={self._handle!r}'else:handle = 'closed'return f'<{self.__class__.__name__}{handle}>'@propertydef handle(self):return self._handledef fileno(self):if self._handle is None:raise ValueError("I/O operation on closed pipe")return self._handledef close(self, *, CloseHandle=_winapi.CloseHandle):if self._handle is not None:CloseHandle(self._handle)self._handle = Nonedef __del__(self):if self._handle is not None:warnings.warn(f"unclosed {self!r}", ResourceWarning,source=self)self.close()def __enter__(self):return selfdef __exit__(self, t, v, tb):self.close()# Replacement for subprocess.Popen using overlapped pipe handlesclass 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) == 0stdin_rfd = stdout_wfd = stderr_wfd = Nonestdin_wh = stdout_rh = stderr_rh = Noneif 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 = stdinif stdout == PIPE:stdout_rh, stdout_wh = pipe(overlapped=(True, False))stdout_wfd = msvcrt.open_osfhandle(stdout_wh, 0)else:stdout_wfd = stdoutif stderr == PIPE:stderr_rh, stderr_wh = pipe(overlapped=(True, False))stderr_wfd = msvcrt.open_osfhandle(stderr_wh, 0)elif stderr == STDOUT:stderr_wfd = stdout_wfdelse:stderr_wfd = stderrtry: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)raiseelse: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)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。