aboutsummaryrefslogtreecommitdiff
path: root/procps
diff options
context:
space:
mode:
Diffstat (limited to 'procps')
-rw-r--r--procps/kill.c6
-rw-r--r--procps/pidof.c13
-rw-r--r--procps/ps.c128
-rw-r--r--procps/top.c170
4 files changed, 51 insertions, 266 deletions
diff --git a/procps/kill.c b/procps/kill.c
index 2ef87aea6..cf5c412a8 100644
--- a/procps/kill.c
+++ b/procps/kill.c
@@ -127,7 +127,7 @@ do_it_now:
127 long* pidList; 127 long* pidList;
128 128
129 pidList = find_pid_by_name(*argv); 129 pidList = find_pid_by_name(*argv);
130 if (!pidList || *pidList<=0) { 130 if (*pidList <= 0) {
131 errors++; 131 errors++;
132 if (quiet==0) 132 if (quiet==0)
133 error_msg( "%s: no process killed", *argv); 133 error_msg( "%s: no process killed", *argv);
@@ -142,9 +142,7 @@ do_it_now:
142 } 142 }
143 } 143 }
144 } 144 }
145 /* Note that we don't bother to free the memory 145 free(pidList);
146 * allocated in find_pid_by_name(). It will be freed
147 * upon exit, so we can save a byte or two */
148 argv++; 146 argv++;
149 } 147 }
150 } 148 }
diff --git a/procps/pidof.c b/procps/pidof.c
index d0d65e0db..169a92007 100644
--- a/procps/pidof.c
+++ b/procps/pidof.c
@@ -54,21 +54,16 @@ extern int pidof_main(int argc, char **argv)
54 while(optind < argc) { 54 while(optind < argc) {
55 long* pidList; 55 long* pidList;
56 56
57 pidList = find_pid_by_name( argv[optind]); 57 pidList = find_pid_by_name(argv[optind]);
58 if (!pidList || *pidList<=0) { 58 for(; *pidList > 0; pidList++) {
59 break;
60 }
61
62 for(; pidList && *pidList!=0; pidList++) {
63 printf("%s%ld", (n++ ? " " : ""), (long)*pidList); 59 printf("%s%ld", (n++ ? " " : ""), (long)*pidList);
64 fail = 0; 60 fail = 0;
65 if (single_flag) 61 if (single_flag)
66 break; 62 break;
67 } 63 }
68 /* Note that we don't bother to free the memory 64 free(pidList);
69 * allocated in find_pid_by_name(). It will be freed
70 * upon exit, so we can save a byte or two */
71 optind++; 65 optind++;
66
72 } 67 }
73 printf("\n"); 68 printf("\n");
74 69
diff --git a/procps/ps.c b/procps/ps.c
index 6036ffc1e..cf2f2b0c4 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -44,82 +44,10 @@ static const int TERMINAL_WIDTH = 79; /* not 80 in case terminal has linefo
44 44
45#if ! defined CONFIG_FEATURE_USE_DEVPS_PATCH 45#if ! defined CONFIG_FEATURE_USE_DEVPS_PATCH
46 46
47/* The following is the first ps implementation --
48 * the one using the /proc virtual filesystem.
49 */
50
51typedef struct proc_s {
52 char cmd[16]; /* basename of executable file in call to exec(2) */
53 int ruid; /* real only (sorry) */
54 int pid; /* process id */
55 int ppid; /* pid of parent process */
56 char state; /* single-char code for process state (S=sleeping) */
57 unsigned int vmsize; /* size of process as far as the vm is concerned */
58} proc_t;
59
60
61
62static int file2str(char *filename, char *ret, int cap)
63{
64 int fd, num_read;
65
66 if ((fd = open(filename, O_RDONLY, 0)) == -1)
67 return -1;
68 if ((num_read = read(fd, ret, cap - 1)) <= 0)
69 return -1;
70 ret[num_read] = 0;
71 close(fd);
72 return num_read;
73}
74
75
76static void parse_proc_status(char *S, proc_t * P)
77{
78 char *tmp;
79
80 memset(P->cmd, 0, sizeof P->cmd);
81 sscanf(S, "Name:\t%15c", P->cmd);
82 tmp = strchr(P->cmd, '\n');
83 if (tmp)
84 *tmp = '\0';
85 tmp = strstr(S, "State");
86 sscanf(tmp, "State:\t%c", &P->state);
87
88 P->pid = 0;
89 P->ppid = 0;
90 tmp = strstr(S, "Pid:");
91 if (tmp)
92 sscanf(tmp, "Pid:\t%d\n" "PPid:\t%d\n", &P->pid, &P->ppid);
93 else
94 error_msg("Internal error!");
95
96 /* For busybox, ignoring effective, saved, etc. */
97 P->ruid = 0;
98 tmp = strstr(S, "Uid:");
99 if (tmp)
100 sscanf(tmp, "Uid:\t%d", &P->ruid);
101 else
102 error_msg("Internal error!");
103
104 P->vmsize = 0;
105 tmp = strstr(S, "VmSize:");
106 if (tmp)
107 sscanf(tmp, "VmSize:\t%d", &P->vmsize);
108#if 0
109 else
110 error_msg("Internal error!");
111#endif
112}
113
114extern int ps_main(int argc, char **argv) 47extern int ps_main(int argc, char **argv)
115{ 48{
116 proc_t p; 49 procps_status_t * p;
117 DIR *dir; 50 int i, len;
118 FILE *file;
119 struct dirent *entry;
120 char path[32], sbuf[512];
121 char uidName[9];
122 int len, i, c;
123#ifdef CONFIG_FEATURE_AUTOWIDTH 51#ifdef CONFIG_FEATURE_AUTOWIDTH
124 struct winsize win = { 0, 0, 0, 0 }; 52 struct winsize win = { 0, 0, 0, 0 };
125 int terminal_width = TERMINAL_WIDTH; 53 int terminal_width = TERMINAL_WIDTH;
@@ -128,11 +56,6 @@ extern int ps_main(int argc, char **argv)
128#endif 56#endif
129 57
130 58
131
132 dir = opendir("/proc");
133 if (!dir)
134 error_msg_and_die("Can't open /proc");
135
136#ifdef CONFIG_FEATURE_AUTOWIDTH 59#ifdef CONFIG_FEATURE_AUTOWIDTH
137 ioctl(fileno(stdout), TIOCGWINSZ, &win); 60 ioctl(fileno(stdout), TIOCGWINSZ, &win);
138 if (win.ws_col > 0) 61 if (win.ws_col > 0)
@@ -140,38 +63,31 @@ extern int ps_main(int argc, char **argv)
140#endif 63#endif
141 64
142 printf(" PID Uid VmSize Stat Command\n"); 65 printf(" PID Uid VmSize Stat Command\n");
143 while ((entry = readdir(dir)) != NULL) { 66 while ((p = procps_scan(1)) != 0) {
144 if (!isdigit(*entry->d_name)) 67 char *namecmd = p->cmd;
145 continue;
146 sprintf(path, "/proc/%s/status", entry->d_name);
147 if ((file2str(path, sbuf, sizeof sbuf)) != -1) {
148 parse_proc_status(sbuf, &p);
149 }
150 68
151 /* Make some adjustments as needed */ 69 if(p->rss == 0)
152 my_getpwuid(uidName, p.ruid); 70 len = printf("%5d %-8s %s ", p->pid, p->user, p->state);
71 else
72 len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state);
73 i = terminal_width-len;
153 74
154 sprintf(path, "/proc/%s/cmdline", entry->d_name); 75 if(namecmd != 0 && namecmd[0] != 0) {
155 file = fopen(path, "r"); 76 if(i < 0)
156 if (file == NULL)
157 continue;
158 i = 0; 77 i = 0;
159 if(p.vmsize == 0) 78 if(strlen(namecmd) > i)
160 len = printf("%5d %-8s %c ", p.pid, uidName, p.state); 79 namecmd[i] = 0;
161 else 80 printf("%s\n", namecmd);
162 len = printf("%5d %-8s %6d %c ", p.pid, uidName, p.vmsize, p.state); 81 } else {
163 while (((c = getc(file)) != EOF) && (i < (terminal_width-len))) { 82 namecmd = p->short_cmd;
164 i++; 83 if(i < 2)
165 if (c == '\0') 84 i = 2;
166 c = ' '; 85 if(strlen(namecmd) > (i-2))
167 putc(c, stdout); 86 namecmd[i-2] = 0;
87 printf("[%s]\n", namecmd);
168 } 88 }
169 fclose(file); 89 free(p->cmd);
170 if (i == 0)
171 printf("[%s]", p.cmd);
172 putchar('\n');
173 } 90 }
174 closedir(dir);
175 return EXIT_SUCCESS; 91 return EXIT_SUCCESS;
176} 92}
177 93
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) {