#!/usr/bin/env python
# Copyright 2018-2019 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,
)


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 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 sys.version_info.major < 3 or 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 = {}
		popen_kwargs['preexec_fn'] = functools.partial(preexec_fn, uid, gid, groups, umask)
		if sys.version_info.major > 2:
			popen_kwargs['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
					# steel 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)

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