http://perforce.freebsd.org/chv.cgi?CH=72890 Change 72890 by pjd@pjd_anger on 2005/03/11 12:16:51 Add '-F' options which allows to specify file which contains process' PID. Affected files ... .. //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#3 edit .. //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#2 edit Differences ... ==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#3 (text+ko) ==== @@ -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 @@ 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 ==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#2 (text+ko) ==== @@ -69,6 +69,9 @@ #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 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 @@ char buf[_POSIX2_LINE_MAX], *mstr, **pargv, *p, *q; const char *execf, *coref; int debug_opt; - int i, ch, bestidx, rv, criteria; + int i, ch, bestidx, rv, criteria, pidfromfile; size_t jsz; void (*action)(struct kinfo_proc *); struct kinfo_proc *kp; @@ -166,13 +170,18 @@ criteria = 0; debug_opt = 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; @@ -330,6 +339,11 @@ 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; @@ -578,3 +592,33 @@ 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); +}