1fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley/* pgrep.c - pgrep and pkill implementation 2fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley * 3fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley * Copyright 2012 Madhur Verma <mad.flexi@gmail.com> 41c8b0090a6529ce35f877973778e7814387c1e3fRob Landley * Copyright 2013 Kyungwan Han <asura321@gmail.com> 5fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley * 6fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 7fe850691155be9a23cc1480e7afdb77028d87e78Rob LandleyUSE_PGREP(NEWTOY(pgrep, "?P# s# xvonlf[!sP]", TOYFLAG_USR|TOYFLAG_BIN)) 8f3e56f4e4ff773de95fa2c9daf979734d826fc33Rob LandleyUSE_PGREP(OLDTOY(pkill, pgrep, TOYFLAG_USR|TOYFLAG_BIN)) 9fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 10fe850691155be9a23cc1480e7afdb77028d87e78Rob Landleyconfig PGREP 11fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley bool "pgrep" 12fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley default n 13fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley help 14fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley usage: pgrep [-flnovx] [-s SID|-P PPID|PATTERN] 15fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley pkill [-l|-SIGNAL] [-fnovx] [-s SID|-P PPID|PATTERN] 16fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 17fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley -l Show command name too / List all signals 18fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley -f Match against entire command line 19fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley -n Show/Signal the newest process only 20fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley -o Show/Signal the oldest process only 21fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley -v Negate the match 22fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley -x Match whole name (not substring) 23fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley -s Match session ID (0 for current) 24fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley -P Match parent process ID 25fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley*/ 26fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 27fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley#define FOR_pgrep 28fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley#include "toys.h" 29fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley#include <regex.h> 30fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 31fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley#define flag_get(f,v,d) ((toys.optflags & f) ? v : d) 32fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley#define flag_chk(f) ((toys.optflags & f) ? 1 : 0) 33fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 34fe850691155be9a23cc1480e7afdb77028d87e78Rob LandleyGLOBALS( 35fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley long sid; //-s 36fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley long ppid; //-P 37fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley char *signame; 38fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley) 39fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 40fe850691155be9a23cc1480e7afdb77028d87e78Rob Landleystatic int exec_action(unsigned pid, char *name, int signal) 41fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley{ 42fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (toys.which->name[1] == 'g') { 43fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley printf("%d", pid); 44fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_l)) printf(" %s", name); 45fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley printf("\n"); 46fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } else { 47fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley kill(pid, signal); 48fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 49fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley return 0; 50fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley} 51fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 52fe850691155be9a23cc1480e7afdb77028d87e78Rob Landleystatic int regex_match(regex_t *rp, char *tar, char *patt) 53fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley{ 54fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley regmatch_t rm[1]; 55fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley int len = strlen(tar); 56fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (regexec(rp, tar, 1, rm, 0) == 0) { 57fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_x)) { 58fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if ((rm[0].rm_so == 0) && ((rm[0].rm_eo - rm[0].rm_so) == len)) return 1; 59fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } else return 1; 60fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 61fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley return 0; 62fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley} 63fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 64fe850691155be9a23cc1480e7afdb77028d87e78Rob Landleyvoid pgrep_main(void) 65fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley{ 66fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley int signum=0, eval=0, ret=1; 67fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley DIR *dp=NULL; 68fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley struct dirent *entry=NULL; 69fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley regex_t rp; 70fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley unsigned pid=0, ppid=0, sid=0, latest_pid=0; 71fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley char *cmdline=NULL, *latest_cmdline = NULL; 72fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley pid_t self = getpid(); 73fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 74fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (!(dp = opendir("/proc"))) perror_exit("OPENDIR: failed to open /proc"); 75fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley setlinebuf(stdout); 76fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 77fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (toys.which->name[1] == 'k') { 78fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_l)) { 79fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley sig_to_num(NULL); 80fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley return; 81fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 82fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (!TT.signame && *toys.optargs && **toys.optargs == '-') { 83fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley TT.signame = *(toys.optargs++) + 1; 84fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 85fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (TT.signame) { 86fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley char *arg; 87fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley int i = strtol(TT.signame, &arg, 10); 88fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (!*arg) arg = num_to_sig(i); 89fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley else arg = TT.signame; 90fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (!arg || (signum = sig_to_num(arg)) == -1) 91fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley error_exit("Unknown signal '%s'", arg); 92fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } else signum = SIGTERM; 93fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 94fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (!(flag_chk(FLAG_s) || flag_chk(FLAG_P)) && !*toys.optargs) { 95fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley toys.exithelp++; 96fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley error_exit("missing argument"); 97fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 98fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (*(toys.optargs+1) && !(flag_chk(FLAG_s) || flag_chk(FLAG_P))) { 99fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley toys.exithelp++; 100fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley error_exit("max argument > 1"); 101fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 102fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (*toys.optargs) { /* compile regular expression(PATTERN) */ 103fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if ((eval = regcomp(&rp, *toys.optargs, REG_EXTENDED | REG_NOSUB)) != 0) { 104fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley char errbuf[256]; 105fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley (void) regerror(eval, &rp, errbuf, sizeof(errbuf)); 106fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley error_exit("%s", errbuf); 107fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 108fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 109fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_s)&&(TT.sid==0)) TT.sid = getsid(0); 110fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley while ((entry = readdir(dp))) { 111fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley int fd = -1, n = 0; 112fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (!isdigit(*entry->d_name)) continue; 113fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 114fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley pid = strtol(entry->d_name, NULL, 10); 115fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (pid == self) continue; 116fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley 117fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley snprintf(toybuf, sizeof(toybuf), "/proc/%s/cmdline", entry->d_name); 118fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if ((fd = open(toybuf, O_RDONLY)) == -1) goto cmdline_fail; 119fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley n = read(fd, toybuf, sizeof(toybuf)); 120fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley close(fd); 121fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley toybuf[n--] = '\0'; 122fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (n < 0) { 123fe850691155be9a23cc1480e7afdb77028d87e78Rob Landleycmdline_fail: 124fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley snprintf(toybuf, sizeof(toybuf), "/proc/%s/comm", entry->d_name); 125fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if ((fd = open(toybuf, O_RDONLY)) == -1) continue; 126fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley n = read(fd, toybuf, sizeof(toybuf)); 127fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley close(fd); 128fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley toybuf[--n] = '\0'; 129fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (n < 1) continue; 130fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 131fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_f)) { 132fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley while (--n) 133fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (toybuf[n] < ' ') toybuf[n] = ' '; 134fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 135fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (cmdline) free(cmdline); 136fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley cmdline = xstrdup(toybuf); 137fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_s) || flag_chk(FLAG_P)) { 138fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley snprintf(toybuf, sizeof(toybuf), "/proc/%s/stat", entry->d_name); 139fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if ((fd = open(toybuf, O_RDONLY)) == -1) continue; 140fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley n = read(fd, toybuf, sizeof(toybuf)); 141fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley close(fd); 142fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (n<1) continue; 143fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley n = sscanf(toybuf, "%*u %*s %*c %u %*u %u", &ppid, &sid); 144fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_s)) if (sid != TT.sid) continue; 145fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_P)) if (ppid != TT.ppid) continue; 146fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 147fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (!*toys.optargs || (regex_match(&rp, cmdline, *toys.optargs)^flag_chk(FLAG_v))) { 148fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_n)) { 149fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (latest_cmdline) free(latest_cmdline); 150fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley latest_cmdline = xstrdup(cmdline); 151fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley latest_pid = pid; 152fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } else exec_action(pid, cmdline, signum); 153fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley ret = 0; 154fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (flag_chk(FLAG_o)) break; 155fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 156fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 157fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (cmdline) free(cmdline); 158fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (latest_cmdline) { 159fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley exec_action(latest_pid, latest_cmdline, signum); 160fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley free(latest_cmdline); 161fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley } 162fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley if (*toys.optargs) regfree(&rp); 163fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley closedir(dp); 164fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley toys.exitval = ret; 165fe850691155be9a23cc1480e7afdb77028d87e78Rob Landley} 166