mrrl-logincaps

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

commit 74a5987415c09fdac410eaeb26a8fd79be49906a
parent eff71495b8917bb618634a1d44b8ab67491a4c7d
Author: ccx <ccx@te2000.cz>
Date:   Fri, 22 Mar 2024 01:39:47 +0000

Set controlling terminal after s6-sudo

Diffstat:
Mbin/handle-nsx11-message | 9++++++++-
Abin/spawn-pty-nc.py | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/bin/handle-nsx11-message b/bin/handle-nsx11-message @@ -19,6 +19,12 @@ in_terminal() { } typeset -f -t in_terminal +in_terminal_nc() { + spawn-pty-nc.py "$terminal_env" " $^@" "" "$terminal_cmd[@]" +} +typeset -f -t in_terminal_nc + + adjust-brightness() { local backlight=/sys/class/backlight/intel_backlight awk >$backlight/brightness \ @@ -197,7 +203,8 @@ container-ssh() { return 1 fi - in_terminal s6-sudo /run/containers/$container/run/exec/exec env TERM=rxvt-unicode-256color s6-setsid "$@" + in_terminal_nc s6-sudo /run/containers/$container/run/exec/exec \ + env TERM=rxvt-unicode-256color s6-setsid s6-setsid -d 0 "$@" } pass-input() { diff --git a/bin/spawn-pty-nc.py b/bin/spawn-pty-nc.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +from __future__ import ( + generators, division, absolute_import, with_statement, print_function +) +import sys +import os +import os.path +from fcntl import ioctl +from termios import TIOCSCTTY +import signal + +# parser = argparse.ArgumentParser(description="Runs one program inside pty and another with changed privileges with master pty as fd 0") +# parser.add_argument('term_env', help='The TERM variable used by the slave') +# parser.add_argument('exe', nargs='+', help='Execline block defining program ran on slave end, then terminal program') + + +def execve(argv, env): + if '/' in argv[0]: + os.execve(argv[0], argv, env) + else: + for p in os.environ['PATH'].split(os.path.pathsep): + try: + os.execve(os.path.join(p, argv[0]), argv, env) + except OSError: + continue + raise SystemExit(1) + + +def exec_terminal(terminal, term_env, slave_exe): + assert isinstance(terminal, (list, tuple)) + assert all(isinstance(s, str) for s in terminal) + assert len(terminal) + assert isinstance(slave_exe, list) + assert all(isinstance(s, str) for s in slave_exe) + master, slave = os.openpty() + if os.fork(): + # parent + os.close(slave) + os.dup2(master, 0) + os.close(master) + env = dict(os.environ) + env['PTY_FD'] = "0" + execve(terminal, env) + else: + # child + + # reset select signal handlers + for sig in ( + signal.SIGHUP, + signal.SIGINT, + signal.SIGQUIT, + signal.SIGPIPE, + signal.SIGALRM, + signal.SIGTERM, + signal.SIGCHLD, + signal.SIGCONT, + # signal.SIGSTOP, + signal.SIGTSTP, + signal.SIGTTIN, + signal.SIGTTOU, + + ): + signal.signal(sig, signal.SIG_DFL) + + env = dict(os.environ) + env['TERM'] = term_env + env.pop('LOGNAME', None) + + os.close(master) + os.dup2(slave, 0) + os.dup2(slave, 1) + os.dup2(slave, 2) + os.close(slave) + #os.setsid() # create new session for this terminal + #ioctl(0, TIOCSCTTY, 0) # set controlling terminal + + execve(slave_exe, env) + + +def main(): + argv = sys.argv[1:] + if len(argv) < 2: + return 1 + + term_env = argv.pop(0) + # compat with argparse way + if term_env in ('-', '--'): + term_env = argv.pop(0) + + slave_argv = [] + + while argv: + a = argv.pop(0) + if a == '': + break + elif a[0] == ' ': + slave_argv.append(a[1:]) + else: + sys.stderr.write("Improperly terminated block!\n") + return 1 + if not argv: + sys.stderr.write("Terminal executable not specified.\n") + return 1 + + exec_terminal( + terminal=argv, + slave_exe=slave_argv, + term_env=term_env, + ) + return 3 + + +if __name__ == '__main__': + sys.exit(main())