svn commit: trunk/busybox: include procps shell

vda at busybox.net vda at busybox.net
Sun Apr 29 23:42:55 UTC 2007


Author: vda
Date: 2007-04-29 16:42:54 -0700 (Sun, 29 Apr 2007)
New Revision: 18532

Log:
ash,kill: use common code for kill applet/builtin

# make bloatcheck
function                                             old     new   delta
evaltreenr                                           644     654     +10
evaltree                                             644     654     +10
parse_conf                                          1440    1444      +4
dpkg_deb_main                                        426     429      +3
ed_main                                             3319    3321      +2
passwd_main                                         2093    2091      -2
kill_main                                            830     826      -4
singlemount                                         4609    4601      -8
find_command                                         962     954      -8
get_lcm                                              123     105     -18
.rodata                                           132243  132147     -96
killcmd                                              449     120    -329
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/7 up/down: 29/-465)          Total: -436 bytes

# size busybox_old busybox_unstripped
   text    data     bss     dec     hex filename
 723901    2940   27504  754345   b82a9 busybox_old
 723457    2940   27504  753901   b80ed busybox_unstripped


Modified:
   trunk/busybox/include/libbb.h
   trunk/busybox/procps/Kbuild
   trunk/busybox/procps/kill.c
   trunk/busybox/shell/ash.c


Changeset:
Modified: trunk/busybox/include/libbb.h
===================================================================
--- trunk/busybox/include/libbb.h	2007-04-29 23:38:12 UTC (rev 18531)
+++ trunk/busybox/include/libbb.h	2007-04-29 23:42:54 UTC (rev 18532)
@@ -636,6 +636,7 @@
 int bb_cat(char** argv);
 int bb_echo(char** argv);
 int bb_test(int argc, char** argv);
+int kill_main(int argc, char **argv);
 #if ENABLE_ROUTE
 void bb_displayroutes(int noresolve, int netstatfmt);
 #endif

Modified: trunk/busybox/procps/Kbuild
===================================================================
--- trunk/busybox/procps/Kbuild	2007-04-29 23:38:12 UTC (rev 18531)
+++ trunk/busybox/procps/Kbuild	2007-04-29 23:42:54 UTC (rev 18532)
@@ -7,6 +7,7 @@
 lib-y:=
 lib-$(CONFIG_FREE)	+= free.o
 lib-$(CONFIG_KILL)	+= kill.o
+lib-$(CONFIG_ASH)	+= kill.o  # used for built-in kill by ash
 lib-$(CONFIG_PIDOF)	+= pidof.o
 lib-$(CONFIG_PS)	+= ps.o
 lib-$(CONFIG_RENICE)	+= renice.o

Modified: trunk/busybox/procps/kill.c
===================================================================
--- trunk/busybox/procps/kill.c	2007-04-29 23:38:12 UTC (rev 18531)
+++ trunk/busybox/procps/kill.c	2007-04-29 23:42:54 UTC (rev 18532)
@@ -10,16 +10,30 @@
 
 #include "busybox.h"
 
+/* Note: kill_main is directly called from shell in order to implement
+ * kill built-in. Shell substitutes job ids with process groups first.
+ *
+ * This brings some complications:
+ *
+ * + we can't use xfunc here
+ * + we can't use applet_name
+ * + we can't use bb_show_usage
+ * (Above doesn't apply for killall[5] cases)
+ *
+ * kill %n gets translated into kill ' -<process group>' by shell (note space!)
+ * This is needed to avoid collision with kill -9 ... syntax
+ */
+
 int kill_main(int argc, char **argv);
 int kill_main(int argc, char **argv)
 {
 	char *arg;
 	pid_t pid;
 	int signo = SIGTERM, errors = 0, quiet = 0;
-	const int killall = (ENABLE_KILLALL && applet_name[4] == 'a'
-	               && (!ENABLE_KILLALL5 || applet_name[7] != '5'));
-	const int killall5 = (ENABLE_KILLALL5 && applet_name[4] == 'a'
-	                  && (!ENABLE_KILLALL || applet_name[7] == '5'));
+	const int killall = (ENABLE_KILLALL && argv[0][4] == 'a'
+	               && (!ENABLE_KILLALL5 || argv[0][7] != '5'));
+	const int killall5 = (ENABLE_KILLALL5 && argv[0][4] == 'a'
+	                  && (!ENABLE_KILLALL || argv[0][7] == '5'));
 
 	/* Parse any options */
 	argc--;
@@ -29,34 +43,38 @@
 		goto do_it_now;
 	}
 
-	/* The -l option, which prints out signal names. */
+	/* The -l option, which prints out signal names.
+	 * Intended usage in shell:
+	 * echo "Died of SIG`kill -l $?`"
+	 * We try to mimic what kill from coreutils-6.8 does */
 	if (arg[1] == 'l' && arg[2] == '\0') {
-		const char *name;
 		if (argc == 1) {
 			/* Print the whole signal list */
-			int col = 0;
 			for (signo = 1; signo < 32; signo++) {
-				name = get_signame(signo);
-				if (isdigit(name[0])) continue;
-				if (col > 66) {
-					puts("");
-					col = 0;
-				}
-				col += printf("%2d) %-6s", signo, name);
+				puts(get_signame(signo));
 			}
-			puts("");
 		} else { /* -l <sig list> */
 			while ((arg = *++argv)) {
 				if (isdigit(arg[0])) {
-					signo = xatoi_u(arg);
-					name = get_signame(signo);
+					signo = bb_strtou(arg, NULL, 10);
+					if (errno) {
+						bb_error_msg("unknown signal '%s'", arg);
+						return EXIT_FAILURE;
+					}
+					/* Exitcodes >= 0x80 are to be treated
+					 * as "killed by signal (exitcode & 0x7f)" */
+					puts(get_signame(signo & 0x7f));
+					/* TODO: 'bad' signal# - coreutils says:
+					 * kill: 127: invalid signal
+					 * we just print "127" instead */
 				} else {
 					signo = get_signum(arg);
-					if (signo < 0)
-						bb_error_msg_and_die("unknown signal '%s'", arg);
-					name = get_signame(signo);
+					if (signo < 0) {
+						bb_error_msg("unknown signal '%s'", arg);
+						return EXIT_FAILURE;
+					}
+					printf("%d\n", signo);
 				}
-				printf("%2d) %s\n", signo, name);
 			}
 		}
 		/* If they specified -l, we are all done */
@@ -74,8 +92,10 @@
 
 	/* -SIG */
 	signo = get_signum(&arg[1]);
-	if (signo < 0)
-		bb_error_msg_and_die("bad signal name '%s'", &arg[1]);
+	if (signo < 0) { /* || signo > MAX_SIGNUM ? */
+		bb_error_msg("bad signal name '%s'", &arg[1]);
+		return EXIT_FAILURE;
+	}
 	arg = *++argv;
 	argc--;
 
@@ -85,10 +105,6 @@
 		pid_t sid;
 		procps_status_t* p = NULL;
 
-// Cannot happen anyway? We don't TERM ourself, we STOP
-//		/* kill(-1, sig) on Linux (at least 2.1.x)
-//		 * might send signal to the calling process too */
-//		signal(SIGTERM, SIG_IGN);
 		/* Now stop all processes */
 		kill(-1, SIGSTOP);
 		/* Find out our own session id */
@@ -104,9 +120,11 @@
 		return 0;
 	}
 
-	/* Pid or name required for kill/killall */
-	if (argc < 1)
-		bb_show_usage();
+	/* Pid or name is required for kill/killall */
+	if (argc < 1) {
+		puts("You need to specify whom to kill");
+		return EXIT_FAILURE;
+	}
 
 	if (killall) {
 		/* Looks like they want to do a killall.  Do that */
@@ -140,15 +158,16 @@
 
 	/* Looks like they want to do a kill. Do that */
 	while (arg) {
-		/* Huh?
-		if (!isdigit(arg[0]) && arg[0] != '-')
-			bb_error_msg_and_die("bad pid '%s'", arg);
-		*/
-		pid = xatou(arg);
-		/* FIXME: better overflow check? */
-		if (kill(pid, signo) != 0) {
-			bb_perror_msg("cannot kill pid %u", (unsigned)pid);
+		/* Support shell 'space' trick */
+		if (arg[0] == ' ')
+			arg++;
+		pid = bb_strtoi(arg, NULL, 10);
+		if (errno) {
+			bb_error_msg("bad pid '%s'", arg);
 			errors++;
+		} else if (kill(pid, signo) != 0) {
+			bb_perror_msg("cannot kill pid %d", (int)pid);
+			errors++;
 		}
 		arg = *++argv;
 	}

Modified: trunk/busybox/shell/ash.c
===================================================================
--- trunk/busybox/shell/ash.c	2007-04-29 23:38:12 UTC (rev 18531)
+++ trunk/busybox/shell/ash.c	2007-04-29 23:42:54 UTC (rev 18532)
@@ -3519,91 +3519,22 @@
 static int
 killcmd(int argc, char **argv)
 {
-	int signo = -1;
-	int list = 0;
-	int i;
-	pid_t pid;
-	struct job *jp;
-
-	if (argc <= 1) {
- usage:
-		ash_msg_and_raise_error(
-"usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n"
-"kill -l [exitstatus]"
-		);
-	}
-
-	if (**++argv == '-') {
-		signo = get_signum(*argv + 1);
-		if (signo < 0) {
-			int c;
-
-			while ((c = nextopt("ls:")) != '\0') {
-				switch (c) {
-				default:
-#if DEBUG
-					abort();
-#endif
-				case 'l':
-					list = 1;
-					break;
-				case 's':
-					signo = get_signum(optionarg);
-					if (signo < 0) {
-						ash_msg_and_raise_error(
-							"invalid signal number or name: %s",
-							optionarg
-						);
-					}
-					break;
-				}
+	if (argv[1] && strcmp(argv[1], "-l") != 0) {
+		int i = 1;
+		do {
+			if (argv[i][0] == '%') {
+				struct job *jp = getjob(argv[i], 0);
+				unsigned pid = jp->ps[0].pid;
+				/* Enough space for ' -NNN<nul>' */
+				argv[i] = alloca(sizeof(int)*3 + 3);
+				/* kill_main has matching code to expect
+				 * leading space. Needed to not confuse
+				 * negative pids with "kill -SIGNAL_NO" syntax */
+				sprintf(argv[i], " -%u", pid);
 			}
-			argv = argptr;
-		} else
-			argv++;
+		} while (argv[++i]);
 	}
-
-	if (!list && signo < 0)
-		signo = SIGTERM;
-
-	if ((signo < 0 || !*argv) ^ list) {
-		goto usage;
-	}
-
-	if (list) {
-		const char *name;
-
-		if (!*argv) {
-			for (i = 1; i < NSIG; i++) {
-				name = get_signame(i);
-				if (!isdigit(*name))
-					out1fmt(snlfmt, name);
-			}
-			return 0;
-		}
-		name = get_signame(signo);
-		if (!isdigit(*name))
-			ash_msg_and_raise_error("invalid signal number or exit status: %s", *argptr);
-		out1fmt(snlfmt, name);
-		return 0;
-	}
-
-	i = 0;
-	do {
-		if (**argv == '%') {
-			jp = getjob(*argv, 0);
-			pid = -jp->ps[0].pid;
-		} else {
-			pid = **argv == '-' ?
-				-number(*argv + 1) : number(*argv);
-		}
-		if (kill(pid, signo) != 0) {
-			ash_msg("(%d) - %m", pid);
-			i = 1;
-		}
-	} while (*++argv);
-
-	return i;
+	return kill_main(argc, argv);
 }
 
 static void
@@ -3642,7 +3573,8 @@
 		if (WIFSTOPPED(ps->status)) {
 			ps->status = -1;
 		}
-	} while (ps++, --i);
+		ps++;
+	} while (--i);
  out:
 	status = (mode == FORK_FG) ? waitforjob(jp) : 0;
 	INT_ON;
@@ -5070,8 +5002,9 @@
 static char *
 _rmescapes(char *str, int flag)
 {
+	static const char qchars[] = { CTLESC, CTLQUOTEMARK, '\0' };
+
 	char *p, *q, *r;
-	static const char qchars[] = { CTLESC, CTLQUOTEMARK, 0 };
 	unsigned inquotes;
 	int notescaped;
 	int globbing;
@@ -11117,13 +11050,7 @@
 		return;
 	}
 
-#if ENABLE_FEATURE_SH_STANDALONE
-	if (find_applet_by_name(name)) {
-		entry->cmdtype = CMDNORMAL;
-		entry->u.index = -1;
-		return;
-	}
-#endif
+/* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */
 
 	updatetbl = (path == pathval());
 	if (!updatetbl) {
@@ -11173,6 +11100,14 @@
 		}
 	}
 
+#if ENABLE_FEATURE_SH_STANDALONE
+	if (find_applet_by_name(name)) {
+		entry->cmdtype = CMDNORMAL;
+		entry->u.index = -1;
+		return;
+	}
+#endif
+
 	/* We have to search path. */
 	prev = -1;              /* where to start */
 	if (cmdp && cmdp->rehash) {     /* doing a rehash */




More information about the busybox-cvs mailing list