| #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; | |
| } |