tvl-depot/users/Profpatsch/shortcuttable/default.nix
Profpatsch 8335076173 feat(users/Profpatsch): add shortcuttable
Initial mockup for a tool which restarts its subprocess on SIGHUP, and
stops everything on SIGTERM and SIGINT.

Change-Id: Ie5260d73c2663d1821eb6623e2bc61d16f6c92cd
Reviewed-on: https://cl.tvl.fyi/c/depot/+/11168
Autosubmit: Profpatsch <mail@profpatsch.de>
Reviewed-by: Profpatsch <mail@profpatsch.de>
Tested-by: BuildkiteCI
2024-03-16 22:36:55 +00:00

172 lines
3.6 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ depot, lib, pkgs, ... }:
let
# run prog... and restart whenever SIGHUP is received
#
# this is useful for binding to a shortcut.
#
# Unfortunately, this requires a bunch of workarounds around the semantics of `trap`,
# but the general idea of bundling subprocesses with `setsid` is somewhat sound.
runShortcuttable =
depot.nix.writeExecline "run-shortcuttable" { } [
"importas"
"-i"
"run"
"XDG_RUNTIME_DIR"
"if"
[ "mkdir" "-p" "\${run}/shortcuttable/test" ]
"getpid"
"-E"
"controlpid"
savePid
"\${run}/shortcuttable/test/control"
"$controlpid"
# start the program
"background"
[
startSaveSID
"\${run}/shortcuttable/test/running-sid"
"$@"
]
"trap"
[
"SIGHUP"
[
"if"
[ "echo" "got hup" ]
"if"
[
"if"
[ "echo" "killing our child processes" ]
"envfile"
"\${run}/shortcuttable/test/running-sid"
"importas"
"-ui"
"child_sid"
"pid"
"foreground"
[ "ps" "-f" "--sid" "$child_sid" ]
ctrlCCtrlDSid
"$child_sid"
]
"if"
[ "echo" "restarting into" "$@" ]
"background"
[
startSaveSID
"\${run}/shortcuttable/test/running-sid"
"$@"
]
]
"SIGTERM"
[
(killShortcuttable { signal = "TERM"; })
"\${run}/shortcuttable/test/running-sid"
"\${run}/shortcuttable/test/exit"
]
"SIGINT"
[
(killShortcuttable { signal = "INT"; })
"\${run}/shortcuttable/test/running-sid"
"\${run}/shortcuttable/test/exit"
]
]
depot.users.Profpatsch.execline.setsid
"child_sid"
"getpid"
"-E"
"exitpid"
savePid
"\${run}/shortcuttable/test/exit"
"$exitpid"
"sleep"
"infinity"
];
killShortcuttable = { signal }: depot.nix.writeExecline "kill-shortcuttable" { readNArgs = 2; } [
"if"
[ "echo" "got SIG${signal}, quitting" ]
"if"
[
"envfile"
"$1"
"importas"
"-ui"
"child_sid"
"pid"
"foreground"
[ "ps" "-f" "--sid" "$child_sid" ]
ctrlCCtrlDSid
"$child_sid"
]
"if"
[ "echo" "killing shortcuttable loop" ]
"envfile"
"$2"
"importas"
"-ui"
"trap_pid"
"pid"
"foreground"
[ "ps" "-fp" "$trap_pid" ]
"kill"
"--signal"
signal
"$trap_pid"
];
savePid = depot.nix.writeExecline "save-pid" { readNArgs = 2; } [
"if"
[ "echo" "saving process:" ]
"if"
[ "ps" "-fp" "$2" ]
"if"
[
"redirfd"
"-w"
"1"
"$1"
"printf"
"pid = %s\n"
"$2"
]
"$@"
];
# try to kill process, first with SIGTERM then SIGQUIT (in case its a repl)
ctrlCCtrlDSid = depot.nix.writeExecline "ctrl-c-ctrl-d" { readNArgs = 1; } [
"ifelse"
"-n"
[ "kill" "--signal" "TERM" "--" "-\${1}" ]
[
"if"
[ "echo" "could not kill via SIGTERM, trying SIGQUIT " ]
"ifelse"
"-n"
[ "kill" "--signal" "QUIT" "--" "-\${1}" ]
[ "echo" "SIGQUIT failed as well, keeping it running" ]
"$@"
]
"$@"
];
startSaveSID = depot.nix.writeExecline "start-save-sid" { readNArgs = 1; } [
depot.users.Profpatsch.execline.setsid
"child_sid"
"importas"
"-ui"
"child_sid"
"child_sid"
"if"
[ "echo" "children sid:" "$child_sid" ]
savePid
"$1"
"$child_sid"
"$@"
];
in
runShortcuttable