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:
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())