#include #include #include #include #include #include #include volatile sig_atomic_t current_src; volatile sig_atomic_t current_sig = -1; int before = -1; int after = -1; int start = 0; void handler (int sig, siginfo_t * info, void * unused) { if (info && (info->si_code != SI_NOINFO) && (info->si_code <= 0)) { current_sig = sig; current_src = info->si_pid; } else if (start) { current_sig = sig; current_src = -1; } } int main (int argc, char ** argv) { struct sigaction act; char c; act.sa_sigaction = handler; act.sa_flags = SA_SIGINFO; sigemptyset (&act.sa_mask); sigaddset (&act.sa_mask, SIGUSR1); sigaddset (&act.sa_mask, SIGTERM); sigaddset (&act.sa_mask, SIGINT); if (sigaction (SIGUSR1, &act, NULL)) { perror ("sigaction"); return 1; } if (sigaction (SIGUSR2, &act, NULL)) { perror ("sigaction"); return 1; } if (sigaction (SIGINT, &act, NULL)) { perror ("sigaction"); return 1; } if (sigaction (SIGTERM, &act, NULL)) { perror ("sigaction"); return 1; } switch (argc) { case 1: break; case 3: if (strcmp (argv[2], "start") != 0) { fprintf (stderr, "usage: %s [ pid [start] ]\n", argv[0]); return 1; } start = 1; /* Fall though */ case 2: if (sscanf (argv[1], "%d%c", &after, &c) == 1) break; /* Fall through */ default: fprintf (stderr, "usage: %s [ pid [start] ]\n", argv[0]); /* Fall through */ case 0: /* Can't output a usage message without argv[0]! */ return 1; } while (1) { int this_sig, this_src; while (current_sig < 0) pause (); sighold (SIGUSR1); sighold (SIGUSR2); sighold (SIGTERM); sighold (SIGINT); this_sig = current_sig; this_src = current_src; current_sig = -1; sigrelse (SIGUSR1); sigrelse (SIGUSR2); sigrelse (SIGTERM); sigrelse (SIGINT); if (this_sig < 0) continue; printf ("Jupp (sig = %d, me = %d)\n", this_sig, (int)getpid ()); if ((start && (this_src < 0)) || (this_src != after)) { if (!start) before = this_src; if (after < 0) { printf ("Bounce (sig = %d, me = %d)\n", this_sig, (int)getpid ()); this_src = after; } else kill (after, this_sig); } if (this_src == after) { if (before >= 0) kill (before, this_sig); else printf ("Drop (sig = %d, me = %d)\n", this_sig, (int)getpid ()); if ((this_sig == SIGTERM) || (this_sig == SIGINT)) break; } } return 0; }