aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-21 17:43:14 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-21 17:43:14 +0200
commit578008a9897b2d64532ed5843807c05fba1f862f (patch)
tree3563c3ec8ffa64e46d019dda3cd520dc21061e05
parent67d42dfdea3fc85e6777689a96b92761084706dc (diff)
downloadbusybox-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.c47
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);