41 |
static int comm_match(procps_status_t *p, const char *procName) |
static int comm_match(procps_status_t *p, const char *procName) |
42 |
{ |
{ |
43 |
int argv1idx; |
int argv1idx; |
44 |
|
const char *argv1; |
45 |
|
|
|
/* comm does not match */ |
|
46 |
if (strncmp(p->comm, procName, 15) != 0) |
if (strncmp(p->comm, procName, 15) != 0) |
47 |
return 0; |
return 0; /* comm does not match */ |
48 |
|
|
49 |
/* in Linux, if comm is 15 chars, it may be a truncated */ |
/* In Linux, if comm is 15 chars, it is truncated. |
50 |
if (p->comm[14] == '\0') /* comm is not truncated - match */ |
* (or maybe the name was exactly 15 chars, but there is |
51 |
return 1; |
* no way to know that) */ |
52 |
|
if (p->comm[14] == '\0') |
53 |
|
return 1; /* comm is not truncated - matches */ |
54 |
|
|
55 |
/* comm is truncated, but first 15 chars match. |
/* comm is truncated, but first 15 chars match. |
56 |
* This can be crazily_long_script_name.sh! |
* This can be crazily_long_script_name.sh! |
57 |
* The telltale sign is basename(argv[1]) == procName. */ |
* The telltale sign is basename(argv[1]) == procName */ |
58 |
|
|
59 |
if (!p->argv0) |
if (!p->argv0) |
60 |
return 0; |
return 0; |
62 |
argv1idx = strlen(p->argv0) + 1; |
argv1idx = strlen(p->argv0) + 1; |
63 |
if (argv1idx >= p->argv_len) |
if (argv1idx >= p->argv_len) |
64 |
return 0; |
return 0; |
65 |
|
argv1 = p->argv0 + argv1idx; |
66 |
|
|
67 |
if (strcmp(bb_basename(p->argv0 + argv1idx), procName) != 0) |
if (strcmp(bb_basename(argv1), procName) != 0) |
68 |
return 0; |
return 0; |
69 |
|
|
70 |
return 1; |
return 1; |
71 |
} |
} |
72 |
|
|
73 |
/* find_pid_by_name() |
/* This finds the pid of the specified process. |
74 |
|
* Currently, it's implemented by rummaging through |
75 |
|
* the proc filesystem. |
76 |
* |
* |
77 |
* Modified by Vladimir Oleynik for use with libbb/procps.c |
* Returns a list of all matching PIDs |
78 |
* This finds the pid of the specified process. |
* It is the caller's duty to free the returned pidlist. |
|
* Currently, it's implemented by rummaging through |
|
|
* the proc filesystem. |
|
79 |
* |
* |
80 |
* Returns a list of all matching PIDs |
* Modified by Vladimir Oleynik for use with libbb/procps.c |
|
* It is the caller's duty to free the returned pidlist. |
|
81 |
*/ |
*/ |
82 |
pid_t* FAST_FUNC find_pid_by_name(const char *procName) |
pid_t* FAST_FUNC find_pid_by_name(const char *procName) |
83 |
{ |
{ |
86 |
procps_status_t* p = NULL; |
procps_status_t* p = NULL; |
87 |
|
|
88 |
pidList = xzalloc(sizeof(*pidList)); |
pidList = xzalloc(sizeof(*pidList)); |
89 |
while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN))) { |
while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN|PSSCAN_EXE))) { |
90 |
if (comm_match(p, procName) |
if (comm_match(p, procName) |
91 |
/* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/ |
/* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/ |
92 |
|| (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0) |
|| (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0) |
93 |
/* TODO: we can also try /proc/NUM/exe link, do we want that? */ |
/* or we require /proc/PID/exe link to match */ |
94 |
|
|| (p->exe && strcmp(bb_basename(p->exe), procName) == 0) |
95 |
) { |
) { |
96 |
pidList = xrealloc_vector(pidList, 2, i); |
pidList = xrealloc_vector(pidList, 2, i); |
97 |
pidList[i++] = p->pid; |
pidList[i++] = p->pid; |