diff options
-rw-r--r-- | lib/lib.c | 51 | ||||
-rw-r--r-- | lib/lib.h | 5 | ||||
-rw-r--r-- | toys/kill.c | 192 | ||||
-rw-r--r-- | toys/killall.c | 38 |
4 files changed, 97 insertions, 189 deletions
@@ -842,3 +842,54 @@ void for_each_pid_with_name_in(char **names, void (*callback)(pid_t pid)) closedir(dp); } + +struct signame { + int num; + char *name; +}; + +// Signals required by POSIX 2008: +// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html + +#define SIGNIFY(x) {SIG##x, #x} + +static struct signame signames[] = { + SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS), SIGNIFY(CHLD), SIGNIFY(CONT), + SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL), + SIGNIFY(PIPE), SIGNIFY(QUIT), SIGNIFY(SEGV), SIGNIFY(STOP), SIGNIFY(TERM), + SIGNIFY(TSTP), SIGNIFY(TTIN), SIGNIFY(TTOU), SIGNIFY(USR1), SIGNIFY(USR2), + SIGNIFY(SYS), SIGNIFY(TRAP), SIGNIFY(URG), SIGNIFY(VTALRM), SIGNIFY(XCPU), + SIGNIFY(XFSZ) +}; + +// not in posix: SIGNIFY(STKFLT), SIGNIFY(WINCH), SIGNIFY(IO), SIGNIFY(PWR) +// obsolete: SIGNIFY(PROF) SIGNIFY(POLL) + +// Convert name to signal number. If name == NULL print names. +int sig_to_num(char *pidstr) +{ + int i; + + if (pidstr) { + char *s; + i = strtol(pidstr, &s, 10); + if (!*s) return i; + + if (!strncasecmp(pidstr, "sig", 3)) pidstr+=3; + } + for (i = 0; i < sizeof(signames)/sizeof(struct signame); i++) + if (!pidstr) xputs(signames[i].name); + else if (!strcasecmp(pidstr, signames[i].name)) + return signames[i].num; + + return -1; +} + +char *num_to_sig(int sig) +{ + int i; + + for (i=0; i<sizeof(signames)/sizeof(struct signame); i++) + if (signames[i].num == sig) return signames[i].name; + return NULL; +} @@ -126,3 +126,8 @@ struct mtab_list { struct mtab_list *getmountlist(int die); void bunzipStream(int src_fd, int dst_fd); + +// signal + +int sig_to_num(char *pidstr); +char *num_to_sig(int sig); diff --git a/toys/kill.c b/toys/kill.c index 10c784b2..d9beda33 100644 --- a/toys/kill.c +++ b/toys/kill.c @@ -6,13 +6,13 @@ * * See http://opengroup.org/onlinepubs/9699919799/utilities/kill.html -USE_KILL(NEWTOY(kill, NULL, TOYFLAG_BIN)) +USE_KILL(NEWTOY(kill, "?s:l", TOYFLAG_BIN)) config KILL bool "kill" default y help - usage: kill [-l signal_number | -s signal_name | -signal_name | -signal_number] pid... + usage: kill [-l [SIGNAL] | -s SIGNAL | -SIGNAL] pid... Send a signal to a process @@ -20,167 +20,57 @@ config KILL #include "toys.h" +DEFINE_GLOBALS( + char *signame; +) + #define TT this.kill -typedef struct { - int signum; - char *signame; -} signals_t; - -const signals_t signals[] = { - { 1, "HUP"}, - { 2, "INT"}, - { 3, "QUIT"}, - { 4, "ILL"}, - { 5, "TRAP"}, - { 6, "ABRT"}, - { 7, "BUS"}, - { 8, "FPE"}, - { 9, "KILL"}, - { 10, "USR1"}, - { 11, "SEGV"}, - { 12, "USR2"}, - { 13, "PIPE"}, - { 14, "ALRM"}, - { 15, "TERM"}, - { 16, "STKFLT"}, - { 17, "CHLD"}, - { 18, "CONT"}, - { 19, "STOP"}, - { 20, "TSTP"}, - { 21, "TTIN"}, - { 22, "TTOU"}, - { 23, "URG"}, - { 24, "XCPU"}, - { 25, "XFSZ"}, - { 26, "VTALRM"}, - { 27, "PROF"}, - { 28, "WINCH"}, - { 29, "POLL"}, - { 30, "PWR"}, - { 31, "SYS"}, - /* terminator */ - { -1, NULL}, -}; - -static char* signum_to_signame(int sig) +void kill_main(void) { - int i = 0; - for (;;) { - if (signals[i].signum == sig) - return signals[i].signame; + int signum; + char *tmp, **args = toys.optargs; + pid_t pid; - if (signals[++i].signum == -1) - break; - } - return NULL; -} + // list signal(s) + if (toys.optflags & 1) { + if (*args) { + int signum = sig_to_num(*args); + char *s = NULL; -static int signame_to_signum(char *signame) -{ - int i=0; - for (;;) { - if (!strcmp(signals[i].signame, signame)) - return signals[i].signum; - if (signals[++i].signum == -1) - break; + if (signum>=0) s = num_to_sig(signum&127); + puts(s ? s : "UNKNOWN"); + } else sig_to_num(NULL); + return; } - return -1; -} -static int send_signal(int sig, pid_t pid) -{ - if (kill(pid, sig) < 0) { - perror("kill"); - return -1; - } - return 0; -} + // signal must come before pids, so "kill -9 -1" isn't confusing. +printf("*args=%s\n", *args); -static void list_all_signals() -{ - int i = 0; - for (;;) { - printf("%s ", signals[i++].signame); - if (i % 16 == 0) - printf("\n"); - if (signals[i].signum == -1) - break; - } - printf("\n"); -} + if (!TT.signame && *args && **args=='-') TT.signame=*(args++)+1; +printf("TT.signame=%s\n", TT.signame); + if (TT.signame) { + char *arg; + int i = strtol(TT.signame, &arg, 10); + if (!*arg) arg = num_to_sig(i); + else arg = TT.signame; -static int list_signal(int signum) -{ - char *signam = signum_to_signame(signum); - if (signam) { - printf("%s\n", signam); - return 0; - } else { - printf("Unknown signal %d\n", signum); - return -1; - } -} + if (!arg || -1 == (signum = sig_to_num(arg))) + error_exit("Unknown signal '%s'", arg); + } else signum = SIGTERM; -static int list_signal_by_name(char *signame) -{ - int signum = signame_to_signum(signame); - if (signum > 0) { - printf("%d\n", signum); - return 0; - } else { - printf("Unknown signal %s\n", signame); - return -1; + if (!*args) { + toys.exithelp++; + error_exit("missing argument"); } -} -void kill_main(void) -{ - int signum = 0; - int have_signal = 0; - char *signame, *tmp; - pid_t pid; - while (*toys.optargs) { - char *arg = *(toys.optargs++); - if (arg[0] == '-' && !have_signal) { - arg++; - switch(arg[0]) { - case 'l': - if (!*toys.optargs) - list_all_signals(); - else { - signum = strtol(*(toys.optargs), &signame, 10); - if (signame == *(toys.optargs)) - list_signal_by_name(signame); - else - list_signal(signum); - } - return; - case 's': - arg = *(toys.optargs++); - default: - signum = strtol(arg, &signame, 10); - if (signame == arg) { - signum = signame_to_signum(signame); - if (signum < 0) { - toys.exitval = EXIT_FAILURE; - return; - } - } - have_signal = 1; - } - } else { - /* pids */ - pid = strtol(arg, &tmp, 10); - if (tmp == arg) { - toys.exitval = EXIT_FAILURE; - return; - } - if (send_signal(signum, pid) < 0) { - toys.exitval = EXIT_FAILURE; - return; - } - + while (*args) { + char *arg = *(args++); + + pid = strtol(arg, &tmp, 10); + if (*tmp || kill(pid, signum) < 0) { + error_msg("unknown pid '%s'", arg); + toys.exitval = EXIT_FAILURE; } } } diff --git a/toys/killall.c b/toys/killall.c index 44379833..b4e06944 100644 --- a/toys/killall.c +++ b/toys/killall.c @@ -30,44 +30,6 @@ DEFINE_GLOBALS( ) #define TT this.killall -struct signame { - int num; - char *name; -}; - -// Signals required by POSIX 2008: -// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - -#define SIGNIFY(x) {SIG##x, #x} - -static struct signame signames[] = { - SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS), SIGNIFY(CHLD), SIGNIFY(CONT), - SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL), - SIGNIFY(PIPE), SIGNIFY(QUIT), SIGNIFY(SEGV), SIGNIFY(STOP), SIGNIFY(TERM), - SIGNIFY(TSTP), SIGNIFY(TTIN), SIGNIFY(TTOU), SIGNIFY(USR1), SIGNIFY(USR2), - SIGNIFY(SYS), SIGNIFY(TRAP), SIGNIFY(URG), SIGNIFY(VTALRM), SIGNIFY(XCPU), - SIGNIFY(XFSZ) -}; - -// SIGNIFY(STKFLT), SIGNIFY(WINCH), SIGNIFY(IO), SIGNIFY(PWR) - -// Convert name to signal number. If name == NULL print names. -static int sig_to_num(char *pidstr) -{ - int i; - - if (pidstr) { - if (isdigit(*pidstr)) return atol(pidstr); - if (!strncasecmp(pidstr, "sig", 3)) pidstr+=3; - } - for (i = 0; i < sizeof(signames)/sizeof(struct signame); i++) - if (!pidstr) xputs(signames[i].name); - else if (!strcasecmp(pidstr, signames[i].name)) - return signames[i].num; - - return -1; -} - static void kill_process(pid_t pid) { int ret; |