aboutsummaryrefslogtreecommitdiff
path: root/procps/pgrep.c
diff options
context:
space:
mode:
Diffstat (limited to 'procps/pgrep.c')
-rw-r--r--procps/pgrep.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/procps/pgrep.c b/procps/pgrep.c
index 3d01c6cff..a3ca9e295 100644
--- a/procps/pgrep.c
+++ b/procps/pgrep.c
@@ -7,16 +7,16 @@
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */ 8 */
9//config:config PGREP 9//config:config PGREP
10//config: bool "pgrep" 10//config: bool "pgrep (6.8 kb)"
11//config: default y 11//config: default y
12//config: help 12//config: help
13//config: Look for processes by name. 13//config: Look for processes by name.
14//config: 14//config:
15//config:config PKILL 15//config:config PKILL
16//config: bool "pkill" 16//config: bool "pkill (7.6 kb)"
17//config: default y 17//config: default y
18//config: help 18//config: help
19//config: Send signals to processes by name. 19//config: Send signals to processes by name.
20 20
21//applet:IF_PGREP(APPLET(pgrep, BB_DIR_USR_BIN, BB_SUID_DROP)) 21//applet:IF_PGREP(APPLET(pgrep, BB_DIR_USR_BIN, BB_SUID_DROP))
22// APPLET_ODDNAME:name main location suid_type help 22// APPLET_ODDNAME:name main location suid_type help
@@ -155,15 +155,18 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv)
155 proc = NULL; 155 proc = NULL;
156 while ((proc = procps_scan(proc, scan_mask)) != NULL) { 156 while ((proc = procps_scan(proc, scan_mask)) != NULL) {
157 char *cmd; 157 char *cmd;
158 int cmdlen; 158 int cmdlen, match;
159 159
160 if (proc->pid == pid) 160 if (proc->pid == pid)
161 continue; 161 continue;
162 162
163 if (ppid2match >= 0 && ppid2match != proc->ppid) 163 if (!OPT_INVERT) {
164 continue; 164 /* Quickly reject -sN -PN mismatches... unless -v */
165 if (sid2match >= 0 && sid2match != proc->sid) 165 if (ppid2match >= 0 && ppid2match != proc->ppid)
166 continue; 166 continue;
167 if (sid2match >= 0 && sid2match != proc->sid)
168 continue;
169 }
167 170
168 cmdlen = -1; 171 cmdlen = -1;
169 cmd = proc->argv0; 172 cmd = proc->argv0;
@@ -186,12 +189,36 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv)
186 } 189 }
187 } 190 }
188 191
192 if (OPT_INVERT) {
193 /* "pgrep -v -P1 firefox" means "not (ppid=1 AND name=firefox)"
194 * or equivalently "ppid!=1 OR name!=firefox".
195 * Check the first condition and if true, skip matching.
196 */
197 if (ppid2match >= 0 && ppid2match != proc->ppid)
198 goto got_it;
199 if (sid2match >= 0 && sid2match != proc->sid)
200 goto got_it;
201 }
202
203 match = !argv[0]; /* if no PATTERN, then it's a match, else... */
204 if (!match) {
205 again:
206 match = (regexec(&re_buffer, cmd, 1, re_match, 0) == 0);
207 if (!match && cmd != proc->comm) {
208 /* if argv[] did not match, try comm */
209 cmdlen = -1;
210 cmd = proc->comm;
211 goto again;
212 }
213 if (match && OPT_ANCHOR) {
214 /* -x requires full string match */
215 match = (re_match[0].rm_so == 0 && cmd[re_match[0].rm_eo] == '\0');
216 }
217 }
218
189 /* NB: OPT_INVERT is always 0 or 1 */ 219 /* NB: OPT_INVERT is always 0 or 1 */
190 if (!argv[0] 220 if (match ^ OPT_INVERT) {
191 || (regexec(&re_buffer, cmd, 1, re_match, 0) == 0 /* match found */ 221 got_it:
192 && (!OPT_ANCHOR || (re_match[0].rm_so == 0 && re_match[0].rm_eo == (regoff_t)strlen(cmd)))
193 ) ^ OPT_INVERT
194 ) {
195 matched_pid = proc->pid; 222 matched_pid = proc->pid;
196 if (OPT_LAST) { 223 if (OPT_LAST) {
197 free(cmd_last); 224 free(cmd_last);