aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-07-11 14:00:07 -0700
committerRob Landley <rob@landley.net>2019-07-12 13:18:11 -0500
commita7b8b772dee4f159028e3b998454d7466fbbc88f (patch)
treef8cdf969a4a42ff39bad63e5d3a7aaf4844cb541 /lib
parent5194d4ad66ad130cb730e0b192ba1e2b5181184d (diff)
downloadtoybox-a7b8b772dee4f159028e3b998454d7466fbbc88f.tar.gz
pidof: fix default behavior, add -x.
Before this patch, we're effectively doing `pidof -x` all the time. This patch changes names_to_pid() to allow us to say whether or not we want to include scripts, and adjusts the callers appropriately. Also add tests for `pidof` versus `pidof -x` which pass after this patch, without regressing the existing killall tests.
Diffstat (limited to 'lib')
-rw-r--r--lib/lib.c21
-rw-r--r--lib/lib.h3
2 files changed, 14 insertions, 10 deletions
diff --git a/lib/lib.c b/lib/lib.c
index e00278c5..47e5ca21 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -1041,7 +1041,8 @@ char *fileunderdir(char *file, char *dir)
}
// Execute a callback for each PID that matches a process name from a list.
-void names_to_pid(char **names, int (*callback)(pid_t pid, char *name))
+void names_to_pid(char **names, int (*callback)(pid_t pid, char *name),
+ int scripts)
{
DIR *dp;
struct dirent *entry;
@@ -1050,18 +1051,20 @@ void names_to_pid(char **names, int (*callback)(pid_t pid, char *name))
while ((entry = readdir(dp))) {
unsigned u = atoi(entry->d_name);
- char *cmd = 0, *comm, **cur;
+ char *cmd = 0, *comm = 0, **cur;
off_t len;
if (!u) continue;
// Comm is original name of executable (argv[0] could be #! interpreter)
// but it's limited to 15 characters
- sprintf(libbuf, "/proc/%u/comm", u);
- len = sizeof(libbuf);
- if (!(comm = readfileat(AT_FDCWD, libbuf, libbuf, &len)) || !len)
- continue;
- if (libbuf[len-1] == '\n') libbuf[--len] = 0;
+ if (scripts) {
+ sprintf(libbuf, "/proc/%u/comm", u);
+ len = sizeof(libbuf);
+ if (!(comm = readfileat(AT_FDCWD, libbuf, libbuf, &len)) || !len)
+ continue;
+ if (libbuf[len-1] == '\n') libbuf[--len] = 0;
+ }
for (cur = names; *cur; cur++) {
struct stat st1, st2;
@@ -1071,7 +1074,7 @@ void names_to_pid(char **names, int (*callback)(pid_t pid, char *name))
// Fast path: only matching a filename (no path) that fits in comm.
// `len` must be 14 or less because with a full 15 bytes we don't
// know whether the name fit or was truncated.
- if (len<=14 && bb==*cur && !strcmp(comm, bb)) goto match;
+ if (scripts && len<=14 && bb==*cur && !strcmp(comm, bb)) goto match;
// If we have a path to existing file only match if same inode
if (bb!=*cur && !stat(*cur, &st1)) {
@@ -1093,7 +1096,7 @@ void names_to_pid(char **names, int (*callback)(pid_t pid, char *name))
cmd[len] = 0;
}
if (!strcmp(bb, getbasename(cmd))) goto match;
- if (!strcmp(bb, getbasename(cmd+strlen(cmd)+1))) goto match;
+ if (scripts && !strcmp(bb, getbasename(cmd+strlen(cmd)+1))) goto match;
continue;
match:
if (callback(u, *cur)) break;
diff --git a/lib/lib.h b/lib/lib.h
index e744977f..9c5e9a37 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -401,7 +401,8 @@ void mode_to_string(mode_t mode, char *buf);
char *getdirname(char *name);
char *getbasename(char *name);
char *fileunderdir(char *file, char *dir);
-void names_to_pid(char **names, int (*callback)(pid_t pid, char *name));
+void names_to_pid(char **names, int (*callback)(pid_t pid, char *name),
+ int scripts);
pid_t __attribute__((returns_twice)) xvforkwrap(pid_t pid);
#define XVFORK() xvforkwrap(vfork())