//config: bool "pgrep (6.8 kb)"
//config: default y
//config: help
-//config: Look for processes by name.
+//config: Look for processes by name.
//config:
//config:config PKILL
//config: bool "pkill (7.6 kb)"
//config: default y
//config: help
-//config: Send signals to processes by name.
+//config: Send signals to processes by name.
-//applet:IF_PGREP(APPLET(pgrep, BB_DIR_USR_BIN, BB_SUID_DROP))
+//applet:IF_PGREP(APPLET_ODDNAME(pgrep, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pgrep))
// APPLET_ODDNAME:name main location suid_type help
//applet:IF_PKILL(APPLET_ODDNAME(pkill, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pkill))
+/* can't be noexec: can find _itself_ under wrong name, since after fork only,
+ * /proc/PID/cmdline and comm are wrong! Can fix comm (prctl(PR_SET_NAME)),
+ * but cmdline?
+ */
//kbuild:lib-$(CONFIG_PGREP) += pgrep.o
//kbuild:lib-$(CONFIG_PKILL) += pgrep.o
proc = NULL;
while ((proc = procps_scan(proc, scan_mask)) != NULL) {
char *cmd;
- int cmdlen;
+ int cmdlen, match;
if (proc->pid == pid)
continue;
- if (ppid2match >= 0 && ppid2match != proc->ppid)
- continue;
- if (sid2match >= 0 && sid2match != proc->sid)
- continue;
+ if (!OPT_INVERT) {
+ /* Quickly reject -sN -PN mismatches... unless -v */
+ if (ppid2match >= 0 && ppid2match != proc->ppid)
+ continue;
+ if (sid2match >= 0 && sid2match != proc->sid)
+ continue;
+ }
cmdlen = -1;
cmd = proc->argv0;
}
}
+ if (OPT_INVERT) {
+ /* "pgrep -v -P1 firefox" means "not (ppid=1 AND name=firefox)"
+ * or equivalently "ppid!=1 OR name!=firefox".
+ * Check the first condition and if true, skip matching.
+ */
+ if (ppid2match >= 0 && ppid2match != proc->ppid)
+ goto got_it;
+ if (sid2match >= 0 && sid2match != proc->sid)
+ goto got_it;
+ }
+
+ match = !argv[0]; /* if no PATTERN, then it's a match, else... */
+ if (!match) {
+ again:
+ match = (regexec(&re_buffer, cmd, 1, re_match, 0) == 0);
+ if (!match && cmd != proc->comm) {
+ /* if argv[] did not match, try comm */
+ cmdlen = -1;
+ cmd = proc->comm;
+ goto again;
+ }
+ if (match && OPT_ANCHOR) {
+ /* -x requires full string match */
+ match = (re_match[0].rm_so == 0 && cmd[re_match[0].rm_eo] == '\0');
+ }
+ }
+
/* NB: OPT_INVERT is always 0 or 1 */
- if (!argv[0]
- || (regexec(&re_buffer, cmd, 1, re_match, 0) == 0 /* match found */
- && (!OPT_ANCHOR || (re_match[0].rm_so == 0 && re_match[0].rm_eo == (regoff_t)strlen(cmd)))
- ) ^ OPT_INVERT
- ) {
+ if (match ^ OPT_INVERT) {
+ got_it:
matched_pid = proc->pid;
if (OPT_LAST) {
free(cmd_last);