Module Name: src
Committed By: roy
Date: Mon Oct 7 06:14:05 UTC 2024
Modified Files:
src/usr.bin/pkill: pkill.1 pkill.c
Log Message:
pkill(1): Add -F option to use a pidfile and -L to ensure it's locked
Taken from FreeBSD
To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/usr.bin/pkill/pkill.1
cvs rdiff -u -r1.33 -r1.34 src/usr.bin/pkill/pkill.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/pkill/pkill.1
diff -u src/usr.bin/pkill/pkill.1:1.32 src/usr.bin/pkill/pkill.1:1.33
--- src/usr.bin/pkill/pkill.1:1.32 Sat Oct 29 08:17:16 2022
+++ src/usr.bin/pkill/pkill.1 Mon Oct 7 06:14:05 2024
@@ -1,4 +1,4 @@
-.\" $NetBSD: pkill.1,v 1.32 2022/10/29 08:17:16 simonb Exp $
+.\" $NetBSD: pkill.1,v 1.33 2024/10/07 06:14:05 roy Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 29, 2022
+.Dd October 6, 2024
.Dt PKILL 1
.Os
.Sh NAME
@@ -37,8 +37,9 @@
.Nd find or signal processes by name
.Sh SYNOPSIS
.Nm pgrep
-.Op Fl filnqvx
+.Op Fl fiLlnqvx
.Op Fl d Ar delim
+.Op Fl F Ar pidfile
.Op Fl G Ar gid
.Op Fl g Ar pgrp
.Op Fl P Ar ppid
@@ -49,7 +50,8 @@
.Ar pattern ...
.Nm pkill
.Op Fl signal
-.Op Fl filnvx
+.Op Fl fiLlnvx
+.Op Fl F Ar pidfile
.Op Fl G Ar gid
.Op Fl g Ar pgrp
.Op Fl P Ar ppid
@@ -89,7 +91,7 @@ The following options are available for
.Nm pkill
and
.Nm pgrep :
-.Bl -tag -width xxxxxxxx
+.Bl -tag -width ".Fl F Ar pidfile"
.It Fl d Ar delim
Specify a delimiter to be printed between each process ID.
The default is a newline.
@@ -99,6 +101,10 @@ command.
.It Fl f
Match against full argument lists.
The default is to match against process names.
+.It Fl F Ar pidfile
+Restrict matches to processes which pid is stored in
+.Ar pidfile
+file.
.It Fl G Ar gid
Restrict matches to processes with a real group ID in the comma-separated
list
@@ -114,6 +120,15 @@ or
command.
.It Fl i
Ignore case distinctions in both the process table and the supplied pattern.
+.It Fl L
+The
+.Ar pidfile
+given for the
+.Fl F
+option must be locked with the
+.Xr flock 2
+syscall or created with
+.Xr pidfile_lock 3 .
.It Fl l
Long output.
Print the process name in addition to the process ID for each matching
@@ -181,7 +196,7 @@ This option is valid only when given as
.Pp
The following option is also available for
.Nm pgrep :
-.Bl -tag -width xxxxxxxx
+.Bl -tag -width ".Fl F Ar pidfile"
.It Fl q
Quiet; do not write anything to standard output.
.El
Index: src/usr.bin/pkill/pkill.c
diff -u src/usr.bin/pkill/pkill.c:1.33 src/usr.bin/pkill/pkill.c:1.34
--- src/usr.bin/pkill/pkill.c:1.33 Sat Oct 29 08:17:16 2022
+++ src/usr.bin/pkill/pkill.c Mon Oct 7 06:14:05 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: pkill.c,v 1.33 2022/10/29 08:17:16 simonb Exp $ */
+/* $NetBSD: pkill.c,v 1.34 2024/10/07 06:14:05 roy Exp $ */
/*-
* Copyright (c) 2002, 2022 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: pkill.c,v 1.33 2022/10/29 08:17:16 simonb Exp $");
+__RCSID("$NetBSD: pkill.c,v 1.34 2024/10/07 06:14:05 roy Exp $");
#endif /* !lint */
#include <sys/types.h>
@@ -52,6 +52,7 @@ __RCSID("$NetBSD: pkill.c,v 1.33 2022/10
#include <ctype.h>
#include <kvm.h>
#include <err.h>
+#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
@@ -62,6 +63,9 @@ __RCSID("$NetBSD: pkill.c,v 1.33 2022/10
#define STATUS_BADUSAGE 2
#define STATUS_ERROR 3
+#define MIN_PID 5
+#define MAX_PID 30000 // XXX PID_MAX from sys/proc.h?
+
enum listtype {
LT_GENERIC,
LT_USER,
@@ -109,12 +113,13 @@ static int killact(const struct kinfo_pr
static int reniceact(const struct kinfo_proc2 *);
static int grepact(const struct kinfo_proc2 *);
static void makelist(struct listhead *, enum listtype, char *);
+static int takepid(const char *, int);
int
main(int argc, char **argv)
{
- char buf[_POSIX2_LINE_MAX], **pargv, *q;
- int i, j, ch, bestidx, rv, criteria;
+ char buf[_POSIX2_LINE_MAX], **pargv, *q, *pidfile = NULL;
+ int i, j, ch, bestidx, rv, criteria, pidfromfile, pidfilelock = 0;
int (*action)(const struct kinfo_proc2 *);
const struct kinfo_proc2 *kp;
struct list *li;
@@ -182,12 +187,19 @@ main(int argc, char **argv)
} else
usage();
} else {
- while ((ch = getopt(argc, argv, "G:P:U:d:fg:ilnqs:t:u:vx")) != -1)
+ while ((ch = getopt(argc, argv, "F:G:LP:U:d:fg:ilnqs:t:u:vx")) != -1)
switch (ch) {
+ case 'F':
+ pidfile = optarg;
+ criteria = 1;
+ break;
case 'G':
makelist(&rgidlist, LT_GROUP, optarg);
criteria = 1;
break;
+ case 'L':
+ pidfilelock = 1;
+ break;
case 'P':
makelist(&ppidlist, LT_GENERIC, optarg);
criteria = 1;
@@ -253,6 +265,15 @@ main(int argc, char **argv)
criteria = 1;
if (!criteria)
usage();
+ if (pidfile != NULL)
+ pidfromfile = takepid(pidfile, pidfilelock);
+ else {
+ if (pidfilelock) {
+ errx(STATUS_ERROR,
+ "Option -L doesn't make sense without -F");
+ }
+ pidfromfile = -1;
+ }
mypid = getpid();
@@ -331,6 +352,11 @@ main(int argc, char **argv)
if ((kp->p_flag & P_SYSTEM) != 0)
continue;
+ if (pidfromfile >= 0 && kp->p_pid != pidfromfile) {
+ selected[i] = 0;
+ continue;
+ }
+
SLIST_FOREACH(li, &ruidlist, li_chain)
if (kp->p_ruid == (uid_t)li->li_number)
break;
@@ -449,12 +475,12 @@ usage(void)
getprogname());
else {
if (pgrep)
- ustr = "[-filnqvx] [-d delim]";
+ ustr = "[-Lfilnqvx] [-d delim]";
else
- ustr = "[-signal] [-filnvx]";
+ ustr = "[-signal] [-Lfilnvx]";
(void)fprintf(stderr,
- "Usage: %s %s [-G gid] [-g pgrp] [-P ppid] [-s sid] "
+ "Usage: %s %s [-F pidfile] [-G gid] [-g pgrp] [-P ppid] [-s sid] "
"[-t tty]\n"
" [-U uid] [-u euid] pattern ...\n",
getprogname(), ustr);
@@ -644,3 +670,48 @@ makelist(struct listhead *head, enum lis
if (empty)
usage();
}
+
+static int
+takepid(const char *pidfile, int pidfilelock)
+{
+ char *endp, line[BUFSIZ];
+ FILE *fh;
+ long rval;
+
+ fh = fopen(pidfile, "r");
+ if (fh == NULL)
+ err(STATUS_ERROR, "Cannot open pidfile `%s'", pidfile);
+
+ if (pidfilelock) {
+ /*
+ * If we can lock pidfile, this means that daemon is not
+ * running, so would be better not to kill some random process.
+ */
+ if (flock(fileno(fh), LOCK_EX | LOCK_NB) == 0) {
+ (void)fclose(fh);
+ errx(STATUS_ERROR, "File '%s' can be locked", pidfile);
+ } else {
+ if (errno != EWOULDBLOCK) {
+ errx(STATUS_ERROR,
+ "Error while locking file '%s'", pidfile);
+ }
+ }
+ }
+
+ if (fgets(line, sizeof(line), fh) == NULL) {
+ if (feof(fh)) {
+ (void)fclose(fh);
+ errx(STATUS_ERROR, "Pidfile `%s' is empty", pidfile);
+ }
+ (void)fclose(fh);
+ 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);
+ else if (rval < MIN_PID || rval > MAX_PID)
+ errx(STATUS_ERROR, "Invalid pid in file `%s'", pidfile);
+ return (rval);
+}