char *str = *endptr;
unsigned long n = 0;
- while ((c = *str++) != ' ') {
+ /* Need to stop on both ' ' and '\n' */
+ while ((c = *str++) > ' ') {
c = ((c|0x20) - '0');
if (c > 9)
- // c = c + '0' - 'a' + 10:
+ /* c = c + '0' - 'a' + 10: */
c = c - ('a' - '0' - 10);
n = n*16 + c;
}
/* We cut a lot of corners here for speed */
static unsigned long fast_strtoul_10(char **endptr)
{
- char c;
+ unsigned char c;
char *str = *endptr;
unsigned long n = *str - '0';
- while ((c = *++str) != ' ')
+ /* Need to stop on both ' ' and '\n' */
+ while ((c = *++str) > ' ')
n = n*10 + (c - '0');
*endptr = str + 1; /* We skip trailing space! */
#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP
int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
- void (*cb)(struct smaprec *, void *), void *data)
+ void (*cb)(struct smaprec *, void *), void *data)
{
FILE *file;
struct smaprec currec;
memset(&currec, 0, sizeof(currec));
while (fgets(buf, PROCPS_BUFSIZE, file)) {
// Each mapping datum has this form:
- // f7d29000-f7d39000 rw-s ADR M:m OFS FILE
+ // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME
// Size: nnn kB
// Rss: nnn kB
// .....
tp = strchr(buf, '-');
if (tp) {
// We reached next mapping - the line of this form:
- // f7d29000-f7d39000 rw-s ADR M:m OFS FILE
+ // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME
if (cb) {
/* If we have a previous record, there's nothing more
strncpy(currec.smap_mode, tp, sizeof(currec.smap_mode)-1);
- // skipping "rw-s ADR M:m OFS "
+ // skipping "rw-s FILEOFS M:m INODE "
tp = skip_whitespace(skip_fields(tp, 4));
// filter out /dev/something (something != zero)
if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) {
void BUG_comm_size(void);
procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
{
- struct dirent *entry;
- char buf[PROCPS_BUFSIZE];
- char filename[sizeof("/proc//cmdline") + sizeof(int)*3];
- char *filename_tail;
- long tasknice;
- unsigned pid;
- int n;
- struct stat sb;
-
if (!sp)
sp = alloc_procps_scan();
for (;;) {
+ struct dirent *entry;
+ char buf[PROCPS_BUFSIZE];
+ long tasknice;
+ unsigned pid;
+ int n;
+ char filename[sizeof("/proc/%u/task/%u/cmdline") + sizeof(int)*3 * 2];
+ char *filename_tail;
+
#if ENABLE_FEATURE_SHOW_THREADS
- if ((flags & PSSCAN_TASKS) && sp->task_dir) {
+ if (sp->task_dir) {
entry = readdir(sp->task_dir);
if (entry)
goto got_entry;
closedir(sp->task_dir);
sp->task_dir = NULL;
- sp->main_thread_pid = 0;
}
#endif
entry = readdir(sp->dir);
/* We found another /proc/PID. Do not use it,
* there will be /proc/PID/task/PID (same PID!),
* so just go ahead and dive into /proc/PID/task. */
- char task_dir[sizeof("/proc/%u/task") + sizeof(int)*3];
- sprintf(task_dir, "/proc/%u/task", pid);
- sp->task_dir = xopendir(task_dir);
+ sprintf(filename, "/proc/%u/task", pid);
+ /* Note: if opendir fails, we just go to next /proc/XXX */
+ sp->task_dir = opendir(filename);
sp->main_thread_pid = pid;
continue;
}
}
#endif
- filename_tail = filename + sprintf(filename, "/proc/%u/", pid);
+#if ENABLE_FEATURE_SHOW_THREADS
+ if (sp->task_dir)
+ filename_tail = filename + sprintf(filename, "/proc/%u/task/%u/", sp->main_thread_pid, pid);
+ else
+#endif
+ filename_tail = filename + sprintf(filename, "/proc/%u/", pid);
if (flags & PSSCAN_UIDGID) {
+ struct stat sb;
if (stat(filename, &sb))
continue; /* process probably exited */
/* Effective UID/GID, not real */
if (n < 11)
continue; /* bogus data, get next /proc/XXX */
# if ENABLE_FEATURE_TOP_SMP_PROCESS
- if (n < 11+15)
+ if (n == 11)
sp->last_seen_on_cpu = 0;
# endif
buf[sz] = '\0';
while (--sz >= 0 && buf[sz] == '\0')
continue;
+ /* Prevent basename("process foo/bar") = "bar" */
+ strchrnul(buf, ' ')[0] = '\0';
base = bb_basename(buf); /* before we replace argv0's NUL with space */
while (sz >= 0) {
if ((unsigned char)(buf[sz]) < ' ')