mrrl-containers

MRRL version of container scripts
git clone https://ccx.te2000.cz/git/mrrl-containers
Log | Files | Refs

commit 438d895c543e458b6f77288667a80de0f66e050a
parent caacc82941a0619c312e681fc9e99413090c1f43
Author: ccx <ccx@te2000.cz>
Date:   Fri,  1 Mar 2024 06:08:57 +0000

Rename pidns_run, exit properly on parent disappearing.

Diffstat:
Dsbin/pidns_run | 76----------------------------------------------------------------------------
Asbin/pidns_run.py | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+), 76 deletions(-)

diff --git a/sbin/pidns_run b/sbin/pidns_run @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 -import sys -import os -import os.path -import ctypes -import fcntl -import select -import errno - -libc = ctypes.CDLL(None, use_errno=True) -CLONE_NEWPID = 0x20000000 - - -def nonblock_cloexec(fd): - fcntl.fcntl( - fd, - fcntl.F_SETFD, - fcntl.fcntl(fd, fcntl.F_GETFD) | os.O_NONBLOCK | fcntl.FD_CLOEXEC, - ) - - -def exit_status(status): - sig = status & 0xff - ret = status >> 8 - if sig: - raise SystemExit(128 + sig) - if ret >= 128: - raise SystemExit(128) - raise SystemExit(ret) - - -def main(argv): - (parent_rfd, parent_wfd) = os.pipe() - nonblock_cloexec(parent_rfd) - nonblock_cloexec(parent_wfd) - if libc.unshare(CLONE_NEWPID) != 0: - raise OSError(ctypes.get_errno()) - fork_pid = os.fork() - if fork_pid == 0: - # child - assert os.getpid() == 1 - os.close(parent_wfd) - fork2_pid = os.fork() - if fork2_pid == 0: - # child - if argv[1][0] == '/': - os.execv(argv[1], argv[1:]) - for d in os.environ['PATH'].split(':'): - try: - os.execv(os.path.join(d, argv[1]), argv[1:]) - except FileNotFoundError: - continue - raise SystemExit(127) - else: - # parent - rlist, wlist, elist = (parent_rfd,), (), () - while True: - (pid, status) = os.waitpid(0, os.WNOHANG) - if pid == fork2_pid: - exit_status(status) - try: - r, w, x = select.select(rlist, wlist, elist, 1.0) - except select.error as e: - code, msg = e.args - # We might get interrupted by SIGCHLD here - if code != errno.EINTR: - raise - else: - # parent - os.close(parent_rfd) - (pid, status) = os.waitpid(fork_pid, 0) - exit_status(status) - - -if __name__ == '__main__': - main(sys.argv) diff --git a/sbin/pidns_run.py b/sbin/pidns_run.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +import sys +import os +import os.path +import ctypes +import fcntl +import select +import errno + +libc = ctypes.CDLL(None, use_errno=True) +CLONE_NEWPID = 0x20000000 + + +def nonblock_cloexec(fd): + fcntl.fcntl( + fd, + fcntl.F_SETFD, + fcntl.fcntl(fd, fcntl.F_GETFD) | os.O_NONBLOCK | fcntl.FD_CLOEXEC, + ) + + +def exit_status(status): + sig = status & 0xff + ret = status >> 8 + if sig: + raise SystemExit(128 + sig) + if ret >= 128: + raise SystemExit(128) + raise SystemExit(ret) + + +def main(argv): + (parent_rfd, parent_wfd) = os.pipe() + nonblock_cloexec(parent_rfd) + nonblock_cloexec(parent_wfd) + if libc.unshare(CLONE_NEWPID) != 0: + raise OSError(ctypes.get_errno()) + fork_pid = os.fork() + if fork_pid == 0: + # child + assert os.getpid() == 1 + os.close(parent_wfd) + fork2_pid = os.fork() + if fork2_pid == 0: + # child + if argv[1][0] == '/': + os.execv(argv[1], argv[1:]) + for d in os.environ['PATH'].split(':'): + try: + os.execv(os.path.join(d, argv[1]), argv[1:]) + except FileNotFoundError: + continue + raise SystemExit(127) + else: + # parent + rlist, wlist, elist = (parent_rfd,), (), () + while True: + (pid, status) = os.waitpid(0, os.WNOHANG) + if pid == fork2_pid: + exit_status(status) + try: + r, w, x = select.select(rlist, wlist, elist, 1.0) + except select.error as e: + code, msg = e.args + # We might get interrupted by SIGCHLD here + if code != errno.EINTR: + raise + if r: + sys.stderr.write('pidns_run: parent died, terminating\n') + raise SystemExit(111) + + else: + # parent + os.close(parent_rfd) + (pid, status) = os.waitpid(fork_pid, 0) + exit_status(status) + + +if __name__ == '__main__': + main(sys.argv)