changeset 498:c9aaceccd6bd

Factor out common code between killall/kill and move it to lib/lib.c, plus cleanups on kill.c.
author Rob Landley <rob@landley.net>
date Sun, 26 Feb 2012 13:48:00 -0600
parents da73bb464ce8
children bc4615e2e339
files lib/lib.c lib/lib.h toys/kill.c toys/killall.c
diffstat 4 files changed, 103 insertions(+), 195 deletions(-) [+]
line wrap: on
line diff
--- a/lib/lib.c	Thu Feb 23 22:08:27 2012 -0500
+++ b/lib/lib.c	Sun Feb 26 13:48:00 2012 -0600
@@ -842,3 +842,54 @@
 
     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;
+}
--- a/lib/lib.h	Thu Feb 23 22:08:27 2012 -0500
+++ b/lib/lib.h	Sun Feb 26 13:48:00 2012 -0600
@@ -126,3 +126,8 @@
 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);
--- a/toys/kill.c	Thu Feb 23 22:08:27 2012 -0500
+++ b/toys/kill.c	Sun Feb 26 13:48:00 2012 -0600
@@ -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 @@
 
 #include "toys.h"
 
-#define TT this.kill
-
-typedef struct {
-	int signum;
+DEFINE_GLOBALS(
 	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)
-{
-	int i = 0;
-	for (;;) {
-		if (signals[i].signum == sig)
-			return signals[i].signame;
-
-		if (signals[++i].signum == -1)
-			break;
-	}
-	return 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;
-	}
-	return -1;
-}
-
-static int send_signal(int sig, pid_t pid)
-{
-	if (kill(pid, sig) < 0) {
-		perror("kill");
-		return -1;
-	}
-	return 0;
-}
-
-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");
-}
-
-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;
-	}
-}
-
-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;
-	}
-} 
+#define TT this.kill
 
 void kill_main(void)
 {
-	int signum = 0;
-	int have_signal = 0;
-	char *signame, *tmp;
+	int signum;
+	char *tmp, **args = toys.optargs;
 	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;
-			}
-				
+
+	// list signal(s)
+	if (toys.optflags & 1) {
+		if (*args) {
+			int signum = sig_to_num(*args);
+			char *s = NULL;
+
+			if (signum>=0) s = num_to_sig(signum&127);
+			puts(s ? s : "UNKNOWN");
+		} else sig_to_num(NULL);
+		return;
+	}
+
+	// signal must come before pids, so "kill -9 -1" isn't confusing.
+printf("*args=%s\n", *args);
+
+	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;
+
+		if (!arg || -1 == (signum = sig_to_num(arg)))
+			error_exit("Unknown signal '%s'", arg);
+	} else signum = SIGTERM;
+
+	if (!*args) {
+		toys.exithelp++;
+		error_exit("missing argument");
+	}
+
+	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;
 		}
 	}
 }
--- a/toys/killall.c	Thu Feb 23 22:08:27 2012 -0500
+++ b/toys/killall.c	Sun Feb 26 13:48:00 2012 -0600
@@ -30,44 +30,6 @@
 )
 #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;