aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-08-28 11:57:36 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-08-28 11:57:36 +0200
commit2390109dcbc7769c8cc373db32805206522ca9a6 (patch)
tree1e0ae86d789f5c5c625a7a49453fc70fb700c9ab
parentabc33ac8b24d2d733aba63ae19e2df6e7da16ec8 (diff)
downloadbusybox-2390109dcbc7769c8cc373db32805206522ca9a6.tar.gz
top: fix CPU% for thread display. Closes 4081
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--libbb/procps.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/libbb/procps.c b/libbb/procps.c
index 1dea61518..e15ddd1e5 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -284,27 +284,25 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
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);
@@ -321,9 +319,9 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
/* 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;
}
@@ -347,9 +345,15 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
}
#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 */