/* $Id$ Copyright 2007, Red Hat Inc. */ #include #include #include #include #include #include #define tkill(tid, sig) syscall (__NR_tkill, (tid), (sig)) #define LENGTH(x) (sizeof (x) / sizeof (*(x))) struct signal { int signo; const char *name; }; static const struct signal sigtab[] = { #ifdef SIG0 { SIG0, "0" }, #endif #ifdef SIGHUP { SIGHUP, "HUP" }, #endif #ifdef SIGINT { SIGINT, "INT" }, #endif #ifdef SIGQUIT { SIGQUIT, "QUIT" }, #endif #ifdef SIGILL { SIGILL, "ILL" }, #endif #ifdef SIGTRAP { SIGTRAP, "TRAP" }, #endif #ifdef SIGABRT { SIGABRT, "ABRT" }, #endif #ifdef SIGBUS { SIGBUS, "BUS" }, #endif #ifdef SIGFPE { SIGFPE, "FPE" }, #endif #ifdef SIGKILL { SIGKILL, "KILL" }, #endif #ifdef SIGUSR1 { SIGUSR1, "USR1" }, #endif #ifdef SIGSEGV { SIGSEGV, "SEGV" }, #endif #ifdef SIGUSR2 { SIGUSR2, "USR2" }, #endif #ifdef SIGPIPE { SIGPIPE, "PIPE" }, #endif #ifdef SIGALRM { SIGALRM, "ALRM" }, #endif #ifdef SIGTERM { SIGTERM, "TERM" }, #endif #ifdef SIGSTKFLT { SIGSTKFLT, "STKFLT" }, #endif #ifdef SIGCHLD { SIGCHLD, "CHLD" }, #endif #ifdef SIGCONT { SIGCONT, "CONT" }, #endif #ifdef SIGSTOP { SIGSTOP, "STOP" }, #endif #ifdef SIGTSTP { SIGTSTP, "TSTP" }, #endif #ifdef SIGTTIN { SIGTTIN, "TTIN" }, #endif #ifdef SIGTTOU { SIGTTOU, "TTOU" }, #endif #ifdef SIGURG { SIGURG, "URG" }, #endif #ifdef SIGXCPU { SIGXCPU, "XCPU" }, #endif #ifdef SIGXFSZ { SIGXFSZ, "XFSZ" }, #endif #ifdef SIGVTALRM { SIGVTALRM, "VTALRM" }, #endif #ifdef SIGPROF { SIGPROF, "PROF" }, #endif #ifdef SIGWINCH { SIGWINCH, "WINCH" }, #endif #ifdef SIGIO { SIGIO, "IO" }, #endif #ifdef SIGPWR { SIGPWR, "PWR" }, #endif #ifdef SIGSYS { SIGSYS, "SYS" }, #endif #ifdef disableSIGRTMIN /* initializer element is not constant */ { SIGRTMIN, "RTMIN" }, #endif #ifdef disableSIGRTMAX /* initializer element is not constant */ { SIGRTMAX, "RTMAX" }, #endif }; static void list (void) { const struct signal *sig; for (sig = sigtab; sig < sigtab + LENGTH (sigtab); sig++) printf ("%2d\t%s\n", sig->signo, sig->name); exit (EXIT_SUCCESS); } static #ifdef __GNUC__ __attribute__((__unused__)) #endif void fail (const char *where) { fprintf (stderr, "Error parsing arguments: %s\n", where); exit (EXIT_FAILURE); } static int parse_number (const char *text) { char *end; long val; val = strtol (text, &end, 0); if (val >= 0 && (int) val == val && (end == NULL || *end == 0)) return val; return -1; } static int parse_signal (const char *text_orig) { const char *text = text_orig; const struct signal *sig; int retval; retval = parse_number (text); if (retval >= 0) return retval; if (strncasecmp (text, "SIG", 3) == 0) text += 3; for (sig = sigtab; sig < sigtab + LENGTH (sigtab); sig++) if (strcasecmp (sig->name, text) == 0) return sig->signo; fail (text_orig); /* NOTREACHED */ return -1; } static void help (void) { fputs ("\ tgkill -h\n\ tgkill -l\n\ tgkill {-s sigspec | -n sigspec | -sigspec} pid ...\n\ ", stdout); exit (EXIT_SUCCESS); } int main (int argc, char **argv) { char **argp; int signo; if (argc == 2 && strcmp (argv[1], "-h") == 0) help (); if (argc == 2 && strcmp (argv[1], "-l") == 0) list (); if (argc > 3 && (strcmp (argv[1], "-s") == 0 || strcmp (argv[1], "-n") == 0)) { signo = parse_signal (argv[2]); argp = argv + 3; } else if (argc > 2 && argv[1][0] == '-') { signo = parse_signal (argv [1] + 1); argp = argv + 2; } else fail (""); while (argp < argv + argc) { const char *arg = *argp++; int pid; pid = parse_number (arg); if (pid == -1) fail (arg); if (tkill (pid, signo) != 0) perror (arg); } return EXIT_SUCCESS; }