svn commit: trunk/busybox: include libbb procps

vda at busybox.net vda at busybox.net
Sat Sep 29 22:26:01 UTC 2007


Author: vda
Date: 2007-09-29 15:26:01 -0700 (Sat, 29 Sep 2007)
New Revision: 20131

Log:
pgrep,pkill: new applets by Loic Grenie <loic.grenie at gmail.com>



Added:
   trunk/busybox/procps/pgrep.c

Modified:
   trunk/busybox/include/applets.h
   trunk/busybox/include/libbb.h
   trunk/busybox/include/usage.h
   trunk/busybox/libbb/procps.c
   trunk/busybox/libbb/u_signal_names.c
   trunk/busybox/procps/Config.in
   trunk/busybox/procps/Kbuild
   trunk/busybox/procps/kill.c


Changeset:
Modified: trunk/busybox/include/applets.h
===================================================================
--- trunk/busybox/include/applets.h	2007-09-29 21:22:23 UTC (rev 20130)
+++ trunk/busybox/include/applets.h	2007-09-29 22:26:01 UTC (rev 20131)
@@ -251,11 +251,13 @@
 USE_OPENVT(APPLET(openvt, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
 USE_PASSWD(APPLET(passwd, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS))
 USE_PATCH(APPLET(patch, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
+USE_PGREP(APPLET(pgrep, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
 USE_PIDOF(APPLET(pidof, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_PING(APPLET(ping, _BB_DIR_BIN, _BB_SUID_MAYBE))
 USE_PING6(APPLET(ping6, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_PIPE_PROGRESS(APPLET_NOUSAGE(pipe_progress, pipe_progress, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_PIVOT_ROOT(APPLET(pivot_root, _BB_DIR_SBIN, _BB_SUID_NEVER))
+USE_PKILL(APPLET_ODDNAME(pkill, pgrep, _BB_DIR_USR_BIN, _BB_SUID_NEVER, pkill))
 USE_HALT(APPLET_ODDNAME(poweroff, halt, _BB_DIR_SBIN, _BB_SUID_NEVER, poweroff))
 USE_PRINTENV(APPLET(printenv, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_PRINTF(APPLET(printf, _BB_DIR_USR_BIN, _BB_SUID_NEVER))

Modified: trunk/busybox/include/libbb.h
===================================================================
--- trunk/busybox/include/libbb.h	2007-09-29 21:22:23 UTC (rev 20130)
+++ trunk/busybox/include/libbb.h	2007-09-29 22:26:01 UTC (rev 20131)
@@ -787,6 +787,7 @@
 
 int get_signum(const char *name);
 const char *get_signame(int number);
+void print_signames_and_exit(void) ATTRIBUTE_NORETURN;
 
 char *bb_simplify_path(const char *path);
 
@@ -973,7 +974,8 @@
 	PSSCAN_UTIME    = 1 << 13,
 	PSSCAN_TTY      = 1 << 14,
 	PSSCAN_SMAPS	= (1 << 15) * ENABLE_FEATURE_TOPMEM,
-	USE_SELINUX(PSSCAN_CONTEXT = 1 << 16,)
+	PSSCAN_ARGVN    = (1 << 16) * (ENABLE_PGREP | ENABLE_PKILL),
+	USE_SELINUX(PSSCAN_CONTEXT = 1 << 17,)
 	/* These are all retrieved from proc/NN/stat in one go: */
 	PSSCAN_STAT     = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
 	                | PSSCAN_COMM | PSSCAN_STATE

Modified: trunk/busybox/include/usage.h
===================================================================
--- trunk/busybox/include/usage.h	2007-09-29 21:22:23 UTC (rev 20130)
+++ trunk/busybox/include/usage.h	2007-09-29 22:26:01 UTC (rev 20131)
@@ -2558,6 +2558,18 @@
        "$ patch -p1 < example.diff\n" \
        "$ patch -p0 -i example.diff"
 
+#define pgrep_trivial_usage \
+       "[-flnovx] pattern"
+#define pgrep_full_usage \
+       "Display process(es) selected by regex pattern" \
+       "\n\nOptions:\n" \
+       "	-l	Show command name too\n" \
+       "	-f	Match against entire command line\n" \
+       "	-n	Signal the newest process only\n" \
+       "	-o	Signal the oldest process only\n" \
+       "	-v	Negate the matching\n" \
+       "	-x	Match whole name (not substring)"
+
 #if (ENABLE_FEATURE_PIDOF_SINGLE || ENABLE_FEATURE_PIDOF_OMIT)
 #define USAGE_PIDOF "Options:"
 #else
@@ -2640,6 +2652,18 @@
        "Move the current root file system to PUT_OLD and make NEW_ROOT\n" \
        "the new root file system"
 
+#define pkill_trivial_usage \
+       "[-l] | [-fnovx] [-signal] pattern"
+#define pkill_full_usage \
+       "Send a signal to process(es) selected by regex pattern" \
+       "\n\nOptions:\n" \
+       "	-l	List all signals\n" \
+       "	-f	Match against entire command line\n" \
+       "	-n	Signal the newest process only\n" \
+       "	-o	Signal the oldest process only\n" \
+       "	-v	Negate the matching\n" \
+       "	-x	Match whole name (not substring)"
+
 #define poweroff_trivial_usage \
        "[-d delay] [-n] [-f]"
 #define poweroff_full_usage \

Modified: trunk/busybox/libbb/procps.c
===================================================================
--- trunk/busybox/libbb/procps.c	2007-09-29 21:22:23 UTC (rev 20130)
+++ trunk/busybox/libbb/procps.c	2007-09-29 22:26:01 UTC (rev 20131)
@@ -375,13 +375,22 @@
 			}
 		}
 #else
-		if (flags & PSSCAN_ARGV0) {
+		if (flags & *PSSCAN_ARGV0|PSSCAN_ARGVN)) {
 			free(sp->argv0);
 			sp->argv0 = NULL;
 			strcpy(filename_tail, "/cmdline");
 			n = read_to_buf(filename, buf);
 			if (n <= 0)
 				break;
+#if ENABLE_PGREP || ENABLE_PKILL
+			if (flags & PSSCAN_ARGVN) {
+				do {
+					n--;
+					if (buf[n] == '\0')
+						buf[n] = ' ';
+				} while (n);
+			}
+#endif
 			sp->argv0 = xstrdup(buf);
 		}
 #endif

Modified: trunk/busybox/libbb/u_signal_names.c
===================================================================
--- trunk/busybox/libbb/u_signal_names.c	2007-09-29 21:22:23 UTC (rev 20130)
+++ trunk/busybox/libbb/u_signal_names.c	2007-09-29 22:26:01 UTC (rev 20131)
@@ -159,3 +159,18 @@
 
 	return itoa(number);
 }
+
+
+// Print the whole signal list
+
+void print_signames_and_exit(void)
+{
+	int signo;
+
+	for (signo = 1; signo < ARRAY_SIZE(signals); signo++) {
+		const char *name = signals[signo];
+		if (name[0])
+			puts(name);
+	}
+	exit(EXIT_SUCCESS);
+}

Modified: trunk/busybox/procps/Config.in
===================================================================
--- trunk/busybox/procps/Config.in	2007-09-29 21:22:23 UTC (rev 20130)
+++ trunk/busybox/procps/Config.in	2007-09-29 22:26:01 UTC (rev 20131)
@@ -49,6 +49,12 @@
 	help
 	  Prints selected system stats continuously, one line per update.
 
+config PGREP
+	bool "pgrep"
+	default n
+	help
+	  Look for processes by name.
+
 config PIDOF
 	bool "pidof"
 	default n
@@ -72,6 +78,12 @@
 	  The special pid %PPID can be used to name the parent process
 	  of the pidof, in other words the calling shell or shell script.
 
+config PKILL
+	bool "pkill"
+	default n
+	help
+	  Send signals to processes by name.
+
 config PS
 	bool "ps"
 	default n

Modified: trunk/busybox/procps/Kbuild
===================================================================
--- trunk/busybox/procps/Kbuild	2007-09-29 21:22:23 UTC (rev 20130)
+++ trunk/busybox/procps/Kbuild	2007-09-29 22:26:01 UTC (rev 20131)
@@ -10,6 +10,8 @@
 lib-$(CONFIG_KILL)	+= kill.o
 lib-$(CONFIG_ASH)	+= kill.o  # used for built-in kill by ash
 lib-$(CONFIG_NMETER)    += nmeter.o
+lib-$(CONFIG_PGREP)	+= pgrep.o
+lib-$(CONFIG_PKILL)	+= pgrep.o
 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-09-29 21:22:23 UTC (rev 20130)
+++ trunk/busybox/procps/kill.c	2007-09-29 22:26:01 UTC (rev 20131)
@@ -58,33 +58,29 @@
 	if (arg[1] == 'l' && arg[2] == '\0') {
 		if (argc == 1) {
 			/* Print the whole signal list */
-			for (signo = 1; signo < 32; signo++) {
-				const char *name = get_signame(signo);
-				if (!isdigit(name[0]))
-					puts(name);
-			}
-		} else { /* -l <sig list> */
-			while ((arg = *++argv)) {
-				if (isdigit(arg[0])) {
-					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("unknown signal '%s'", arg);
-						return EXIT_FAILURE;
-					}
-					printf("%d\n", signo);
+			print_signames_and_exit();
+		}
+		/* -l <sig list> */
+		while ((arg = *++argv)) {
+			if (isdigit(arg[0])) {
+				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("unknown signal '%s'", arg);
+					return EXIT_FAILURE;
+				}
+				printf("%d\n", signo);
 			}
 		}
 		/* If they specified -l, we are all done */

Added: trunk/busybox/procps/pgrep.c
===================================================================
--- trunk/busybox/procps/pgrep.c	                        (rev 0)
+++ trunk/busybox/procps/pgrep.c	2007-09-29 22:26:01 UTC (rev 20131)
@@ -0,0 +1,136 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini pgrep/pkill implementation for busybox
+ *
+ * Copyright (C) 2007 Loic Grenie <loic.grenie at gmail.com>
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ */
+
+#include <getopt.h>
+
+#include "libbb.h"
+#include "xregex.h"
+
+/* Idea taken from kill.c */
+#define pgrep (ENABLE_PGREP && applet_name[1] == 'g')
+#define pkill (ENABLE_PKILL && applet_name[1] == 'k')
+
+enum {
+	/* "vlfxon" */
+	PGREPOPTBIT_V = 0, /* must be first, we need OPT_INVERT = 0/1 */
+	PGREPOPTBIT_L,
+	PGREPOPTBIT_F,
+	PGREPOPTBIT_X,
+	PGREPOPTBIT_O,
+	PGREPOPTBIT_N,
+};
+
+#define OPT_INVERT	(opt & (1 << PGREPOPTBIT_V))
+#define OPT_LIST	(opt & (1 << PGREPOPTBIT_L))
+#define OPT_FULL	(opt & (1 << PGREPOPTBIT_F))
+#define OPT_ANCHOR	(opt & (1 << PGREPOPTBIT_X))
+#define OPT_FIRST	(opt & (1 << PGREPOPTBIT_O))
+#define OPT_LAST	(opt & (1 << PGREPOPTBIT_N))
+
+static void act(unsigned pid, char *cmd, int signo, unsigned opt)
+{
+	if (pgrep) {
+		if (OPT_LIST)
+			printf("%d %s\n", pid, cmd);
+		else
+			printf("%d\n", pid);
+	} else
+		kill(pid, signo);
+}
+
+int pgrep_main(int argc, char **argv);
+int pgrep_main(int argc, char **argv)
+{
+	unsigned pid = getpid();
+	int signo = SIGTERM;
+	unsigned opt;
+	int scan_mask = PSSCAN_COMM;
+	char *first_arg;
+	int first_arg_idx;
+	int matched_pid;
+	char *cmd_last;
+	procps_status_t *proc;
+	/* These are initialized to 0 */
+	struct {
+		regex_t re_buffer;
+		regmatch_t re_match[1];
+	} Z;
+#define re_buffer (Z.re_buffer)
+#define re_match  (Z.re_match )
+
+	memset(&Z, 0, sizeof(Z));
+
+	/* We must avoid interpreting -NUM (signal num) as an option */
+	first_arg_idx = 1;
+	while (1) {
+		first_arg = argv[first_arg_idx];
+		if (!first_arg)
+			break;
+		if (first_arg[0] != '-' || first_arg[1] < 'a' || first_arg[1] > 'z') {
+			argv[first_arg_idx] = NULL;
+			break;
+		}
+		first_arg_idx++;
+	}
+	opt = getopt32(argv, "vlfxon");
+	argv[first_arg_idx] = first_arg;
+
+	argv += optind;
+	//argc -= optind; - unused anyway
+	if (OPT_FULL)
+		scan_mask |= PSSCAN_ARGVN;
+
+	if (pkill) {
+		if (OPT_LIST) /* -l: print the whole signal list */
+			print_signames_and_exit();
+		if (first_arg && first_arg[0] == '-') {
+			signo = get_signum(&first_arg[1]);
+			if (signo < 0) /* || signo > MAX_SIGNUM ? */
+				bb_error_msg_and_die("bad signal name '%s'", &first_arg[1]);
+			argv++;
+		}
+	}
+
+	/* One pattern is required */
+	if (!argv[0] || argv[1])
+		bb_show_usage();
+
+	xregcomp(&re_buffer, argv[0], 0);
+	matched_pid = 0;
+	cmd_last = NULL;
+	proc = NULL;
+	while ((proc = procps_scan(proc, scan_mask)) != NULL) {
+		char *cmd;
+		if (proc->pid == pid)
+			continue;
+		cmd = proc->argv0;
+		if (!cmd)
+			cmd = proc->comm;
+		/* NB: OPT_INVERT is always 0 or 1 */
+		if ((regexec(&re_buffer, cmd, 1, re_match, 0) == 0 /* match found */
+                     && (!OPT_ANCHOR || (re_match[0].rm_so == 0 && re_match[0].rm_eo == strlen(cmd)))) ^ OPT_INVERT
+		) {
+			matched_pid = proc->pid;
+			if (OPT_LAST) {
+				free(cmd_last);
+				cmd_last = xstrdup(cmd_last);
+				continue;
+			}
+			act(proc->pid, cmd, signo, opt);
+			if (OPT_FIRST)
+				break;
+		}
+	}
+	if (cmd_last) {
+		act(matched_pid, cmd_last, signo, opt);
+		if (ENABLE_FEATURE_CLEAN_UP)
+			free(cmd_last);
+	}
+	return matched_pid == 0; /* return 1 if no processes listed/signaled */
+}




More information about the busybox-cvs mailing list