Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- '''
- Modern recipe for async subprocesses in Linux and Windows. Works in Python 3.3+.
- Written March 28, 2014 by Josiah Carlson
- Released into the public domain.
- From these two functions you can build buffered reads, writes, timeouts on
- reads or writes, readline, etc.
- '''
- import errno
- import os
- import subprocess
- import time
- if subprocess.mswindows:
- from _winapi import PeekNamedPipe, ReadFile, WriteFile
- from msvcrt import get_osfhandle
- else:
- import fcntl
- import select
- def read(sp, stderr=False):
- """
- Reads all available data from the provided subprocess.
- Pass stderr=True if you want to read from stderr.
- """
- pipe = sp.stderr if stderr else sp.stdout
- if pipe.closed:
- return b''
- flags = fcntl.fcntl(pipe, fcntl.F_GETFL)
- fcntl.fcntl(pipe, fcntl.F_SETFL, flags | os.O_NONBLOCK)
- ret = []
- try:
- while select.select([pipe], [], [], 0)[0]:
- ret.append(pipe.read(4096))
- if not ret[-1]:
- break
- return b''.join(ret)
- finally:
- if not pipe.closed:
- fcntl.fcntl(pipe, fcntl.F_SETFL, flags)
- def write(sp, data):
- """
- Tries to write the data to the provided subprocess.
- Returns the number of bytes written.
- """
- if not select.select([], [sp.stdin], [], 0)[1]:
- return 0
- try:
- return os.write(sp.stdin.fileno(), data)
- except OSError as why:
- if why[0] == errno.EPIPE:
- return 0
- raise
- if subprocess.mswindows:
- def read(sp, stderr=False):
- """
- Reads all available data from the provided subprocess.
- Pass stderr=True if you want to read from stderr.
- """
- pipe = sp.stderr if stderr else sp.stdout
- if pipe.closed:
- return b''
- try:
- handle = get_osfhandle(pipe.fileno())
- avail = PeekNamedPipe(handle, 0)[0]
- if avail > 0:
- return ReadFile(handle, avail)[0]
- return b''
- except ValueError:
- return b''
- except (subprocess.pywintypes.error, Exception) as why:
- if why[0] in (109, errno.ESHUTDOWN):
- return b''
- raise
- def write(sp, data):
- """
- Tries to write the data to the provided subprocess.
- Returns the number of bytes written.
- """
- try:
- handle = get_osfhandle(sp.stdin.fileno())
- return WriteFile(handle, data)[0]
- except ValueError:
- return 0
- except (subprocess.pywintypes.error, Exception) as why:
- if why[0] in (109, errno.ESHUTDOWN):
- return 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement