vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

signal-relay.c (1860B)


      1 /* (c) Copyright 2007 Daniel Hokka Zakrisson
      2    Released under the terms of the GNU GPL v2
      3 
      4    Build with gcc -lvserver ... -osignal-relay signal-relay
      5  */
      6 
      7 #include <stdio.h>
      8 #include <signal.h>
      9 #include <sys/types.h>
     10 #include <sys/wait.h>
     11 #include <unistd.h>
     12 
     13 #include <stdint.h>
     14 typedef uint32_t		xid_t;
     15 typedef uint32_t		nid_t;
     16 typedef uint32_t		tag_t;
     17 #include <vserver.h>
     18 
     19 #define PREFIX "signal-relay: "
     20 
     21 static pid_t child;
     22 
     23 static void signal_handler(int signal)
     24 {
     25 	/* child exited, so should we */
     26 	if (signal == SIGCHLD) {
     27 		int ret;
     28 		if (waitpid(child, &ret, 0) == -1) {
     29 			perror(PREFIX "waitpid");
     30 			exit(111);
     31 		}
     32 		exit(WEXITSTATUS(ret));
     33 	}
     34 	/* relay */
     35 	else {
     36 		xid_t xid = vc_get_task_xid(child);
     37 		if (xid == VC_NOCTX) {
     38 			perror(PREFIX "vc_get_task_xid");
     39 			return;
     40 		}
     41 		if (vc_ctx_kill(xid, child, signal) == -1)
     42 			perror(PREFIX "vc_ctx_kill");
     43 	}
     44 }
     45 
     46 #define SETSIG(sig)	if (signal(sig, signal_handler) == SIG_ERR) { \
     47 				signal_handler(SIGTERM); \
     48 				perror(PREFIX "signal(" #sig ")"); \
     49 				exit(111); \
     50 			}
     51 int main(int argc, char *argv[])
     52 {
     53 	int opt, new_group = 0;
     54 	while ((opt = getopt(argc, argv, "+P")) != -1) {
     55 		switch (opt) {
     56 		case 'P':
     57 			new_group = 1;
     58 			break;
     59 		default:
     60 			fprintf(stderr, "Usage: %s [-P] <program> <args>*\n", argv[0]);
     61 			break;
     62 		}
     63 	}
     64 
     65 	if (argc == optind)
     66 		return 0;
     67 
     68 	SETSIG(SIGCHLD)
     69 	child = fork();
     70 	if (child == 0) {
     71 		if (new_group && setsid() == -1) {
     72 			perror(PREFIX "setsid");
     73 			exit(111);
     74 		}
     75 		execvp(argv[optind], argv+optind);
     76 		perror(PREFIX "execvp");
     77 		exit(111);
     78 	}
     79 	else if (child == -1) {
     80 		perror(PREFIX "fork");
     81 		exit(111);
     82 	}
     83 	SETSIG(SIGHUP)
     84 	SETSIG(SIGINT)
     85 	SETSIG(SIGSEGV)
     86 	SETSIG(SIGTERM)
     87 	SETSIG(SIGUSR1)
     88 	SETSIG(SIGUSR2)
     89 	SETSIG(SIGWINCH)
     90 	SETSIG(SIGALRM)
     91 	SETSIG(SIGPWR)
     92 
     93 	while (1) {
     94 		sleep(600);
     95 	}
     96 	/* never get here, signal handler exits */
     97 	return 1;
     98 }