These are three patches for busybox.

1) The first one adds a function xfree(ptr) to xfuncs.c which acts
    as if (ptr) free(ptr) and substitute some examples of such
    elements in the code. I don't remember whether such a
    function is necessary or whether free() itself already checks
    for null pointer.

2) The second one corrects a comment.

3) The third one adds functions pgrep and pkill (this one includes
    the "procps.diff" that I've sent before).

    The first patch contains some modifications to libbb.h that are
  logically part of the third. Since I've hand-split the file, I've not
  tried to disentangle them. It's not very difficult to do it if for
  any reason you need either one and not the other.

       Loïc
Index: include/libbb.h
===================================================================
--- include/libbb.h	(révision 20077)
+++ include/libbb.h	(copie de travail)
@@ -259,8 +259,9 @@
 char *xmalloc_readlink(const char *path);
 char *xmalloc_readlink_or_warn(const char *path);
 char *xrealloc_getcwd_or_warn(char *cwd);
+/* Free pointer if non NULL */
+void xfree(void *ptr);
 
-
 //TODO: signal(sid, f) is the same? then why?
 extern void sig_catch(int,void (*)(int));
 //#define sig_ignore(s) (sig_catch((s), SIG_IGN))
@@ -787,6 +788,7 @@
 
 int get_signum(const char *name);
 const char *get_signame(int number);
+void print_signames_and_exit(void);
 
 char *bb_simplify_path(const char *path);
 
@@ -974,6 +976,7 @@
 	PSSCAN_TTY      = 1 << 14,
 	PSSCAN_SMAPS	= (1 << 15) * ENABLE_FEATURE_TOPMEM,
 	USE_SELINUX(PSSCAN_CONTEXT = 1 << 16,)
+	PSSCAN_ARGVN    = 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
Index: libbb/xfuncs.c
===================================================================
--- libbb/xfuncs.c	(révision 20077)
+++ libbb/xfuncs.c	(copie de travail)
@@ -100,6 +100,13 @@
 	return memcpy(t, s, n);
 }
 
+// This one does not die but checks whether argument is != NULL
+void xfree(void *ptr)
+{
+	if (ptr != NULL)
+		free(ptr);
+}
+
 // Die if we can't open a file and return a FILE * to it.
 // Notice we haven't got xfread(), This is for use with fscanf() and friends.
 FILE *xfopen(const char *path, const char *mode)
Index: editors/sed.c
===================================================================
--- editors/sed.c	(révision 20077)
+++ editors/sed.c	(copie de travail)
@@ -157,7 +157,7 @@
 		sed_cmd = sed_cmd_next;
 	}
 
-	if (G.hold_space) free(G.hold_space);
+	xfree(G.hold_space);
 
 	while (G.current_input_file < G.input_file_count)
 		fclose(G.input_file_list[G.current_input_file++]);
Index: shell/lash.c
===================================================================
--- shell/lash.c	(révision 20077)
+++ shell/lash.c	(copie de travail)
@@ -455,8 +455,7 @@
 	for (i = 0; i < cmd->num_progs; i++) {
 		free(cmd->progs[i].argv);
 #if ENABLE_LASH_PIPE_N_REDIRECTS
-		if (cmd->progs[i].redirects)
-			free(cmd->progs[i].redirects);
+		xfree(cmd->progs[i].redirects);
 #endif
 	}
 	free(cmd->progs);
Index: shell/ash.c
===================================================================
--- shell/ash.c	(révision 20077)
+++ shell/ash.c	(copie de travail)
@@ -5328,8 +5328,7 @@
 		p = buf;
 	}
 
-	if (in.buf)
-		free(in.buf);
+	xfree(in.buf);
 	if (in.fd >= 0) {
 		close(in.fd);
 		back_exitstatus = waitforjob(in.jp);
@@ -8788,8 +8787,7 @@
 	INT_OFF;
 	if (pf->fd >= 0)
 		close(pf->fd);
-	if (pf->buf)
-		free(pf->buf);
+	xfree(pf->buf);
 	while (pf->strpush)
 		popstring();
 	parsefile = pf->prev;
@@ -10330,8 +10328,7 @@
 #endif
 	savepbq = parsebackquote;
 	if (setjmp(jmploc.loc)) {
-		if (str)
-			free(str);
+		xfree(str);
 		parsebackquote = 0;
 		exception_handler = savehandler;
 		longjmp(exception_handler->loc, 1);
@@ -11264,8 +11261,7 @@
 			else
 				action = ckstrdup(action);
 		}
-		if (trap[signo])
-			free(trap[signo]);
+		xfree(trap[signo]);
 		trap[signo] = action;
 		if (signo != 0)
 			setsignal(signo);
Index: libbb/lineedit.c
===================================================================
--- libbb/lineedit.c	(révision 20077)
+++ libbb/lineedit.c	(copie de travail)
@@ -854,7 +854,7 @@
 static void get_previous_history(void)
 {
 	if (command_ps[0] != '\0' || state->history[state->cur_history] == NULL) {
-		free(state->history[state->cur_history]);
+		xfree(state->history[state->cur_history]);
 		state->history[state->cur_history] = xstrdup(command_ps);
 	}
 	state->cur_history--;
Index: libbb/getopt32.c
===================================================================
--- libbb/getopt32.c	(révision 20077)
+++ libbb/getopt32.c	(copie de travail)
@@ -30,7 +30,7 @@
 
         "r" will add 1    (bit 0)
         "n" will add 2    (bit 1)
-        "u  will add 4    (bit 2)
+        "u" will add 4    (bit 2)
         "g" will add 8    (bit 3)
 
         and so on.  You can also look at the return value as a bit
Index: libbb/procps.c
===================================================================
--- libbb/procps.c	(révision 20077)
+++ libbb/procps.c	(copie de travail)
@@ -353,14 +353,10 @@
 
 #if 0 /* PSSCAN_CMD is not used */
 		if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) {
-			if (sp->argv0) {
-				free(sp->argv0);
-				sp->argv0 = NULL;
-			}
-			if (sp->cmd) {
-				free(sp->cmd);
-				sp->cmd = NULL;
-			}
+			xfree(sp->argv0);
+			sp->argv0 = NULL;
+			xfree(sp->cmd);
+			sp->cmd = NULL;
 			strcpy(filename_tail, "/cmdline");
 			/* TODO: to get rid of size limits, read into malloc buf,
 			 * then realloc it down to real size. */
@@ -379,17 +375,21 @@
 			}
 		}
 #else
-		if (flags & PSSCAN_ARGV0) {
-			if (sp->argv0) {
-				free(sp->argv0);
-				sp->argv0 = NULL;
-			}
+		if (flags & (PSSCAN_ARGV0|PSSCAN_ARGVN)) {
+			xfree(sp->argv0);
+			sp->argv0 = NULL;
 			strcpy(filename_tail, "/cmdline");
 			n = read_to_buf(filename, buf);
 			if (n <= 0)
 				break;
-			if (flags & PSSCAN_ARGV0)
-				sp->argv0 = xstrdup(buf);
+			if (flags & PSSCAN_ARGVN) {
+				do {
+					n--;
+					if (buf[n] == '\0')
+						buf[n] = ' ';
+				} while (n);
+			}
+			sp->argv0 = xstrdup(buf);
 		}
 #endif
 		break;
Index: libbb/u_signal_names.c
===================================================================
--- libbb/u_signal_names.c	(révision 20077)
+++ libbb/u_signal_names.c	(copie de travail)
@@ -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);
+}
Index: procps/kill.c
===================================================================
--- procps/kill.c	(révision 20077)
+++ procps/kill.c	(copie de travail)
@@ -58,11 +58,7 @@
 	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);
-			}
+			print_signames_and_exit();
 		} else { /* -l <sig list> */
 			while ((arg = *++argv)) {
 				if (isdigit(arg[0])) {
Index: include/usage.h
===================================================================
--- include/usage.h	(révision 20077)
+++ include/usage.h	(copie de travail)
@@ -2558,6 +2558,18 @@
        "$ patch -p1 < example.diff\n" \
        "$ patch -p0 -i example.diff"
 
+#define pgrep_trivial_usage \
+       "[-flnovx] pattern"
+#define pgrep_full_usage \
+       "	pattern to look for in the name of the process" \
+       "\n\nOptions:\n" \
+       "	-f	Match against the command line instead of process name\n" \
+       "	-l	Give command name in addition to process number\n" \
+       "	-n	Select the last started process of the list\n" \
+       "	-o	Select the first started process of the list\n" \
+       "	-v	Negate the matching\n" \
+       "	-x	Match the complete name"
+
 #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 (default is TERM) to the process(es) specified by name" \
+       "\n\nOptions:\n" \
+       "	-l	List all signal names and numbers\n" \
+       "	-f	Match against the command line instead of process name\n" \
+       "	-n	Select the last started process of the list\n" \
+       "	-o	Select the first started process of the list\n" \
+       "	-v	Negate the matching\n" \
+       "	-x	Match the complete name"
+
 #define poweroff_trivial_usage \
        "[-d delay] [-n] [-f]"
 #define poweroff_full_usage \
Index: include/applets.h
===================================================================
--- include/applets.h	(révision 20077)
+++ include/applets.h	(copie de travail)
@@ -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))
Index: procps/Config.in
===================================================================
--- procps/Config.in	(révision 20077)
+++ procps/Config.in	(copie de travail)
@@ -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
Index: procps/Kbuild
===================================================================
--- procps/Kbuild	(révision 20077)
+++ procps/Kbuild	(copie de travail)
@@ -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
--- /dev/null	2007-09-26 12:43:34.255962088 +0200
+++ procps/pgrep.c	2007-09-28 14:13:18.000000000 +0200
@@ -0,0 +1,135 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini pgrep/pkill implementation for busybox
+ *
+ * Copyright (C) 2007
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ */
+
+#include <getopt.h>
+
+#include "libbb.h"
+#include "xregex.h"
+
+static char char2;
+/* Idea taken from kill.c */
+#define pgrep (ENABLE_PGREP && char2 == 'g')
+#define pkill (ENABLE_PKILL && char2 == 'k')
+
+static void act(unsigned pid, char *cmd, int signo, int opt)
+{
+	if (pgrep)
+	{
+		if (opt)
+			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)
+{
+	char *first_arg, *cmdm = NULL;
+    procps_status_t *p = NULL;
+	regex_t re_buffer;
+	const int NMATCH = 2;
+	regmatch_t re_regs[NMATCH];
+	int match = 0;
+	unsigned pid = getpid();
+	int signo = SIGTERM, i;
+	uint32_t opt;
+	int scan_mask = PSSCAN_STAT, anchor, invert, last;
+
+	char2 = argv[0][1];
+	for (i = 1; ; i++)
+	{
+		first_arg = argv[i];
+		if (!first_arg)
+			break;
+		if (first_arg[0] != '-' || first_arg[1] < 'a' || first_arg[1] > 'z')
+		{
+			argv[i] = NULL;
+			break;
+		}
+	}
+	opt = getopt32(argv, "lfxvon");
+	for (i = 1; argv[i]; i++)
+		;
+	argv[i] = first_arg;
+	argc -= optind;
+	argv += optind;
+	if (opt & 0x02)
+		scan_mask |= PSSCAN_ARGVN;
+	if (opt & 0x04)
+		anchor = 0;
+	else
+		anchor = 1;
+	if (opt & 0x08)
+		invert = 1;
+	else
+		invert = 0;
+	if (opt & 0x20)
+		last = 1;
+	else
+		last = 0;
+
+	if (pkill && opt == 0x01) { // -l
+		if (argc || opt & ~0x01)
+			bb_perror_nomsg_and_die();
+		/* Print the whole signal list */
+		print_signames_and_exit();
+	}
+
+	if (pkill && first_arg && first_arg[0] == '-')
+	{
+		signo = get_signum(&first_arg[1]);
+		++argv;
+		--argc;
+	}
+	if (signo < 0) { /* || signo > MAX_SIGNUM ? */
+		bb_error_msg_and_die("bad signal name '%s'", &first_arg[1]);
+	}
+
+	/* Name is required */
+	if (argc != 1)
+		bb_error_msg_and_die("You need to specify one matching criteria");
+
+	memset(&re_buffer, 0, sizeof(re_buffer));
+	memset(re_regs, 0, sizeof(*re_regs));
+	xregcomp(&re_buffer, argv[0], 0);
+
+    while ((p = procps_scan(p, scan_mask)) != NULL) {
+		char *cmd;
+		cmd = p->argv0;
+		if (!cmd)
+			cmd = p->comm;
+		if (p->pid != pid &&
+			(regexec(&re_buffer, cmd, NMATCH, re_regs, 0) != REG_NOMATCH &&
+				(anchor ||
+				 (re_regs[0].rm_so == 0 && re_regs[0].rm_eo == strlen(cmd))))
+				^ invert)
+		{
+			match = p->pid;
+			if ((opt & 0x21) == 0x21)
+			{
+				xfree(cmdm);
+				cmdm = xstrdup(cmd);
+			}
+			if (last)
+				continue;
+			act(p->pid, cmd, signo, opt & 0x01);
+			if (opt & 0x10)
+				break;
+		}
+    }
+	if (last && match)
+	{
+		act(match, cmdm, signo, opt & 0x01);
+		xfree(cmdm);
+	}
+	return !match;
+}
_______________________________________________
busybox mailing list
busybox@busybox.net
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to