aboutsummaryrefslogtreecommitdiff
path: root/procps/top.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-10-22 12:21:15 +0000
committerEric Andersen <andersen@codepoet.org>2002-10-22 12:21:15 +0000
commit44608e9693b03661fbab5e27650bb040c6871d11 (patch)
tree4555230653cdb82d998f076b29130d8fe18a6f7a /procps/top.c
parent1887b0478f2743ce7808e8b37462e18d584611e1 (diff)
downloadbusybox-w32-44608e9693b03661fbab5e27650bb040c6871d11.tar.gz
busybox-w32-44608e9693b03661fbab5e27650bb040c6871d11.tar.bz2
busybox-w32-44608e9693b03661fbab5e27650bb040c6871d11.zip
Patch last_pach62 from vodz. This patch moves all the /proc parsing
code into libbb so it can be shared by ps, top, etc, saving over 1.5k.
Diffstat (limited to 'procps/top.c')
-rw-r--r--procps/top.c170
1 files changed, 23 insertions, 147 deletions
diff --git a/procps/top.c b/procps/top.c
index 06ae77119..4204deaf2 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -31,10 +31,8 @@
31#include <stdio.h> 31#include <stdio.h>
32#include <stdlib.h> 32#include <stdlib.h>
33#include <unistd.h> 33#include <unistd.h>
34#include <dirent.h>
35#include <string.h> 34#include <string.h>
36#include <sys/ioctl.h> 35#include <sys/ioctl.h>
37#include <sys/stat.h>
38/* get page info */ 36/* get page info */
39#include <asm/page.h> 37#include <asm/page.h>
40#include "busybox.h" 38#include "busybox.h"
@@ -49,30 +47,13 @@
49#endif 47#endif
50 48
51 49
52typedef struct { 50typedef int (*cmp_t)(procps_status_t *P, procps_status_t *Q);
53 int pid;
54 char user[9];
55 char state[4];
56 unsigned long rss;
57 int ppid;
58#ifdef FEATURE_CPU_USAGE_PERCENTAGE
59 unsigned pcpu;
60 unsigned long stime, utime;
61#endif
62 char *cmd;
63
64 /* basename of executable file in call to exec(2),
65 size from kernel headers */
66 char short_cmd[16];
67} status_t;
68
69typedef int (*cmp_t)(status_t *P, status_t *Q);
70 51
71static status_t *top; /* Hehe */ 52static procps_status_t *top; /* Hehe */
72static int ntop; 53static int ntop;
73 54
74 55
75static int pid_sort (status_t *P, status_t *Q) 56static int pid_sort (procps_status_t *P, procps_status_t *Q)
76{ 57{
77 int p = P->pid; 58 int p = P->pid;
78 int q = Q->pid; 59 int q = Q->pid;
@@ -82,7 +63,7 @@ static int pid_sort (status_t *P, status_t *Q)
82 return 0; 63 return 0;
83} 64}
84 65
85static int mem_sort (status_t *P, status_t *Q) 66static int mem_sort (procps_status_t *P, procps_status_t *Q)
86{ 67{
87 long p = P->rss; 68 long p = P->rss;
88 long q = Q->rss; 69 long q = Q->rss;
@@ -97,7 +78,7 @@ static int mem_sort (status_t *P, status_t *Q)
97#define sort_depth 3 78#define sort_depth 3
98static cmp_t sort_function[sort_depth]; 79static cmp_t sort_function[sort_depth];
99 80
100static int pcpu_sort (status_t *P, status_t *Q) 81static int pcpu_sort (procps_status_t *P, procps_status_t *Q)
101{ 82{
102 int p = P->pcpu; 83 int p = P->pcpu;
103 int q = Q->pcpu; 84 int q = Q->pcpu;
@@ -107,7 +88,7 @@ static int pcpu_sort (status_t *P, status_t *Q)
107 return 0; 88 return 0;
108} 89}
109 90
110static int time_sort (status_t *P, status_t *Q) 91static int time_sort (procps_status_t *P, procps_status_t *Q)
111{ 92{
112 long p = P->stime; 93 long p = P->stime;
113 long q = Q->stime; 94 long q = Q->stime;
@@ -253,7 +234,7 @@ static void do_stats(void)
253 struct timezone timez; 234 struct timezone timez;
254 float elapsed_time; 235 float elapsed_time;
255 236
256 status_t *cur; 237 procps_status_t *cur;
257 int total_time, i, n; 238 int total_time, i, n;
258 static int prev_count; 239 static int prev_count;
259 int systime, usrtime, pid; 240 int systime, usrtime, pid;
@@ -317,7 +298,7 @@ static void do_stats(void)
317 save_history = memcpy(xmalloc(sizeof(struct save_hist)*n), New_save_hist, 298 save_history = memcpy(xmalloc(sizeof(struct save_hist)*n), New_save_hist,
318 sizeof(struct save_hist)*n); 299 sizeof(struct save_hist)*n);
319 prev_count = n; 300 prev_count = n;
320 qsort(top, n, sizeof(status_t), (void*)mult_lvl_cmp); 301 qsort(top, n, sizeof(procps_status_t), (void*)mult_lvl_cmp);
321} 302}
322#else 303#else
323static cmp_t sort_function; 304static cmp_t sort_function;
@@ -370,7 +351,7 @@ static unsigned long display_generic(void)
370/* display process statuses */ 351/* display process statuses */
371static void display_status(int count, int col) 352static void display_status(int count, int col)
372{ 353{
373 status_t *s = top; 354 procps_status_t *s = top;
374 char rss_str_buf[8]; 355 char rss_str_buf[8];
375 unsigned long total_memory = display_generic(); 356 unsigned long total_memory = display_generic();
376 357
@@ -382,7 +363,7 @@ static void display_status(int count, int col)
382#endif 363#endif
383 364
384 while (count--) { 365 while (count--) {
385 char *namecmd = s->cmd; 366 char *namecmd = s->short_cmd;
386 int pmem; 367 int pmem;
387 368
388 pmem = 1000.0 * s->rss / total_memory; 369 pmem = 1000.0 * s->rss / total_memory;
@@ -402,130 +383,17 @@ static void display_status(int count, int col)
402 s->pcpu/10, s->pcpu%10, 383 s->pcpu/10, s->pcpu%10,
403#endif 384#endif
404 pmem/10, pmem%10); 385 pmem/10, pmem%10);
405 if(namecmd != 0 && namecmd[0] != 0) {
406 if(strlen(namecmd) > col) 386 if(strlen(namecmd) > col)
407 namecmd[col] = 0; 387 namecmd[col] = 0;
408 printf("%s\n", namecmd); 388 printf("%s\n", namecmd);
409 } else {
410 namecmd = s->short_cmd;
411 if(strlen(namecmd) > (col-2))
412 namecmd[col-2] = 0;
413 printf("[%s]\n", namecmd);
414 }
415 s++; 389 s++;
416 } 390 }
417} 391}
418 392
419/* returns true for file names which are PID dirs 393static void clearmems(void)
420 * (i.e. start with number)
421 */
422static int filter_pids(const struct dirent *dir)
423{ 394{
424 char *name = dir->d_name;
425 int n;
426 char status[20];
427 char buf[1024];
428 FILE *fp;
429 status_t curstatus;
430 int pid;
431 long tasknice;
432 struct stat sb;
433
434 if (!(*name >= '0' && *name <= '9'))
435 return 0;
436 if(stat(name, &sb))
437 return 0;
438
439 memset(&curstatus, 0, sizeof(status_t));
440 pid = atoi(name);
441 curstatus.pid = pid;
442
443 my_getpwuid(curstatus.user, sb.st_uid);
444
445 sprintf(status, "%d/stat", pid);
446 if((fp = fopen(status, "r")) == NULL)
447 return 0;
448 name = fgets(buf, sizeof(buf), fp);
449 fclose(fp);
450 if(name == NULL)
451 return 0;
452 name = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
453 if(name == 0 || name[1] != ' ')
454 return 0;
455 *name = 0;
456 sscanf(buf, "%*s (%15c", curstatus.short_cmd);
457 n = sscanf(name+2,
458 "%c %d "
459 "%*s %*s %*s %*s " /* pgrp, session, tty, tpgid */
460 "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
461#ifdef FEATURE_CPU_USAGE_PERCENTAGE
462 "%lu %lu "
463#else
464 "%*s %*s "
465#endif
466 "%*s %*s %*s " /* cutime, cstime, priority */
467 "%ld "
468 "%*s %*s %*s " /* timeout, it_real_value, start_time */
469 "%*s " /* vsize */
470 "%ld",
471 curstatus.state, &curstatus.ppid,
472#ifdef FEATURE_CPU_USAGE_PERCENTAGE
473 &curstatus.utime, &curstatus.stime,
474#endif
475 &tasknice,
476 &curstatus.rss);
477#ifdef FEATURE_CPU_USAGE_PERCENTAGE
478 if(n != 6)
479#else
480 if(n != 4)
481#endif
482 return 0;
483
484 if (curstatus.rss == 0 && curstatus.state[0] != 'Z')
485 curstatus.state[1] = 'W';
486 else
487 curstatus.state[1] = ' ';
488 if (tasknice < 0)
489 curstatus.state[2] = '<';
490 else if (tasknice > 0)
491 curstatus.state[2] = 'N';
492 else
493 curstatus.state[2] = ' ';
494
495 curstatus.rss <<= (PAGE_SHIFT - 10); /* 2**10 = 1kb */
496
497 sprintf(status, "%d/cmdline", pid);
498 if((fp = fopen(status, "r")) == NULL)
499 return 0;
500 if(fgets(buf, sizeof(buf), fp) != NULL) {
501 name = strchr(buf, '\n');
502 if(name != NULL)
503 *name = 0;
504 if(buf[0])
505 curstatus.cmd = strdup(buf); /* if NULL it work true also */
506 }
507 fclose(fp);
508
509 n = ntop;
510 top = xrealloc(top, (++ntop)*sizeof(status_t));
511 memcpy(top + n, &curstatus, sizeof(status_t));
512 return 1;
513}
514
515
516static struct dirent **namelist;
517
518static void clearmems(void) {
519 int i;
520
521 for(i = 0; i < ntop; i++) {
522 free(top[i].cmd);
523 free(namelist[i]);
524 }
525 free(top); 395 free(top);
526 free(namelist);
527 top = 0; 396 top = 0;
528 namelist = 0;
529 ntop = 0; 397 ntop = 0;
530} 398}
531 399
@@ -591,7 +459,7 @@ int top_main(int argc, char **argv)
591#else 459#else
592 col = 35; 460 col = 35;
593#endif 461#endif
594 /* change to proc */ 462 /* change to /proc */
595 if (chdir("/proc") < 0) { 463 if (chdir("/proc") < 0) {
596 perror_msg_and_die("chdir('/proc')"); 464 perror_msg_and_die("chdir('/proc')");
597 } 465 }
@@ -631,7 +499,15 @@ int top_main(int argc, char **argv)
631#endif 499#endif
632 while (1) { 500 while (1) {
633 /* read process IDs & status for all the processes */ 501 /* read process IDs & status for all the processes */
634 if (scandir(".", &namelist, filter_pids, 0) < 0) { 502 procps_status_t * p;
503
504 while ((p = procps_scan(0)) != 0) {
505 int n = ntop;
506
507 top = xrealloc(top, (++ntop)*sizeof(procps_status_t));
508 memcpy(top + n, p, sizeof(procps_status_t));
509 }
510 if (ntop == 0) {
635 perror_msg_and_die("scandir('/proc')"); 511 perror_msg_and_die("scandir('/proc')");
636 } 512 }
637#ifdef FEATURE_CPU_USAGE_PERCENTAGE 513#ifdef FEATURE_CPU_USAGE_PERCENTAGE
@@ -644,7 +520,7 @@ int top_main(int argc, char **argv)
644 } 520 }
645 do_stats(); 521 do_stats();
646#else 522#else
647 qsort(top, ntop, sizeof(status_t), (void*)sort_function); 523 qsort(top, ntop, sizeof(procps_status_t), (void*)sort_function);
648#endif 524#endif
649 opt = lines; 525 opt = lines;
650 if (opt > ntop) { 526 if (opt > ntop) {