1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4
5#include <sys/types.h>
6#include <signal.h>
7
8static struct {
9    unsigned int number;
10    char *name;
11} signals[] = {
12#define _SIG(name) {SIG##name, #name}
13    /* Single Unix Specification signals */
14    _SIG(ABRT),
15    _SIG(ALRM),
16    _SIG(FPE),
17    _SIG(HUP),
18    _SIG(ILL),
19    _SIG(INT),
20    _SIG(KILL),
21    _SIG(PIPE),
22    _SIG(QUIT),
23    _SIG(SEGV),
24    _SIG(TERM),
25    _SIG(USR1),
26    _SIG(USR2),
27    _SIG(CHLD),
28    _SIG(CONT),
29    _SIG(STOP),
30    _SIG(TSTP),
31    _SIG(TTIN),
32    _SIG(TTOU),
33    _SIG(BUS),
34    _SIG(POLL),
35    _SIG(PROF),
36    _SIG(SYS),
37    _SIG(TRAP),
38    _SIG(URG),
39    _SIG(VTALRM),
40    _SIG(XCPU),
41    _SIG(XFSZ),
42    /* non-SUS signals */
43    _SIG(IO),
44    _SIG(PWR),
45#ifdef SIGSTKFLT
46    _SIG(STKFLT),
47#endif
48    _SIG(WINCH),
49#undef _SIG
50};
51
52/* To indicate a matching signal was not found */
53static const unsigned int SENTINEL = (unsigned int) -1;
54
55void list_signals()
56{
57    unsigned int sorted_signals[_NSIG];
58    unsigned int i;
59    unsigned int num;
60
61    memset(sorted_signals, SENTINEL, sizeof(sorted_signals));
62
63    // Sort the signals
64    for (i = 0; i < sizeof(signals)/sizeof(signals[0]); i++) {
65        sorted_signals[signals[i].number] = i;
66    }
67
68    num = 0;
69    for (i = 1; i < _NSIG; i++) {
70        unsigned int index = sorted_signals[i];
71        if (index == SENTINEL) {
72            continue;
73        }
74
75        fprintf(stderr, "%2d) SIG%-9s ", i, signals[index].name);
76
77        if ((num++ % 4) == 3) {
78            fprintf(stderr, "\n");
79        }
80    }
81
82    if ((num % 4) == 3) {
83        fprintf(stderr, "\n");
84    }
85}
86
87unsigned int name_to_signal(const char* name)
88{
89    unsigned int i;
90
91    for (i = 1; i < sizeof(signals) / sizeof(signals[0]); i++) {
92        if (!strcasecmp(name, signals[i].name)) {
93            return signals[i].number;
94        }
95    }
96
97    return SENTINEL;
98}
99
100int kill_main(int argc, char **argv)
101{
102    unsigned int sig = SIGTERM;
103    int result = 0;
104
105    argc--;
106    argv++;
107
108    if (argc >= 1 && argv[0][0] == '-') {
109        char *endptr;
110        size_t arg_len = strlen(argv[0]);
111        if (arg_len < 2) {
112            fprintf(stderr, "invalid argument: -\n");
113            return -1;
114        }
115
116        char* arg = argv[0] + 1;
117        if (arg_len == 2 && *arg == 'l') {
118            list_signals();
119            return 0;
120        }
121
122        sig = strtol(arg, &endptr, 10);
123        if (*endptr != '\0') {
124            sig = name_to_signal(arg);
125            if (sig == SENTINEL) {
126                fprintf(stderr, "invalid signal name: %s\n", arg);
127                return -1;
128            }
129        }
130
131        argc--;
132        argv++;
133    }
134
135    while(argc > 0){
136        int pid = atoi(argv[0]);
137        int err = kill(pid, sig);
138        if (err < 0) {
139            result = err;
140            fprintf(stderr, "could not kill pid %d: %s\n", pid, strerror(errno));
141        }
142
143        argc--;
144        argv++;
145    }
146
147    return result;
148}
149