aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2012-02-26 13:48:00 -0600
committerRob Landley <rob@landley.net>2012-02-26 13:48:00 -0600
commit2dd50adc460e63c57eddb696f908dd6b1abfd723 (patch)
treefe0a05588e4d8c2485cdba1113b213442693d92d
parentbef57ed266cfad82114b5bb16052571035e9fff1 (diff)
downloadtoybox-2dd50adc460e63c57eddb696f908dd6b1abfd723.tar.gz
Factor out common code between killall/kill and move it to lib/lib.c, plus cleanups on kill.c.
-rw-r--r--lib/lib.c51
-rw-r--r--lib/lib.h5
-rw-r--r--toys/kill.c192
-rw-r--r--toys/killall.c38
4 files changed, 97 insertions, 189 deletions
diff --git a/lib/lib.c b/lib/lib.c
index ba6d132d..3f04cb61 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -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;
+}
diff --git a/lib/lib.h b/lib/lib.h
index dd8a3f17..a6959730 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -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;