diff options
author | Alexander Shishkin <virtuoso@slind.org> | 2009-07-29 01:35:13 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-07-29 01:35:13 +0200 |
commit | e766f6213259d4cb3b3b0ce09aa43690215bfe4e (patch) | |
tree | 8a73d1e4a4408e3bec91f31695612f2aeaa4f4d8 | |
parent | 09449630fbf0331a76a9d055fcbff0774c57ab65 (diff) | |
download | busybox-w32-e766f6213259d4cb3b3b0ce09aa43690215bfe4e.tar.gz busybox-w32-e766f6213259d4cb3b3b0ce09aa43690215bfe4e.tar.bz2 busybox-w32-e766f6213259d4cb3b3b0ce09aa43690215bfe4e.zip |
make find_pid_by_name look at /proc/PID/exe too
function old new delta
procps_scan 1642 1709 +67
find_pid_by_name 193 223 +30
free_procps_scan 29 37 +8
Signed-off-by: Alexander Shishkin <virtuoso@slind.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/libbb.h | 3 | ||||
-rw-r--r-- | libbb/find_pid_by_name.c | 22 | ||||
-rw-r--r-- | libbb/procps.c | 18 |
3 files changed, 27 insertions, 16 deletions
diff --git a/include/libbb.h b/include/libbb.h index c7b4de13c..51ac69ed5 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1280,6 +1280,7 @@ typedef struct procps_status_t { | |||
1280 | /* Fields are set to 0/NULL if failed to determine (or not requested) */ | 1280 | /* Fields are set to 0/NULL if failed to determine (or not requested) */ |
1281 | uint16_t argv_len; | 1281 | uint16_t argv_len; |
1282 | char *argv0; | 1282 | char *argv0; |
1283 | char *exe; | ||
1283 | IF_SELINUX(char *context;) | 1284 | IF_SELINUX(char *context;) |
1284 | /* Everything below must contain no ptrs to malloc'ed data: | 1285 | /* Everything below must contain no ptrs to malloc'ed data: |
1285 | * it is memset(0) for each process in procps_scan() */ | 1286 | * it is memset(0) for each process in procps_scan() */ |
@@ -1327,7 +1328,7 @@ enum { | |||
1327 | PSSCAN_COMM = 1 << 5, | 1328 | PSSCAN_COMM = 1 << 5, |
1328 | /* PSSCAN_CMD = 1 << 6, - use read_cmdline instead */ | 1329 | /* PSSCAN_CMD = 1 << 6, - use read_cmdline instead */ |
1329 | PSSCAN_ARGV0 = 1 << 7, | 1330 | PSSCAN_ARGV0 = 1 << 7, |
1330 | /* PSSCAN_EXE = 1 << 8, - not implemented */ | 1331 | PSSCAN_EXE = 1 << 8, |
1331 | PSSCAN_STATE = 1 << 9, | 1332 | PSSCAN_STATE = 1 << 9, |
1332 | PSSCAN_VSZ = 1 << 10, | 1333 | PSSCAN_VSZ = 1 << 10, |
1333 | PSSCAN_RSS = 1 << 11, | 1334 | PSSCAN_RSS = 1 << 11, |
diff --git a/libbb/find_pid_by_name.c b/libbb/find_pid_by_name.c index 600d4e1a8..52a0c6dab 100644 --- a/libbb/find_pid_by_name.c +++ b/libbb/find_pid_by_name.c | |||
@@ -41,18 +41,20 @@ and therefore comm field contains "exe". | |||
41 | static int comm_match(procps_status_t *p, const char *procName) | 41 | static int comm_match(procps_status_t *p, const char *procName) |
42 | { | 42 | { |
43 | int argv1idx; | 43 | int argv1idx; |
44 | const char *argv1; | ||
44 | 45 | ||
45 | /* comm does not match */ | ||
46 | if (strncmp(p->comm, procName, 15) != 0) | 46 | if (strncmp(p->comm, procName, 15) != 0) |
47 | return 0; | 47 | return 0; /* comm does not match */ |
48 | 48 | ||
49 | /* in Linux, if comm is 15 chars, it may be a truncated */ | 49 | /* In Linux, if comm is 15 chars, it is truncated. |
50 | if (p->comm[14] == '\0') /* comm is not truncated - match */ | 50 | * (or maybe the name was exactly 15 chars, but there is |
51 | return 1; | 51 | * no way to know that) */ |
52 | if (p->comm[14] == '\0') | ||
53 | return 1; /* comm is not truncated - matches */ | ||
52 | 54 | ||
53 | /* comm is truncated, but first 15 chars match. | 55 | /* comm is truncated, but first 15 chars match. |
54 | * This can be crazily_long_script_name.sh! | 56 | * This can be crazily_long_script_name.sh! |
55 | * The telltale sign is basename(argv[1]) == procName. */ | 57 | * The telltale sign is basename(argv[1]) == procName */ |
56 | 58 | ||
57 | if (!p->argv0) | 59 | if (!p->argv0) |
58 | return 0; | 60 | return 0; |
@@ -60,8 +62,9 @@ static int comm_match(procps_status_t *p, const char *procName) | |||
60 | argv1idx = strlen(p->argv0) + 1; | 62 | argv1idx = strlen(p->argv0) + 1; |
61 | if (argv1idx >= p->argv_len) | 63 | if (argv1idx >= p->argv_len) |
62 | return 0; | 64 | return 0; |
65 | argv1 = p->argv0 + argv1idx; | ||
63 | 66 | ||
64 | if (strcmp(bb_basename(p->argv0 + argv1idx), procName) != 0) | 67 | if (strcmp(bb_basename(argv1), procName) != 0) |
65 | return 0; | 68 | return 0; |
66 | 69 | ||
67 | return 1; | 70 | return 1; |
@@ -83,11 +86,12 @@ pid_t* FAST_FUNC find_pid_by_name(const char *procName) | |||
83 | procps_status_t* p = NULL; | 86 | procps_status_t* p = NULL; |
84 | 87 | ||
85 | pidList = xzalloc(sizeof(*pidList)); | 88 | pidList = xzalloc(sizeof(*pidList)); |
86 | while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN))) { | 89 | while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN|PSSCAN_EXE))) { |
87 | if (comm_match(p, procName) | 90 | if (comm_match(p, procName) |
88 | /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/ | 91 | /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/ |
89 | || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0) | 92 | || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0) |
90 | /* TODO: we can also try /proc/NUM/exe link, do we want that? */ | 93 | /* or we require /proc/PID/exe link to match */ |
94 | || (p->exe && strcmp(bb_basename(p->exe), procName) == 0) | ||
91 | ) { | 95 | ) { |
92 | pidList = xrealloc_vector(pidList, 2, i); | 96 | pidList = xrealloc_vector(pidList, 2, i); |
93 | pidList[i++] = p->pid; | 97 | pidList[i++] = p->pid; |
diff --git a/libbb/procps.c b/libbb/procps.c index 6e122c4d5..307d8d622 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -111,6 +111,7 @@ void FAST_FUNC free_procps_scan(procps_status_t* sp) | |||
111 | { | 111 | { |
112 | closedir(sp->dir); | 112 | closedir(sp->dir); |
113 | free(sp->argv0); | 113 | free(sp->argv0); |
114 | free(sp->exe); | ||
114 | IF_SELINUX(free(sp->context);) | 115 | IF_SELINUX(free(sp->context);) |
115 | free(sp); | 116 | free(sp); |
116 | } | 117 | } |
@@ -213,7 +214,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
213 | } | 214 | } |
214 | #endif | 215 | #endif |
215 | 216 | ||
216 | filename_tail = filename + sprintf(filename, "/proc/%d", pid); | 217 | filename_tail = filename + sprintf(filename, "/proc/%u/", pid); |
217 | 218 | ||
218 | if (flags & PSSCAN_UIDGID) { | 219 | if (flags & PSSCAN_UIDGID) { |
219 | if (stat(filename, &sb)) | 220 | if (stat(filename, &sb)) |
@@ -230,7 +231,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
230 | unsigned long vsz, rss; | 231 | unsigned long vsz, rss; |
231 | #endif | 232 | #endif |
232 | /* see proc(5) for some details on this */ | 233 | /* see proc(5) for some details on this */ |
233 | strcpy(filename_tail, "/stat"); | 234 | strcpy(filename_tail, "stat"); |
234 | n = read_to_buf(filename, buf); | 235 | n = read_to_buf(filename, buf); |
235 | if (n < 0) | 236 | if (n < 0) |
236 | break; | 237 | break; |
@@ -340,7 +341,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
340 | if (flags & (PSSCAN_SMAPS)) { | 341 | if (flags & (PSSCAN_SMAPS)) { |
341 | FILE *file; | 342 | FILE *file; |
342 | 343 | ||
343 | strcpy(filename_tail, "/smaps"); | 344 | strcpy(filename_tail, "smaps"); |
344 | file = fopen_for_read(filename); | 345 | file = fopen_for_read(filename); |
345 | if (!file) | 346 | if (!file) |
346 | break; | 347 | break; |
@@ -390,7 +391,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
390 | if (flags & PSSCAN_RUIDGID) { | 391 | if (flags & PSSCAN_RUIDGID) { |
391 | FILE *file; | 392 | FILE *file; |
392 | 393 | ||
393 | strcpy(filename_tail, "/status"); | 394 | strcpy(filename_tail, "status"); |
394 | file = fopen_for_read(filename); | 395 | file = fopen_for_read(filename); |
395 | if (!file) | 396 | if (!file) |
396 | break; | 397 | break; |
@@ -415,7 +416,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
415 | sp->argv0 = NULL; | 416 | sp->argv0 = NULL; |
416 | free(sp->cmd); | 417 | free(sp->cmd); |
417 | sp->cmd = NULL; | 418 | sp->cmd = NULL; |
418 | strcpy(filename_tail, "/cmdline"); | 419 | strcpy(filename_tail, "cmdline"); |
419 | /* TODO: to get rid of size limits, read into malloc buf, | 420 | /* TODO: to get rid of size limits, read into malloc buf, |
420 | * then realloc it down to real size. */ | 421 | * then realloc it down to real size. */ |
421 | n = read_to_buf(filename, buf); | 422 | n = read_to_buf(filename, buf); |
@@ -436,7 +437,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
436 | if (flags & (PSSCAN_ARGV0|PSSCAN_ARGVN)) { | 437 | if (flags & (PSSCAN_ARGV0|PSSCAN_ARGVN)) { |
437 | free(sp->argv0); | 438 | free(sp->argv0); |
438 | sp->argv0 = NULL; | 439 | sp->argv0 = NULL; |
439 | strcpy(filename_tail, "/cmdline"); | 440 | strcpy(filename_tail, "cmdline"); |
440 | n = read_to_buf(filename, buf); | 441 | n = read_to_buf(filename, buf); |
441 | if (n <= 0) | 442 | if (n <= 0) |
442 | break; | 443 | break; |
@@ -451,6 +452,11 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
451 | } | 452 | } |
452 | } | 453 | } |
453 | #endif | 454 | #endif |
455 | if (flags & PSSCAN_EXE) { | ||
456 | strcpy(filename_tail, "exe"); | ||
457 | free(sp->exe); | ||
458 | sp->exe = xmalloc_readlink(filename); | ||
459 | } | ||
454 | break; | 460 | break; |
455 | } | 461 | } |
456 | return sp; | 462 | return sp; |