|  | #include <stdio.h> | 
|  | #include <stdlib.h> | 
|  | #include <errno.h> | 
|  |  | 
|  | #include <sys/types.h> | 
|  | #include <signal.h> | 
|  |  | 
|  | static struct { | 
|  | unsigned int number; | 
|  | char *name; | 
|  | } signals[] = { | 
|  | #define _SIG(name) {SIG##name, #name} | 
|  | /* Single Unix Specification signals */ | 
|  | _SIG(ABRT), | 
|  | _SIG(ALRM), | 
|  | _SIG(FPE), | 
|  | _SIG(HUP), | 
|  | _SIG(ILL), | 
|  | _SIG(INT), | 
|  | _SIG(KILL), | 
|  | _SIG(PIPE), | 
|  | _SIG(QUIT), | 
|  | _SIG(SEGV), | 
|  | _SIG(TERM), | 
|  | _SIG(USR1), | 
|  | _SIG(USR2), | 
|  | _SIG(CHLD), | 
|  | _SIG(CONT), | 
|  | _SIG(STOP), | 
|  | _SIG(TSTP), | 
|  | _SIG(TTIN), | 
|  | _SIG(TTOU), | 
|  | _SIG(BUS), | 
|  | _SIG(POLL), | 
|  | _SIG(PROF), | 
|  | _SIG(SYS), | 
|  | _SIG(TRAP), | 
|  | _SIG(URG), | 
|  | _SIG(VTALRM), | 
|  | _SIG(XCPU), | 
|  | _SIG(XFSZ), | 
|  | /* non-SUS signals */ | 
|  | _SIG(IO), | 
|  | _SIG(PWR), | 
|  | #ifdef SIGSTKFLT | 
|  | _SIG(STKFLT), | 
|  | #endif | 
|  | _SIG(WINCH), | 
|  | #undef _SIG | 
|  | }; | 
|  |  | 
|  | /* To indicate a matching signal was not found */ | 
|  | static const unsigned int SENTINEL = (unsigned int) -1; | 
|  |  | 
|  | void list_signals() | 
|  | { | 
|  | unsigned int sorted_signals[_NSIG]; | 
|  | unsigned int i; | 
|  | unsigned int num; | 
|  |  | 
|  | memset(sorted_signals, SENTINEL, sizeof(sorted_signals)); | 
|  |  | 
|  | // Sort the signals | 
|  | for (i = 0; i < sizeof(signals)/sizeof(signals[0]); i++) { | 
|  | sorted_signals[signals[i].number] = i; | 
|  | } | 
|  |  | 
|  | num = 0; | 
|  | for (i = 1; i < _NSIG; i++) { | 
|  | unsigned int index = sorted_signals[i]; | 
|  | if (index == SENTINEL) { | 
|  | continue; | 
|  | } | 
|  |  | 
|  | fprintf(stderr, "%2d) SIG%-9s ", i, signals[index].name); | 
|  |  | 
|  | if ((num++ % 4) == 3) { | 
|  | fprintf(stderr, "\n"); | 
|  | } | 
|  | } | 
|  |  | 
|  | if ((num % 4) == 3) { | 
|  | fprintf(stderr, "\n"); | 
|  | } | 
|  | } | 
|  |  | 
|  | unsigned int name_to_signal(const char* name) | 
|  | { | 
|  | unsigned int i; | 
|  |  | 
|  | for (i = 1; i < sizeof(signals) / sizeof(signals[0]); i++) { | 
|  | if (!strcasecmp(name, signals[i].name)) { | 
|  | return signals[i].number; | 
|  | } | 
|  | } | 
|  |  | 
|  | return SENTINEL; | 
|  | } | 
|  |  | 
|  | int kill_main(int argc, char **argv) | 
|  | { | 
|  | unsigned int sig = SIGTERM; | 
|  | int result = 0; | 
|  |  | 
|  | argc--; | 
|  | argv++; | 
|  |  | 
|  | if (argc >= 1 && argv[0][0] == '-') { | 
|  | char *endptr; | 
|  | size_t arg_len = strlen(argv[0]); | 
|  | if (arg_len < 2) { | 
|  | fprintf(stderr, "invalid argument: -\n"); | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | char* arg = argv[0] + 1; | 
|  | if (arg_len == 2 && *arg == 'l') { | 
|  | list_signals(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | sig = strtol(arg, &endptr, 10); | 
|  | if (*endptr != '\0') { | 
|  | sig = name_to_signal(arg); | 
|  | if (sig == SENTINEL) { | 
|  | fprintf(stderr, "invalid signal name: %s\n", arg); | 
|  | return -1; | 
|  | } | 
|  | } | 
|  |  | 
|  | argc--; | 
|  | argv++; | 
|  | } | 
|  |  | 
|  | while(argc > 0){ | 
|  | int pid = atoi(argv[0]); | 
|  | int err = kill(pid, sig); | 
|  | if (err < 0) { | 
|  | result = err; | 
|  | fprintf(stderr, "could not kill pid %d: %s\n", pid, strerror(errno)); | 
|  | } | 
|  |  | 
|  | argc--; | 
|  | argv++; | 
|  | } | 
|  |  | 
|  | return result; | 
|  | } |