pidof/killall: fix bug 625 (kernel threads get stale "binary name")
function old new delta procps_scan 1622 1642 +20 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
200d522fb8
commit
ed4ff0e8cb
133
libbb/procps.c
133
libbb/procps.c
@ -138,8 +138,8 @@ static unsigned long fast_strtoul_16(char **endptr)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
/* TOPMEM uses fast_strtoul_10, so... */
|
/* TOPMEM uses fast_strtoul_10, so... */
|
||||||
#undef ENABLE_FEATURE_FAST_TOP
|
# undef ENABLE_FEATURE_FAST_TOP
|
||||||
#define ENABLE_FEATURE_FAST_TOP 1
|
# define ENABLE_FEATURE_FAST_TOP 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLE_FEATURE_FAST_TOP
|
#if ENABLE_FEATURE_FAST_TOP
|
||||||
@ -223,14 +223,16 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* After this point we have to break, not continue
|
/* After this point we can:
|
||||||
* ("continue" would mean that current /proc/NNN
|
* "break": stop parsing, return the data
|
||||||
* is not a valid process info) */
|
* "continue": try next /proc/XXX
|
||||||
|
*/
|
||||||
|
|
||||||
memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz));
|
memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz));
|
||||||
|
|
||||||
sp->pid = pid;
|
sp->pid = pid;
|
||||||
if (!(flags & ~PSSCAN_PID)) break;
|
if (!(flags & ~PSSCAN_PID))
|
||||||
|
break; /* we needed only pid, we got it */
|
||||||
|
|
||||||
#if ENABLE_SELINUX
|
#if ENABLE_SELINUX
|
||||||
if (flags & PSSCAN_CONTEXT) {
|
if (flags & PSSCAN_CONTEXT) {
|
||||||
@ -243,7 +245,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
|
|||||||
|
|
||||||
if (flags & PSSCAN_UIDGID) {
|
if (flags & PSSCAN_UIDGID) {
|
||||||
if (stat(filename, &sb))
|
if (stat(filename, &sb))
|
||||||
break;
|
continue; /* process probably exited */
|
||||||
/* Effective UID/GID, not real */
|
/* Effective UID/GID, not real */
|
||||||
sp->uid = sb.st_uid;
|
sp->uid = sb.st_uid;
|
||||||
sp->gid = sb.st_gid;
|
sp->gid = sb.st_gid;
|
||||||
@ -259,10 +261,10 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
|
|||||||
strcpy(filename_tail, "stat");
|
strcpy(filename_tail, "stat");
|
||||||
n = read_to_buf(filename, buf);
|
n = read_to_buf(filename, buf);
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
break;
|
continue; /* process probably exited */
|
||||||
cp = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
|
cp = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
|
||||||
/*if (!cp || cp[1] != ' ')
|
/*if (!cp || cp[1] != ' ')
|
||||||
break;*/
|
continue;*/
|
||||||
cp[0] = '\0';
|
cp[0] = '\0';
|
||||||
if (sizeof(sp->comm) < 16)
|
if (sizeof(sp->comm) < 16)
|
||||||
BUG_comm_size();
|
BUG_comm_size();
|
||||||
@ -282,12 +284,12 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
|
|||||||
"%lu " /* start_time */
|
"%lu " /* start_time */
|
||||||
"%lu " /* vsize */
|
"%lu " /* vsize */
|
||||||
"%lu " /* rss */
|
"%lu " /* rss */
|
||||||
#if ENABLE_FEATURE_TOP_SMP_PROCESS
|
# if ENABLE_FEATURE_TOP_SMP_PROCESS
|
||||||
"%*s %*s %*s %*s %*s %*s " /*rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */
|
"%*s %*s %*s %*s %*s %*s " /*rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */
|
||||||
"%*s %*s %*s %*s " /*signal, blocked, sigignore, sigcatch */
|
"%*s %*s %*s %*s " /*signal, blocked, sigignore, sigcatch */
|
||||||
"%*s %*s %*s %*s " /*wchan, nswap, cnswap, exit_signal */
|
"%*s %*s %*s %*s " /*wchan, nswap, cnswap, exit_signal */
|
||||||
"%d" /*cpu last seen on*/
|
"%d" /*cpu last seen on*/
|
||||||
#endif
|
# endif
|
||||||
,
|
,
|
||||||
sp->state, &sp->ppid,
|
sp->state, &sp->ppid,
|
||||||
&sp->pgid, &sp->sid, &tty,
|
&sp->pgid, &sp->sid, &tty,
|
||||||
@ -296,17 +298,17 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
|
|||||||
&sp->start_time,
|
&sp->start_time,
|
||||||
&vsz,
|
&vsz,
|
||||||
&rss
|
&rss
|
||||||
#if ENABLE_FEATURE_TOP_SMP_PROCESS
|
# if ENABLE_FEATURE_TOP_SMP_PROCESS
|
||||||
, &sp->last_seen_on_cpu
|
, &sp->last_seen_on_cpu
|
||||||
#endif
|
# endif
|
||||||
);
|
);
|
||||||
|
|
||||||
if (n < 11)
|
if (n < 11)
|
||||||
break;
|
continue; /* bogus data, get next /proc/XXX */
|
||||||
#if ENABLE_FEATURE_TOP_SMP_PROCESS
|
# if ENABLE_FEATURE_TOP_SMP_PROCESS
|
||||||
if (n < 11+15)
|
if (n < 11+15)
|
||||||
sp->last_seen_on_cpu = 0;
|
sp->last_seen_on_cpu = 0;
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
/* vsz is in bytes and we want kb */
|
/* vsz is in bytes and we want kb */
|
||||||
sp->vsz = vsz >> 10;
|
sp->vsz = vsz >> 10;
|
||||||
@ -336,14 +338,14 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
|
|||||||
sp->vsz = fast_strtoul_10(&cp) >> 10;
|
sp->vsz = fast_strtoul_10(&cp) >> 10;
|
||||||
/* vsz is in bytes but rss is in *PAGES*! Can you believe that? */
|
/* vsz is in bytes but rss is in *PAGES*! Can you believe that? */
|
||||||
sp->rss = fast_strtoul_10(&cp) << sp->shift_pages_to_kb;
|
sp->rss = fast_strtoul_10(&cp) << sp->shift_pages_to_kb;
|
||||||
#if ENABLE_FEATURE_TOP_SMP_PROCESS
|
# if ENABLE_FEATURE_TOP_SMP_PROCESS
|
||||||
/* (6): rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */
|
/* (6): rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */
|
||||||
/* (4): signal, blocked, sigignore, sigcatch */
|
/* (4): signal, blocked, sigignore, sigcatch */
|
||||||
/* (4): wchan, nswap, cnswap, exit_signal */
|
/* (4): wchan, nswap, cnswap, exit_signal */
|
||||||
cp = skip_fields(cp, 14);
|
cp = skip_fields(cp, 14);
|
||||||
//FIXME: is it safe to assume this field exists?
|
//FIXME: is it safe to assume this field exists?
|
||||||
sp->last_seen_on_cpu = fast_strtoul_10(&cp);
|
sp->last_seen_on_cpu = fast_strtoul_10(&cp);
|
||||||
#endif
|
# endif
|
||||||
#endif /* end of !ENABLE_FEATURE_TOP_SMP_PROCESS */
|
#endif /* end of !ENABLE_FEATURE_TOP_SMP_PROCESS */
|
||||||
|
|
||||||
#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
|
#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
|
||||||
@ -368,48 +370,48 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
|
|||||||
|
|
||||||
strcpy(filename_tail, "smaps");
|
strcpy(filename_tail, "smaps");
|
||||||
file = fopen_for_read(filename);
|
file = fopen_for_read(filename);
|
||||||
if (!file)
|
if (file) {
|
||||||
break;
|
while (fgets(buf, sizeof(buf), file)) {
|
||||||
while (fgets(buf, sizeof(buf), file)) {
|
unsigned long sz;
|
||||||
unsigned long sz;
|
char *tp;
|
||||||
char *tp;
|
char w;
|
||||||
char w;
|
|
||||||
#define SCAN(str, name) \
|
#define SCAN(str, name) \
|
||||||
if (strncmp(buf, str, sizeof(str)-1) == 0) { \
|
if (strncmp(buf, str, sizeof(str)-1) == 0) { \
|
||||||
tp = skip_whitespace(buf + sizeof(str)-1); \
|
tp = skip_whitespace(buf + sizeof(str)-1); \
|
||||||
sp->name += fast_strtoul_10(&tp); \
|
sp->name += fast_strtoul_10(&tp); \
|
||||||
continue; \
|
continue; \
|
||||||
}
|
}
|
||||||
SCAN("Shared_Clean:" , shared_clean );
|
SCAN("Shared_Clean:" , shared_clean );
|
||||||
SCAN("Shared_Dirty:" , shared_dirty );
|
SCAN("Shared_Dirty:" , shared_dirty );
|
||||||
SCAN("Private_Clean:", private_clean);
|
SCAN("Private_Clean:", private_clean);
|
||||||
SCAN("Private_Dirty:", private_dirty);
|
SCAN("Private_Dirty:", private_dirty);
|
||||||
#undef SCAN
|
#undef SCAN
|
||||||
// f7d29000-f7d39000 rw-s ADR M:m OFS FILE
|
// f7d29000-f7d39000 rw-s ADR M:m OFS FILE
|
||||||
tp = strchr(buf, '-');
|
tp = strchr(buf, '-');
|
||||||
if (tp) {
|
if (tp) {
|
||||||
*tp = ' ';
|
*tp = ' ';
|
||||||
tp = buf;
|
tp = buf;
|
||||||
sz = fast_strtoul_16(&tp); /* start */
|
sz = fast_strtoul_16(&tp); /* start */
|
||||||
sz = (fast_strtoul_16(&tp) - sz) >> 10; /* end - start */
|
sz = (fast_strtoul_16(&tp) - sz) >> 10; /* end - start */
|
||||||
// tp -> "rw-s" string
|
// tp -> "rw-s" string
|
||||||
w = tp[1];
|
w = tp[1];
|
||||||
// skipping "rw-s ADR M:m OFS "
|
// skipping "rw-s ADR M:m OFS "
|
||||||
tp = skip_whitespace(skip_fields(tp, 4));
|
tp = skip_whitespace(skip_fields(tp, 4));
|
||||||
// filter out /dev/something (something != zero)
|
// filter out /dev/something (something != zero)
|
||||||
if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) {
|
if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) {
|
||||||
if (w == 'w') {
|
if (w == 'w') {
|
||||||
sp->mapped_rw += sz;
|
sp->mapped_rw += sz;
|
||||||
} else if (w == '-') {
|
} else if (w == '-') {
|
||||||
sp->mapped_ro += sz;
|
sp->mapped_ro += sz;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//else printf("DROPPING %s (%s)\n", buf, tp);
|
//else printf("DROPPING %s (%s)\n", buf, tp);
|
||||||
if (strcmp(tp, "[stack]\n") == 0)
|
if (strcmp(tp, "[stack]\n") == 0)
|
||||||
sp->stack += sz;
|
sp->stack += sz;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
fclose(file);
|
||||||
}
|
}
|
||||||
fclose(file);
|
|
||||||
}
|
}
|
||||||
#endif /* TOPMEM */
|
#endif /* TOPMEM */
|
||||||
#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
|
#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
|
||||||
@ -418,23 +420,34 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
|
|||||||
|
|
||||||
strcpy(filename_tail, "status");
|
strcpy(filename_tail, "status");
|
||||||
file = fopen_for_read(filename);
|
file = fopen_for_read(filename);
|
||||||
if (!file)
|
if (file) {
|
||||||
break;
|
while (fgets(buf, sizeof(buf), file)) {
|
||||||
while (fgets(buf, sizeof(buf), file)) {
|
char *tp;
|
||||||
char *tp;
|
|
||||||
#define SCAN_TWO(str, name, statement) \
|
#define SCAN_TWO(str, name, statement) \
|
||||||
if (strncmp(buf, str, sizeof(str)-1) == 0) { \
|
if (strncmp(buf, str, sizeof(str)-1) == 0) { \
|
||||||
tp = skip_whitespace(buf + sizeof(str)-1); \
|
tp = skip_whitespace(buf + sizeof(str)-1); \
|
||||||
sscanf(tp, "%u", &sp->name); \
|
sscanf(tp, "%u", &sp->name); \
|
||||||
statement; \
|
statement; \
|
||||||
}
|
}
|
||||||
SCAN_TWO("Uid:", ruid, continue);
|
SCAN_TWO("Uid:", ruid, continue);
|
||||||
SCAN_TWO("Gid:", rgid, break);
|
SCAN_TWO("Gid:", rgid, break);
|
||||||
#undef SCAN_TWO
|
#undef SCAN_TWO
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
}
|
}
|
||||||
fclose(file);
|
|
||||||
}
|
}
|
||||||
#endif /* PS_ADDITIONAL_COLUMNS */
|
#endif /* PS_ADDITIONAL_COLUMNS */
|
||||||
|
if (flags & PSSCAN_EXE) {
|
||||||
|
strcpy(filename_tail, "exe");
|
||||||
|
free(sp->exe);
|
||||||
|
sp->exe = xmalloc_readlink(filename);
|
||||||
|
}
|
||||||
|
/* Note: if /proc/PID/cmdline is empty,
|
||||||
|
* code below "breaks". Therefore it must be
|
||||||
|
* the last code to parse /proc/PID/xxx data
|
||||||
|
* (we used to have /proc/PID/exe parsing after it
|
||||||
|
* and were getting stale sp->exe).
|
||||||
|
*/
|
||||||
#if 0 /* PSSCAN_CMD is not used */
|
#if 0 /* PSSCAN_CMD is not used */
|
||||||
if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) {
|
if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) {
|
||||||
free(sp->argv0);
|
free(sp->argv0);
|
||||||
@ -477,13 +490,9 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (flags & PSSCAN_EXE) {
|
|
||||||
strcpy(filename_tail, "exe");
|
|
||||||
free(sp->exe);
|
|
||||||
sp->exe = xmalloc_readlink(filename);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
} /* for (;;) */
|
||||||
|
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user