util/run_silent_if_successful.py (49 lines of code) (raw):

#!/usr/bin/env python3 # Copyright (c) Facebook, Inc. and its affiliates. # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import os import pty import signal import subprocess import sys import threading master_pty_fd, slave_pty_fd = pty.openpty() read_data = [] def master_pty_fd_reader(): while True: try: data = os.read(master_pty_fd, 1024) except OSError: return else: if data: read_data.append(data) else: return master_pty_fd_reader_thread = threading.Thread(target=master_pty_fd_reader) master_pty_fd_reader_thread.start() pid = None def handler(signal_number, frame): if not pid: return os.kill(pid, signal_number) signal.signal(signal.SIGINT, handler) signal.signal(signal.SIGTERM, handler) signal.signal(signal.SIGHUP, handler) try: popen = subprocess.Popen( sys.argv[1:], stdin=subprocess.DEVNULL, stdout=slave_pty_fd, stderr=slave_pty_fd, ) except FileNotFoundError as e: print(str(e), file=sys.stderr) os.close(slave_pty_fd) master_pty_fd_reader_thread.join() sys.exit(127) pid = popen.pid returncode = popen.wait() os.close(slave_pty_fd) master_pty_fd_reader_thread.join() if returncode: for data in read_data: os.write(sys.stdout.fileno(), data) sys.exit(returncode)