[Midnightbsd-cvs] src: usr.bin/pkill: sync pkill with freebsd and install in /bin with

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri Mar 27 18:02:25 EDT 2009


Log Message:
-----------
sync pkill with freebsd and install in /bin with symlinks to /usr/bin as needed

Modified Files:
--------------
    src/usr.bin/pkill:
        Makefile (r1.1.1.1 -> r1.2)
        pkill.1 (r1.1.1.2 -> r1.2)
        pkill.c (r1.1.1.2 -> r1.2)

-------------- next part --------------
Index: pkill.c
===================================================================
RCS file: /home/cvs/src/usr.bin/pkill/pkill.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L usr.bin/pkill/pkill.c -L usr.bin/pkill/pkill.c -u -r1.1.1.2 -r1.2
--- usr.bin/pkill/pkill.c
+++ usr.bin/pkill/pkill.c
@@ -1,7 +1,8 @@
-/*	$NetBSD: pkill.c,v 1.8 2005/03/02 15:31:44 abs Exp $	*/
-
+/*	$NetBSD: pkill.c,v 1.16 2005/10/10 22:13:20 kleink Exp $	*/
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 2005 Pawel Jakub Dawidek <pjd at FreeBSD.org>
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -37,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/usr.bin/pkill/pkill.c,v 1.26.2.1 2006/01/15 17:50:35 delphij Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/pkill/pkill.c,v 1.31 2006/11/23 11:55:17 yar Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -83,6 +84,7 @@
 	LT_GROUP,
 	LT_TTY,
 	LT_PGRP,
+	LT_JID,
 	LT_SID
 };
 
@@ -93,50 +95,48 @@
 
 SLIST_HEAD(listhead, list);
 
-struct kinfo_proc	*plist;
-char	*selected;
-const char	*delim = "\n";
-int	nproc;
-int	pgrep;
-int	signum = SIGTERM;
-int	newest;
-int	oldest;
-int	inverse;
-int	longfmt;
-int	matchargs;
-int	fullmatch;
-int	kthreads;
-int	cflags = REG_EXTENDED;
-kvm_t	*kd;
-pid_t	mypid;
-
-struct listhead euidlist = SLIST_HEAD_INITIALIZER(list);
-struct listhead ruidlist = SLIST_HEAD_INITIALIZER(list);
-struct listhead rgidlist = SLIST_HEAD_INITIALIZER(list);
-struct listhead pgrplist = SLIST_HEAD_INITIALIZER(list);
-struct listhead ppidlist = SLIST_HEAD_INITIALIZER(list);
-struct listhead tdevlist = SLIST_HEAD_INITIALIZER(list);
-struct listhead sidlist = SLIST_HEAD_INITIALIZER(list);
-struct listhead jidlist = SLIST_HEAD_INITIALIZER(list);
-
-int	main(int, char **);
-void	usage(void);
-void	killact(struct kinfo_proc *);
-void	grepact(struct kinfo_proc *);
-void	makelist(struct listhead *, enum listtype, char *);
-int	takepid(const char *, int);
+static struct kinfo_proc *plist;
+static char	*selected;
+static const char *delim = "\n";
+static int	nproc;
+static int	pgrep;
+static int	signum = SIGTERM;
+static int	newest;
+static int	oldest;
+static int	interactive;
+static int	inverse;
+static int	longfmt;
+static int	matchargs;
+static int	fullmatch;
+static int	kthreads;
+static int	cflags = REG_EXTENDED;
+static kvm_t	*kd;
+static pid_t	mypid;
+
+static struct listhead euidlist = SLIST_HEAD_INITIALIZER(list);
+static struct listhead ruidlist = SLIST_HEAD_INITIALIZER(list);
+static struct listhead rgidlist = SLIST_HEAD_INITIALIZER(list);
+static struct listhead pgrplist = SLIST_HEAD_INITIALIZER(list);
+static struct listhead ppidlist = SLIST_HEAD_INITIALIZER(list);
+static struct listhead tdevlist = SLIST_HEAD_INITIALIZER(list);
+static struct listhead sidlist = SLIST_HEAD_INITIALIZER(list);
+static struct listhead jidlist = SLIST_HEAD_INITIALIZER(list);
+
+static void	usage(void) __attribute__((__noreturn__));
+static int	killact(const struct kinfo_proc *);
+static int	grepact(const struct kinfo_proc *);
+static void	makelist(struct listhead *, enum listtype, char *);
+static int	takepid(const char *, int);
 
 int
 main(int argc, char **argv)
 {
-	extern char *optarg;
-	extern int optind;
 	char buf[_POSIX2_LINE_MAX], *mstr, **pargv, *p, *q, *pidfile;
 	const char *execf, *coref;
 	int debug_opt;
 	int i, ch, bestidx, rv, criteria, pidfromfile, pidfilelock;
 	size_t jsz;
-	void (*action)(struct kinfo_proc *);
+	int (*action)(const struct kinfo_proc *);
 	struct kinfo_proc *kp;
 	struct list *li;
 	struct timeval best_tval;
@@ -180,7 +180,7 @@
 	pidfilelock = 0;
 	execf = coref = _PATH_DEVNULL;
 
-	while ((ch = getopt(argc, argv, "DF:G:LM:N:P:SU:d:fg:ij:lnos:t:u:vx")) != -1)
+	while ((ch = getopt(argc, argv, "DF:G:ILM:N:P:SU:d:fg:ij:lnos:t:u:vx")) != -1)
 		switch (ch) {
 		case 'D':
 			debug_opt++;
@@ -193,6 +193,11 @@
 			makelist(&rgidlist, LT_GROUP, optarg);
 			criteria = 1;
 			break;
+		case 'I':
+			if (pgrep)
+				usage();
+			interactive = 1;
+			break;
 		case 'L':
 			pidfilelock = 1;
 			break;
@@ -231,7 +236,7 @@
 			cflags |= REG_ICASE;
 			break;
 		case 'j':
-			makelist(&jidlist, LT_GENERIC, optarg);
+			makelist(&jidlist, LT_JID, optarg);
 			criteria = 1;
 			break;
 		case 'l':
@@ -277,12 +282,14 @@
 	if (!criteria)
 		usage();
 	if (newest && oldest)
-		errx(STATUS_ERROR, "-n and -o are mutually exclusive");
+		errx(STATUS_ERROR, "Options -n and -o are mutually exclusive");
 	if (pidfile != NULL)
 		pidfromfile = takepid(pidfile, pidfilelock);
 	else {
-		if (pidfilelock)
-			errx(STATUS_ERROR, "-L doesn't make sense without -F");
+		if (pidfilelock) {
+			errx(STATUS_ERROR,
+			    "Option -L doesn't make sense without -F");
+		}
 		pidfromfile = -1;
 	}
 
@@ -293,22 +300,26 @@
 	 */
 	kd = kvm_openfiles(execf, coref, NULL, O_RDONLY, buf);
 	if (kd == NULL)
-		errx(STATUS_ERROR, "kvm_openfiles(): %s", buf);
+		errx(STATUS_ERROR, "Cannot open kernel files (%s)", buf);
 
 	/*
 	 * Use KERN_PROC_PROC instead of KERN_PROC_ALL, since we
 	 * just want processes and not individual kernel threads.
 	 */
 	plist = kvm_getprocs(kd, KERN_PROC_PROC, 0, &nproc);
-	if (plist == NULL)
-		errx(STATUS_ERROR, "kvm_getprocs() failed");
+	if (plist == NULL) {
+		errx(STATUS_ERROR, "Cannot get process list (%s)",
+		    kvm_geterr(kd));
+	}
 
 	/*
 	 * Allocate memory which will be used to keep track of the
 	 * selection.
 	 */
-	if ((selected = malloc(nproc)) == NULL)
-		errx(STATUS_ERROR, "memory allocation failure");
+	if ((selected = malloc(nproc)) == NULL) {
+		err(STATUS_ERROR, "Cannot allocate memory for %d processes",
+		    nproc);
+	}
 	memset(selected, 0, nproc);
 
 	/*
@@ -317,7 +328,9 @@
 	for (; *argv != NULL; argv++) {
 		if ((rv = regcomp(&reg, *argv, cflags)) != 0) {
 			regerror(rv, &reg, buf, sizeof(buf));
-			errx(STATUS_BADUSAGE, "bad expression: %s", buf);
+			errx(STATUS_BADUSAGE,
+			    "Cannot compile regular expression `%s' (%s)",
+			    *argv, buf);
 		}
 
 		for (i = 0, kp = plist; i < nproc; i++, kp++) {
@@ -353,7 +366,9 @@
 					selected[i] = 1;
 			} else if (rv != REG_NOMATCH) {
 				regerror(rv, &reg, buf, sizeof(buf));
-				errx(STATUS_ERROR, "regexec(): %s", buf);
+				errx(STATUS_ERROR,
+				    "Regular expression evaluation error (%s)",
+				    buf);
 			}
 			if (debug_opt > 1) {
 				const char *rv_res = "NoMatch";
@@ -437,12 +452,12 @@
 		}
 
 		SLIST_FOREACH(li, &jidlist, li_chain) {
-			if (kp->ki_jid > 0) {
-				if (li->li_number == 0)
-					break;
-				if (kp->ki_jid == (int)li->li_number)
-					break;
-			}
+			/* A particular jail ID, including 0 (not in jail) */
+			if (kp->ki_jid == (int)li->li_number)
+				break;
+			/* Any jail */
+			if (kp->ki_jid > 0 && li->li_number == -1)
+				break;
 		}
 		if (SLIST_FIRST(&jidlist) != NULL && li == NULL) {
 			selected[i] = 0;
@@ -495,14 +510,13 @@
 				continue;
 		} else if (!inverse)
 			continue;
-		rv = 1;
-		(*action)(kp);
+		rv |= (*action)(kp);
 	}
 
 	exit(rv ? STATUS_MATCH : STATUS_NOMATCH);
 }
 
-void
+static void
 usage(void)
 {
 	const char *ustr;
@@ -510,7 +524,7 @@
 	if (pgrep)
 		ustr = "[-LSfilnovx] [-d delim]";
 	else
-		ustr = "[-signal] [-Lfinovx]";
+		ustr = "[-signal] [-ILfinovx]";
 
 	fprintf(stderr,
 		"usage: %s %s [-F pidfile] [-G gid] [-M core] [-N system]\n"
@@ -518,23 +532,15 @@
 		"             [-t tty] [-u euid] pattern ...\n", getprogname(),
 		ustr);
 
-	exit(STATUS_ERROR);
+	exit(STATUS_BADUSAGE);
 }
 
-void
-killact(struct kinfo_proc *kp)
-{
-
-	if (kill(kp->ki_pid, signum) == -1)
-		err(STATUS_ERROR, "signalling pid %d", (int)kp->ki_pid);
-}
-
-void
-grepact(struct kinfo_proc *kp)
+static void
+show_process(const struct kinfo_proc *kp)
 {
 	char **argv;
 
-	if (longfmt && matchargs &&
+	if ((longfmt || !pgrep) && matchargs &&
 	    (argv = kvm_getargv(kd, kp, 0)) != NULL) {
 		printf("%d ", (int)kp->ki_pid);
 		for (; *argv != NULL; argv++) {
@@ -542,38 +548,86 @@
 			if (argv[1] != NULL)
 				putchar(' ');
 		}
-	} else if (longfmt)
+	} else if (longfmt || !pgrep)
 		printf("%d %s", (int)kp->ki_pid, kp->ki_comm);
 	else
 		printf("%d", (int)kp->ki_pid);
+}
 
+static int
+killact(const struct kinfo_proc *kp)
+{
+	int ch, first;
+
+	if (interactive) {
+		/*
+		 * Be careful, ask before killing.
+		 */
+		printf("kill ");
+		show_process(kp);
+		printf("? ");
+		fflush(stdout);
+		first = ch = getchar();
+		while (ch != '\n' && ch != EOF)
+			ch = getchar();
+		if (first != 'y' && first != 'Y')
+			return (1);
+	}
+	if (kill(kp->ki_pid, signum) == -1) {
+		/* 
+		 * Check for ESRCH, which indicates that the process
+		 * disappeared between us matching it and us
+		 * signalling it; don't issue a warning about it.
+		 */
+		if (errno != ESRCH)
+			warn("signalling pid %d", (int)kp->ki_pid);
+		/*
+		 * Return 0 to indicate that the process should not be
+		 * considered a match, since we didn't actually get to
+		 * signal it.
+		 */
+		return (0);
+	}
+	return (1);
+}
+
+static int
+grepact(const struct kinfo_proc *kp)
+{
+
+	show_process(kp);
 	printf("%s", delim);
+	return (1);
 }
 
-void
+static void
 makelist(struct listhead *head, enum listtype type, char *src)
 {
 	struct list *li;
 	struct passwd *pw;
 	struct group *gr;
 	struct stat st;
-	const char *cp;
-	char *sp, *p, buf[MAXPATHLEN];
+	const char *cp, *prefix;
+	char *sp, *ep, buf[MAXPATHLEN];
 	int empty;
 
 	empty = 1;
+	prefix = _PATH_DEV;
 
 	while ((sp = strsep(&src, ",")) != NULL) {
 		if (*sp == '\0')
 			usage();
 
-		if ((li = malloc(sizeof(*li))) == NULL)
-			errx(STATUS_ERROR, "memory allocation failure");
+		if ((li = malloc(sizeof(*li))) == NULL) {
+			err(STATUS_ERROR, "Cannot allocate %zu bytes",
+			    sizeof(*li));
+		}
+
 		SLIST_INSERT_HEAD(head, li, li_chain);
 		empty = 0;
 
-		li->li_number = (uid_t)strtol(sp, &p, 0);
-		if (*p == '\0') {
+		li->li_number = (uid_t)strtol(sp, &ep, 0);
+		if (*ep == '\0') {
 			switch (type) {
 			case LT_PGRP:
 				if (li->li_number == 0)
@@ -583,8 +637,17 @@
 				if (li->li_number == 0)
 					li->li_number = getsid(mypid);
 				break;
+			case LT_JID:
+				if (li->li_number < 0)
+					errx(STATUS_BADUSAGE,
+					     "Negative jail ID `%s'", sp);
+				/* For compatibility with old -j */
+				if (li->li_number == 0)
+					li->li_number = -1;	/* any jail */
+				break;
 			case LT_TTY:
 				usage();
+				/* NOTREACHED */
 			default:
 				break;
 			}
@@ -594,54 +657,60 @@
 		switch (type) {
 		case LT_USER:
 			if ((pw = getpwnam(sp)) == NULL)
-				errx(STATUS_BADUSAGE, "unknown user `%s'",
-				    sp);
+				errx(STATUS_BADUSAGE, "Unknown user `%s'", sp);
 			li->li_number = pw->pw_uid;
 			break;
 		case LT_GROUP:
 			if ((gr = getgrnam(sp)) == NULL)
-				errx(STATUS_BADUSAGE, "unknown group `%s'",
-				    sp);
+				errx(STATUS_BADUSAGE, "Unknown group `%s'", sp);
 			li->li_number = gr->gr_gid;
 			break;
 		case LT_TTY:
 			if (strcmp(sp, "-") == 0) {
 				li->li_number = -1;
 				break;
-			} else if (strcmp(sp, "co") == 0)
+			} else if (strcmp(sp, "co") == 0) {
 				cp = "console";
-			else if (strncmp(sp, "tty", 3) == 0)
+			} else {
 				cp = sp;
-			else
-				cp = NULL;
+				if (strncmp(sp, "tty", 3) != 0)
+					prefix = _PATH_TTY;
+			}
 
-			if (cp == NULL)
-				snprintf(buf, sizeof(buf), "/dev/tty%s", sp);
-			else
-				snprintf(buf, sizeof(buf), "/dev/%s", cp);
+			snprintf(buf, sizeof(buf), "%s%s", prefix, cp);
 
-			if (stat(buf, &st) < 0) {
-				if (errno == ENOENT)
+			if (stat(buf, &st) == -1) {
+				if (errno == ENOENT) {
 					errx(STATUS_BADUSAGE,
-					    "no such tty: `%s'", sp);
-				err(STATUS_ERROR, "stat(%s)", sp);
+					    "No such tty: `%s'", sp);
+				}
+				err(STATUS_ERROR, "Cannot access `%s'", sp);
 			}
 
 			if ((st.st_mode & S_IFCHR) == 0)
-				errx(STATUS_BADUSAGE, "not a tty: `%s'", sp);
+				errx(STATUS_BADUSAGE, "Not a tty: `%s'", sp);
 
 			li->li_number = st.st_rdev;
 			break;
+		case LT_JID:
+			if (strcmp(sp, "none") == 0)
+				li->li_number = 0;
+			else if (strcmp(sp, "any") == 0)
+				li->li_number = -1;
+			else if (*ep != '\0')
+				errx(STATUS_BADUSAGE,
+				     "Invalid jail ID `%s'", sp);
+			break;
 		default:
 			usage();
-		};
+		}
 	}
 
 	if (empty)
 		usage();
 }
 
-int
+static int
 takepid(const char *pidfile, int pidfilelock)
 {
 	char *endp, line[BUFSIZ];
@@ -650,7 +719,7 @@
 
 	fh = fopen(pidfile, "r");
 	if (fh == NULL)
-		err(STATUS_ERROR, "can't open pid file `%s'", pidfile);
+		err(STATUS_ERROR, "Cannot open pidfile `%s'", pidfile);
 
 	if (pidfilelock) {
 		/*
@@ -659,11 +728,11 @@
 		 */
 		if (flock(fileno(fh), LOCK_EX | LOCK_NB) == 0) {
 			(void)fclose(fh);
-			errx(STATUS_ERROR, "file '%s' can be locked", pidfile);
+			errx(STATUS_ERROR, "File '%s' can be locked", pidfile);
 		} else {
 			if (errno != EWOULDBLOCK) {
 				errx(STATUS_ERROR,
-				    "error while locking file '%s'", pidfile);
+				    "Error while locking file '%s'", pidfile);
 			}
 		}
 	}
@@ -671,17 +740,17 @@
 	if (fgets(line, sizeof(line), fh) == NULL) {
 		if (feof(fh)) {
 			(void)fclose(fh);
-			errx(STATUS_ERROR, "pid file `%s' is empty", pidfile);
+			errx(STATUS_ERROR, "Pidfile `%s' is empty", pidfile);
 		}
 		(void)fclose(fh);
-		err(STATUS_ERROR, "can't read from pid file `%s'", pidfile);
+		err(STATUS_ERROR, "Cannot read from pid file `%s'", pidfile);
 	}
 	(void)fclose(fh);
 
 	rval = strtol(line, &endp, 10);
 	if (*endp != '\0' && !isspace((unsigned char)*endp))
-		errx(STATUS_ERROR, "invalid pid in file `%s'", pidfile);
+		errx(STATUS_ERROR, "Invalid pid in file `%s'", pidfile);
 	else if (rval < MIN_PID || rval > MAX_PID)
-		errx(STATUS_ERROR, "invalid pid in file `%s'", pidfile);
+		errx(STATUS_ERROR, "Invalid pid in file `%s'", pidfile);
 	return (rval);
 }
Index: Makefile
===================================================================
RCS file: /home/cvs/src/usr.bin/pkill/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L usr.bin/pkill/Makefile -L usr.bin/pkill/Makefile -u -r1.1.1.1 -r1.2
--- usr.bin/pkill/Makefile
+++ usr.bin/pkill/Makefile
@@ -1,5 +1,8 @@
 #	$NetBSD: Makefile,v 1.1 2002/03/01 11:21:58 ad Exp $
-# $FreeBSD: src/usr.bin/pkill/Makefile,v 1.5 2004/11/13 17:12:22 ru Exp $
+# $FreeBSD: src/usr.bin/pkill/Makefile,v 1.7 2006/08/20 04:25:20 yar Exp $
+# $MidnightBSD$
+
+BINDIR=	/bin
 
 PROG=	pkill
 WARNS?=	5
@@ -10,4 +13,12 @@
 LINKS=	${BINDIR}/pkill ${BINDIR}/pgrep
 MLINKS=	pkill.1 pgrep.1
 
+#
+# If considering retirement of these compatibility symlinks,
+# keep in mind that pkill is installed to /usr/bin in other
+# OS types, e.g., NetBSD, OpenBSD, Solaris, and Linux.
+#
+SYMLINKS=	${BINDIR}/pkill /usr/bin/pkill
+SYMLINKS+=	${BINDIR}/pgrep /usr/bin/pgrep
+
 .include <bsd.prog.mk>
Index: pkill.1
===================================================================
RCS file: /home/cvs/src/usr.bin/pkill/pkill.1,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L usr.bin/pkill/pkill.1 -L usr.bin/pkill/pkill.1 -u -r1.1.1.2 -r1.2
--- usr.bin/pkill/pkill.1
+++ usr.bin/pkill/pkill.1
@@ -1,6 +1,7 @@
 .\"	$NetBSD: pkill.1,v 1.8 2003/02/14 15:59:18 grant Exp $
 .\"
-.\" $FreeBSD: src/usr.bin/pkill/pkill.1,v 1.16.2.1 2006/01/15 17:50:35 delphij Exp $
+.\" $FreeBSD: src/usr.bin/pkill/pkill.1,v 1.22 2006/12/20 11:57:22 ru Exp $
+.\" $MidnightBSD$
 .\"
 .\" Copyright (c) 2002 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -36,7 +37,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd March 20, 2005
+.Dd November 23, 2006
 .Dt PKILL 1
 .Os
 .Sh NAME
@@ -60,7 +61,7 @@
 .Ar pattern ...
 .Nm pkill
 .Op Fl Ar signal
-.Op Fl Lfinovx
+.Op Fl ILfinovx
 .Op Fl F Ar pidfile
 .Op Fl G Ar gid
 .Op Fl M Ar core
@@ -95,6 +96,8 @@
 Restrict matches to processes with a real group ID in the comma-separated
 list
 .Ar gid .
+.It Fl I
+Request confirmation before attempting to signal each process.
 .It Fl L
 The
 .Ar pidfile
@@ -144,7 +147,12 @@
 Restrict matches to processes inside jails with a jail ID in the comma-separated
 list
 .Ar jid .
-The value zero is taken to mean any jail ID.
+The value
+.Dq Li any
+matches processes in any jail.
+The value
+.Dq Li none
+matches processes not in jail.
 .It Fl l
 Long output.
 Print the process name in addition to the process ID for each matching
@@ -238,6 +246,18 @@
 .It 3
 An internal error occurred.
 .El
+.Sh COMPATIBILITY
+Historically the option
+.Dq Fl j Li 0
+means any jail, although in other utilities such as
+.Xr ps 1
+jail ID
+.Li 0
+has the opposite meaning, not in jail.
+Therefore
+.Dq Fl j Li 0
+is deprecated, and its use is discouraged in favor of
+.Dq Fl j Li any .
 .Sh SEE ALSO
 .Xr kill 1 ,
 .Xr killall 1 ,


More information about the Midnightbsd-cvs mailing list