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