#!/usr/bin/env python
# Copyright 2018-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import errno
import fcntl
import functools
import os
import platform
import signal
import subprocess
import sys
import termios


KILL_SIGNALS = (
	signal.SIGINT,
	signal.SIGTERM,
	signal.SIGHUP,
)

SIGTSTP_SIGCONT = (
	signal.SIGTSTP,
	signal.SIGCONT,
)


def forward_kill_signal(pid, signum, frame):
	if pid == 0:
		# Avoid a signal feedback loop, since signals sent to the
		# process group are also sent to the current process.
		signal.signal(signum, signal.SIG_DFL)
	os.kill(pid, signum)


def forward_sigtstp_sigcont(pid, signum, frame):
	handler = None
	if pid == 0:
		# Temporarily disable the handler in order to prevent it from
		# being called recursively, since the signal will also be sent
		# to the current process.
		handler = signal.signal(signum, signal.SIG_DFL)
	os.kill(pid, signum)
	if handler is not None:
		signal.signal(signum, handler)


def preexec_fn(uid, gid, groups, umask):
	if gid is not None:
		os.setgid(gid)
	if groups is not None:
		os.setgroups(groups)
	if uid is not None:
		os.setuid(uid)
	if umask is not None:
		os.umask(umask)

	# CPython >= 3 subprocess.Popen handles this internally.
	if platform.python_implementation() != 'CPython':
		for signum in (
			signal.SIGHUP,
			signal.SIGINT,
			signal.SIGPIPE,
			signal.SIGQUIT,
			signal.SIGTERM,
			):
			signal.signal(signum, signal.SIG_DFL)


def main(argv):
	if len(argv) < 2:
		return 'Usage: {} <main-child-pid> or <uid> <gid> <groups> <umask> <pass_fds> <binary> <argv0> [arg]..'.format(argv[0])

	if len(argv) == 2:
		# The child process is init (pid 1) in a child pid namespace, and
		# the current process supervises from within the global pid namespace
		# (forwarding signals to init and forwarding exit status to the parent
		# process).
		main_child_pid = int(argv[1])
		setsid = False
		proc = None
	else:
		# The current process is init (pid 1) in a child pid namespace.
		uid, gid, groups, umask, pass_fds, binary, args = argv[1], argv[2], argv[3], argv[4], tuple(int(fd) for fd in argv[5].split(',')), argv[6], argv[7:]
		uid = int(uid) if uid else None
		gid = int(gid) if gid else None
		groups = tuple(int(group) for group in groups.split(',')) if groups else None
		umask = int(umask) if umask else None

		popen_kwargs = {
			'preexec_fn': functools.partial(preexec_fn, uid, gid, groups, umask),
			'pass_fds': pass_fds,
		}
		# Isolate parent process from process group SIGSTOP (bug 675870)
		setsid = True
		os.setsid()
		if sys.stdout.isatty():
			try:
				fcntl.ioctl(sys.stdout, termios.TIOCSCTTY, 0)
			except EnvironmentError as e:
				if e.errno == errno.EPERM:
					# This means that stdout refers to the controlling terminal
					# of the parent process, and in this case we do not want to
					# steal it.
					pass
				else:
					raise
		proc = subprocess.Popen(args, executable=binary, **popen_kwargs)
		main_child_pid = proc.pid

	# If setsid has been called, use kill(0, signum) to
	# forward signals to the entire process group.
	sig_handler = functools.partial(forward_kill_signal, 0 if setsid else main_child_pid)
	for signum in KILL_SIGNALS:
		signal.signal(signum, sig_handler)

	# For correct operation of Ctrl+Z, forward SIGTSTP and SIGCONT.
	sigtstp_sigcont_handler = functools.partial(forward_sigtstp_sigcont, 0 if setsid else main_child_pid)
	for signum in SIGTSTP_SIGCONT:
		signal.signal(signum, sigtstp_sigcont_handler)

	# wait for child processes
	while True:
		try:
			pid, status = os.wait()
		except EnvironmentError as e:
			if e.errno == errno.EINTR:
				continue
			raise
		if pid == main_child_pid:
			if proc is not None:
				# Suppress warning messages like this:
				# ResourceWarning: subprocess 1234 is still running
				proc.returncode = 0

			if os.WIFEXITED(status):
				return os.WEXITSTATUS(status)
			elif os.WIFSIGNALED(status):
				signal.signal(os.WTERMSIG(status), signal.SIG_DFL)
				os.kill(os.getpid(), os.WTERMSIG(status))
			# go to the unreachable place
			break

	# this should never be reached
	return 127


if __name__ == '__main__':
	sys.exit(main(sys.argv))
