diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-21 17:43:14 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-21 17:43:14 +0200 |
commit | 578008a9897b2d64532ed5843807c05fba1f862f (patch) | |
tree | 3563c3ec8ffa64e46d019dda3cd520dc21061e05 | |
parent | 67d42dfdea3fc85e6777689a96b92761084706dc (diff) | |
download | busybox-w32-578008a9897b2d64532ed5843807c05fba1f862f.tar.gz busybox-w32-578008a9897b2d64532ed5843807c05fba1f862f.tar.bz2 busybox-w32-578008a9897b2d64532ed5843807c05fba1f862f.zip |
pgrep: fix "pgrep -v -P1"; also allow matching of comm - closes 10086
function old new delta
pgrep_main 662 720 +58
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | procps/pgrep.c | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/procps/pgrep.c b/procps/pgrep.c index 327f6a934..a3ca9e295 100644 --- a/procps/pgrep.c +++ b/procps/pgrep.c | |||
@@ -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); |