Index: pkill.1 =================================================================== RCS file: /private/FreeBSD/src/usr.bin/pkill/pkill.1,v retrieving revision 1.8 diff -u -p -r1.8 pkill.1 --- pkill.1 16 Aug 2004 04:49:43 -0000 1.8 +++ pkill.1 24 Oct 2004 23:21:46 -0000 @@ -45,6 +45,7 @@ .Sh SYNOPSIS .Nm pgrep .Op Fl flnvx +.Op Fl F Ar pidfile .Op Fl G Ar gid .Op Fl M Ar core .Op Fl N Ar system @@ -59,6 +60,7 @@ .Nm pkill .Op Fl Ar signal .Op Fl fnvx +.Op Fl F Ar pidfile .Op Fl G Ar gid .Op Fl M Ar core .Op Fl N Ar system @@ -82,7 +84,11 @@ command searches the process table on th processes that match the criteria given on the command line. .Pp The following options are available: -.Bl -tag -width ".Fl d Ar delim" +.Bl -tag -width ".Fl F Ar pidfile" +.It Fl F Ar pidfile +Restrict matches to process 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 Index: pkill.c =================================================================== RCS file: /private/FreeBSD/src/usr.bin/pkill/pkill.c,v retrieving revision 1.18 diff -u -p -r1.18 pkill.c --- pkill.c 15 Jul 2004 08:10:26 -0000 1.18 +++ pkill.c 25 Oct 2004 19:33:24 -0000 @@ -69,6 +69,9 @@ __FBSDID("$FreeBSD: src/usr.bin/pkill/pk #define STATUS_BADUSAGE 2 #define STATUS_ERROR 3 +#define MIN_PID 5 +#define MAX_PID 99999 + /* Check for system-processes which should always be ignored. */ #define IS_KERNPROC(kp) ((kp)->ki_flag & P_KTHREAD) @@ -115,6 +118,7 @@ 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 main(int argc, char **argv) @@ -124,7 +128,7 @@ main(int argc, char **argv) char buf[_POSIX2_LINE_MAX], *mstr, **pargv, *p, *q; const char *execf, *coref; int debug_opt; - int i, ch, bestidx, rv, criteria, drop_privs; + int i, ch, bestidx, rv, criteria, drop_privs, pidfromfile; size_t jsz; void (*action)(struct kinfo_proc *); struct kinfo_proc *kp; @@ -167,13 +171,18 @@ main(int argc, char **argv) criteria = 0; debug_opt = 0; drop_privs = 0; + pidfromfile = -1; execf = coref = _PATH_DEVNULL; - while ((ch = getopt(argc, argv, "DG:M:N:P:U:d:fg:lns:t:u:vx")) != -1) + while ((ch = getopt(argc, argv, "DF:G:M:N:P:U:d:fg:lns:t:u:vx")) != -1) switch (ch) { case 'D': debug_opt++; break; + case 'F': + pidfromfile = takepid(optarg); + criteria = 1; + break; case 'G': makelist(&rgidlist, LT_GROUP, optarg); criteria = 1; @@ -342,6 +351,11 @@ main(int argc, char **argv) if (IS_KERNPROC(kp) != 0) continue; + if (pidfromfile >= 0 && kp->ki_pid != pidfromfile) { + selected[i] = 0; + continue; + } + SLIST_FOREACH(li, &ruidlist, li_chain) if (kp->ki_ruid == (uid_t)li->li_number) break; @@ -590,3 +604,33 @@ makelist(struct listhead *head, enum lis if (empty) usage(); } + +int +takepid(const char *pidfile) +{ + char *endp, line[BUFSIZ]; + FILE *fh; + long rval; + + fh = fopen(pidfile, "r"); + if (fh == NULL) + err(STATUS_ERROR, "can't open pid file `%s'", pidfile); + + if (fgets(line, sizeof(line), fh) == NULL) { + if (feof(fh)) { + (void)fclose(fh); + errx(STATUS_ERROR, "pid file `%s' is empty", pidfile); + } + (void)fclose(fh); + err(STATUS_ERROR, "can't read from pid file `%s'", pidfile); + } + (void)fclose(fh); + + errno = 0; + rval = strtol(line, &endp, 10); + if (*endp != '\0' && !isspace(*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); +}