commit defceb26ce06431297ca1009bd7b89917a9ed67e
parent 8716f7ba7975541ba89488ea63e4e73d913dacb0
Author: root <root@dorje.v103.te2000>
Date: Thu, 11 Nov 2021 01:30:58 +0000
Add signal-relay command, move all commands to prefix/command.
Diffstat:
A | signal-relay.c | | | 98 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 98 insertions(+), 0 deletions(-)
diff --git a/signal-relay.c b/signal-relay.c
@@ -0,0 +1,98 @@
+/* (c) Copyright 2007 Daniel Hokka Zakrisson
+ Released under the terms of the GNU GPL v2
+
+ Build with gcc -lvserver ... -osignal-relay signal-relay
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <stdint.h>
+typedef uint32_t xid_t;
+typedef uint32_t nid_t;
+typedef uint32_t tag_t;
+#include <vserver.h>
+
+#define PREFIX "signal-relay: "
+
+static pid_t child;
+
+static void signal_handler(int signal)
+{
+ /* child exited, so should we */
+ if (signal == SIGCHLD) {
+ int ret;
+ if (waitpid(child, &ret, 0) == -1) {
+ perror(PREFIX "waitpid");
+ exit(111);
+ }
+ exit(WEXITSTATUS(ret));
+ }
+ /* relay */
+ else {
+ xid_t xid = vc_get_task_xid(child);
+ if (xid == VC_NOCTX) {
+ perror(PREFIX "vc_get_task_xid");
+ return;
+ }
+ if (vc_ctx_kill(xid, child, signal) == -1)
+ perror(PREFIX "vc_ctx_kill");
+ }
+}
+
+#define SETSIG(sig) if (signal(sig, signal_handler) == SIG_ERR) { \
+ signal_handler(SIGTERM); \
+ perror(PREFIX "signal(" #sig ")"); \
+ exit(111); \
+ }
+int main(int argc, char *argv[])
+{
+ int opt, new_group = 0;
+ while ((opt = getopt(argc, argv, "+P")) != -1) {
+ switch (opt) {
+ case 'P':
+ new_group = 1;
+ break;
+ default:
+ fprintf(stderr, "Usage: %s [-P] <program> <args>*\n", argv[0]);
+ break;
+ }
+ }
+
+ if (argc == optind)
+ return 0;
+
+ SETSIG(SIGCHLD)
+ child = fork();
+ if (child == 0) {
+ if (new_group && setsid() == -1) {
+ perror(PREFIX "setsid");
+ exit(111);
+ }
+ execvp(argv[optind], argv+optind);
+ perror(PREFIX "execvp");
+ exit(111);
+ }
+ else if (child == -1) {
+ perror(PREFIX "fork");
+ exit(111);
+ }
+ SETSIG(SIGHUP)
+ SETSIG(SIGINT)
+ SETSIG(SIGSEGV)
+ SETSIG(SIGTERM)
+ SETSIG(SIGUSR1)
+ SETSIG(SIGUSR2)
+ SETSIG(SIGWINCH)
+ SETSIG(SIGALRM)
+ SETSIG(SIGPWR)
+
+ while (1) {
+ sleep(600);
+ }
+ /* never get here, signal handler exits */
+ return 1;
+}