You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
39 lines
1.0 KiB
39 lines
1.0 KiB
4 years ago
|
import os
|
||
|
import sys
|
||
|
import fcntl
|
||
|
import errno
|
||
|
import signal
|
||
|
|
||
|
|
||
|
def unblock_stdout():
|
||
|
# get a non-blocking stdout
|
||
|
child_pid, child_pty = os.forkpty()
|
||
|
if child_pid != 0: # parent
|
||
|
|
||
|
# child is in its own process group, manually pass kill signals
|
||
|
signal.signal(signal.SIGINT, lambda signum, frame: os.kill(child_pid, signal.SIGINT))
|
||
|
signal.signal(signal.SIGTERM, lambda signum, frame: os.kill(child_pid, signal.SIGTERM))
|
||
|
|
||
|
fcntl.fcntl(sys.stdout, fcntl.F_SETFL, fcntl.fcntl(sys.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||
|
|
||
|
while True:
|
||
|
try:
|
||
|
dat = os.read(child_pty, 4096)
|
||
|
except OSError as e:
|
||
|
if e.errno == errno.EIO:
|
||
|
break
|
||
|
continue
|
||
|
|
||
|
if not dat:
|
||
|
break
|
||
|
|
||
|
try:
|
||
|
sys.stdout.write(dat.decode('utf8'))
|
||
|
except (OSError, IOError, UnicodeDecodeError):
|
||
|
pass
|
||
|
|
||
|
# os.wait() returns a tuple with the pid and a 16 bit value
|
||
|
# whose low byte is the signal number and whose high byte is the exit satus
|
||
|
exit_status = os.wait()[1] >> 8
|
||
|
os._exit(exit_status)
|