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
			| 
											5 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)
 |