mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 16:34:47 +01:00
copy code from subprocess rather than inheriting from Popen
This commit is contained in:
parent
aec5a0be4e
commit
253f78c323
1 changed files with 149 additions and 2 deletions
151
xonsh/proc.py
151
xonsh/proc.py
|
@ -1,6 +1,7 @@
|
|||
import io
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
|
||||
from threading import Thread
|
||||
from subprocess import Popen
|
||||
|
@ -8,7 +9,13 @@ from collections import Sequence
|
|||
|
||||
from xonsh.tools import redirect_stdout, redirect_stderr
|
||||
|
||||
class ProcProxy(Thread, Popen):
|
||||
iswindows = platform.system() == 'Windows'
|
||||
if iswindows:
|
||||
import _winapi
|
||||
import msvcrt
|
||||
|
||||
|
||||
class ProcProxy(Thread):
|
||||
def __init__(self, f, args,
|
||||
stdin=None,
|
||||
stdout=None,
|
||||
|
@ -18,7 +25,8 @@ class ProcProxy(Thread, Popen):
|
|||
self.args = args
|
||||
self.pid = None
|
||||
self.returncode = None
|
||||
|
||||
self.wait = self.join
|
||||
|
||||
handles = self._get_handles(stdin, stdout, stderr)
|
||||
(self.p2cread, self.p2cwrite,
|
||||
self.c2pread, self.c2pwrite,
|
||||
|
@ -67,6 +75,145 @@ class ProcProxy(Thread, Popen):
|
|||
def poll(self):
|
||||
return self.returncode
|
||||
|
||||
# The code below (_get_devnull, _get_handles, and _make_inheritable) comes
|
||||
# from subprocess.py in the Python 3.4.2 Standard Library
|
||||
def _get_devnull(self):
|
||||
if not hasattr(self, '_devnull'):
|
||||
self._devnull = os.open(os.devnull, os.O_RDWR)
|
||||
return self._devnull
|
||||
|
||||
if iswindows:
|
||||
def _make_inheritable(self, handle):
|
||||
"""Return a duplicate of handle, which is inheritable"""
|
||||
h = _winapi.DuplicateHandle(
|
||||
_winapi.GetCurrentProcess(), handle,
|
||||
_winapi.GetCurrentProcess(), 0, 1,
|
||||
_winapi.DUPLICATE_SAME_ACCESS)
|
||||
return Handle(h)
|
||||
|
||||
def _get_handles(self, stdin, stdout, stderr):
|
||||
"""Construct and return tuple with IO objects:
|
||||
p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
|
||||
"""
|
||||
if stdin is None and stdout is None and stderr is None:
|
||||
return (-1, -1, -1, -1, -1, -1)
|
||||
|
||||
p2cread, p2cwrite = -1, -1
|
||||
c2pread, c2pwrite = -1, -1
|
||||
errread, errwrite = -1, -1
|
||||
|
||||
if stdin is None:
|
||||
p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE)
|
||||
if p2cread is None:
|
||||
p2cread, _ = _winapi.CreatePipe(None, 0)
|
||||
p2cread = Handle(p2cread)
|
||||
_winapi.CloseHandle(_)
|
||||
elif stdin == PIPE:
|
||||
p2cread, p2cwrite = _winapi.CreatePipe(None, 0)
|
||||
p2cread, p2cwrite = Handle(p2cread), Handle(p2cwrite)
|
||||
elif stdin == DEVNULL:
|
||||
p2cread = msvcrt.get_osfhandle(self._get_devnull())
|
||||
elif isinstance(stdin, int):
|
||||
p2cread = msvcrt.get_osfhandle(stdin)
|
||||
else:
|
||||
# Assuming file-like object
|
||||
p2cread = msvcrt.get_osfhandle(stdin.fileno())
|
||||
p2cread = self._make_inheritable(p2cread)
|
||||
|
||||
if stdout is None:
|
||||
c2pwrite = _winapi.GetStdHandle(_winapi.STD_OUTPUT_HANDLE)
|
||||
if c2pwrite is None:
|
||||
_, c2pwrite = _winapi.CreatePipe(None, 0)
|
||||
c2pwrite = Handle(c2pwrite)
|
||||
_winapi.CloseHandle(_)
|
||||
elif stdout == PIPE:
|
||||
c2pread, c2pwrite = _winapi.CreatePipe(None, 0)
|
||||
c2pread, c2pwrite = Handle(c2pread), Handle(c2pwrite)
|
||||
elif stdout == DEVNULL:
|
||||
c2pwrite = msvcrt.get_osfhandle(self._get_devnull())
|
||||
elif isinstance(stdout, int):
|
||||
c2pwrite = msvcrt.get_osfhandle(stdout)
|
||||
else:
|
||||
# Assuming file-like object
|
||||
c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
|
||||
c2pwrite = self._make_inheritable(c2pwrite)
|
||||
|
||||
if stderr is None:
|
||||
errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE)
|
||||
if errwrite is None:
|
||||
_, errwrite = _winapi.CreatePipe(None, 0)
|
||||
errwrite = Handle(errwrite)
|
||||
_winapi.CloseHandle(_)
|
||||
elif stderr == PIPE:
|
||||
errread, errwrite = _winapi.CreatePipe(None, 0)
|
||||
errread, errwrite = Handle(errread), Handle(errwrite)
|
||||
elif stderr == STDOUT:
|
||||
errwrite = c2pwrite
|
||||
elif stderr == DEVNULL:
|
||||
errwrite = msvcrt.get_osfhandle(self._get_devnull())
|
||||
elif isinstance(stderr, int):
|
||||
errwrite = msvcrt.get_osfhandle(stderr)
|
||||
else:
|
||||
# Assuming file-like object
|
||||
errwrite = msvcrt.get_osfhandle(stderr.fileno())
|
||||
errwrite = self._make_inheritable(errwrite)
|
||||
|
||||
return (p2cread, p2cwrite,
|
||||
c2pread, c2pwrite,
|
||||
errread, errwrite)
|
||||
|
||||
else:
|
||||
# POSIX versions
|
||||
def _get_handles(self, stdin, stdout, stderr):
|
||||
"""Construct and return tuple with IO objects:
|
||||
p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
|
||||
"""
|
||||
p2cread, p2cwrite = -1, -1
|
||||
c2pread, c2pwrite = -1, -1
|
||||
errread, errwrite = -1, -1
|
||||
|
||||
if stdin is None:
|
||||
pass
|
||||
elif stdin == PIPE:
|
||||
p2cread, p2cwrite = os.pipe()
|
||||
elif stdin == DEVNULL:
|
||||
p2cread = self._get_devnull()
|
||||
elif isinstance(stdin, int):
|
||||
p2cread = stdin
|
||||
else:
|
||||
# Assuming file-like object
|
||||
p2cread = stdin.fileno()
|
||||
|
||||
if stdout is None:
|
||||
pass
|
||||
elif stdout == PIPE:
|
||||
c2pread, c2pwrite = os.pipe()
|
||||
elif stdout == DEVNULL:
|
||||
c2pwrite = self._get_devnull()
|
||||
elif isinstance(stdout, int):
|
||||
c2pwrite = stdout
|
||||
else:
|
||||
# Assuming file-like object
|
||||
c2pwrite = stdout.fileno()
|
||||
|
||||
if stderr is None:
|
||||
pass
|
||||
elif stderr == PIPE:
|
||||
errread, errwrite = os.pipe()
|
||||
elif stderr == STDOUT:
|
||||
errwrite = c2pwrite
|
||||
elif stderr == DEVNULL:
|
||||
errwrite = self._get_devnull()
|
||||
elif isinstance(stderr, int):
|
||||
errwrite = stderr
|
||||
else:
|
||||
# Assuming file-like object
|
||||
errwrite = stderr.fileno()
|
||||
|
||||
return (p2cread, p2cwrite,
|
||||
c2pread, c2pwrite,
|
||||
errread, errwrite)
|
||||
|
||||
def _simple_wrapper(f):
|
||||
def wrapped_simple_command_proxy(args, stdin, stdout, stderr):
|
||||
try:
|
||||
|
|
Loading…
Add table
Reference in a new issue