Index: pkill.1 =================================================================== --- pkill.1 (revision 253889) +++ pkill.1 (working copy) @@ -29,7 +29,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd February 11, 2010 +.Dd August 5, 2013 .Dt PKILL 1 .Os .Sh NAME @@ -44,6 +44,7 @@ .Op Fl N Ar system .Op Fl P Ar ppid .Op Fl U Ar uid +.Op Fl c Ar class .Op Fl d Ar delim .Op Fl g Ar pgrp .Op Fl j Ar jid @@ -60,6 +61,7 @@ .Op Fl N Ar system .Op Fl P Ar ppid .Op Fl U Ar uid +.Op Fl c Ar class .Op Fl g Ar pgrp .Op Fl j Ar jid .Op Fl s Ar sid @@ -130,6 +132,9 @@ or process and all of its ancestors are excluded (unless .Fl v is used). +.It Fl c Ar class +Restrict matches to processes running with specified login class +.Ar class . .It Fl f Match against full argument lists. The default is to match against process names. Index: pkill.c =================================================================== --- pkill.c (revision 253889) +++ pkill.c (working copy) @@ -79,12 +79,14 @@ enum listtype { LT_TTY, LT_PGRP, LT_JID, - LT_SID + LT_SID, + LT_CLASS }; struct list { SLIST_ENTRY(list) li_chain; long li_number; + char *li_name; }; SLIST_HEAD(listhead, list); @@ -116,6 +118,7 @@ static struct listhead ppidlist = SLIST_HEAD_INITI static struct listhead tdevlist = SLIST_HEAD_INITIALIZER(tdevlist); static struct listhead sidlist = SLIST_HEAD_INITIALIZER(sidlist); static struct listhead jidlist = SLIST_HEAD_INITIALIZER(jidlist); +static struct listhead classlist = SLIST_HEAD_INITIALIZER(classlist); static void usage(void) __attribute__((__noreturn__)); static int killact(const struct kinfo_proc *); @@ -179,7 +182,7 @@ main(int argc, char **argv) execf = NULL; coref = _PATH_DEVNULL; - while ((ch = getopt(argc, argv, "DF:G:ILM:N:P:SU:ad:fg:ij:lnoqs:t:u:vx")) != -1) + while ((ch = getopt(argc, argv, "DF:G:ILM:N:P:SU:ac:d:fg:ij:lnoqs:t:u:vx")) != -1) switch (ch) { case 'D': debug_opt++; @@ -222,6 +225,10 @@ main(int argc, char **argv) case 'a': ancestors++; break; + case 'c': + makelist(&classlist, LT_CLASS, optarg); + criteria = 1; + break; case 'd': if (!pgrep) usage(); @@ -469,6 +476,16 @@ main(int argc, char **argv) continue; } + SLIST_FOREACH(li, &classlist, li_chain) { + if (kp->ki_loginclass != NULL && + strcmp(kp->ki_loginclass, li->li_name) == 0) + break; + } + if (SLIST_FIRST(&classlist) != NULL && li == NULL) { + selected[i] = 0; + continue; + } + if (argc == 0) selected[i] = 1; } @@ -562,9 +579,9 @@ usage(void) fprintf(stderr, "usage: %s %s [-F pidfile] [-G gid] [-M core] [-N system]\n" - " [-P ppid] [-U uid] [-g pgrp] [-j jid] [-s sid]\n" - " [-t tty] [-u euid] pattern ...\n", getprogname(), - ustr); + " [-P ppid] [-U uid] [-c class] [-g pgrp] [-j jid]\n" + " [-s sid] [-t tty] [-u euid] pattern ...\n", + getprogname(), ustr); exit(STATUS_BADUSAGE); } @@ -664,8 +681,10 @@ makelist(struct listhead *head, enum listtype type SLIST_INSERT_HEAD(head, li, li_chain); empty = 0; - li->li_number = (uid_t)strtol(sp, &ep, 0); - if (*ep == '\0') { + if (type != LT_CLASS) + li->li_number = (uid_t)strtol(sp, &ep, 0); + + if (type != LT_CLASS && *ep == '\0') { switch (type) { case LT_PGRP: if (li->li_number == 0) @@ -750,6 +769,12 @@ foundtty: if ((st.st_mode & S_IFCHR) == 0) errx(STATUS_BADUSAGE, "Invalid jail ID `%s'", sp); break; + case LT_CLASS: + li->li_number = -1; + li->li_name = strdup(sp); + if (li->li_name == NULL) + err(STATUS_ERROR, "Cannot allocate memory"); + break; default: usage(); }