Deleted Added
full compact
machine.c (131310) machine.c (131402)
1/*
2 * top - a top users display for Unix
3 *
4 * SYNOPSIS: For FreeBSD-2.x and later
5 *
6 * DESCRIPTION:
7 * Originally written for BSD4.4 system by Christos Zoulas.
8 * Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider

--- 6 unchanged lines hidden (view full) ---

15 *
16 * LIBS: -lkvm
17 *
18 * AUTHOR: Christos Zoulas <christos@ee.cornell.edu>
19 * Steven Wallace <swallace@freebsd.org>
20 * Wolfram Schneider <wosch@FreeBSD.org>
21 * Thomas Moestl <tmoestl@gmx.net>
22 *
1/*
2 * top - a top users display for Unix
3 *
4 * SYNOPSIS: For FreeBSD-2.x and later
5 *
6 * DESCRIPTION:
7 * Originally written for BSD4.4 system by Christos Zoulas.
8 * Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider

--- 6 unchanged lines hidden (view full) ---

15 *
16 * LIBS: -lkvm
17 *
18 * AUTHOR: Christos Zoulas <christos@ee.cornell.edu>
19 * Steven Wallace <swallace@freebsd.org>
20 * Wolfram Schneider <wosch@FreeBSD.org>
21 * Thomas Moestl <tmoestl@gmx.net>
22 *
23 * $FreeBSD: head/usr.bin/top/machine.c 131310 2004-06-30 04:19:23Z alfred $
23 * $FreeBSD: head/usr.bin/top/machine.c 131402 2004-07-01 09:12:38Z alfred $
24 */
25
26
27#include <sys/time.h>
28#include <sys/types.h>
29#include <sys/signal.h>
30#include <sys/param.h>
31

--- 26 unchanged lines hidden (view full) ---

58
59static void getsysctl(char *, void *, size_t);
60
61#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
62
63extern char* printable(char *);
64int swapmode(int *retavail, int *retfree);
65static int smpmode;
24 */
25
26
27#include <sys/time.h>
28#include <sys/types.h>
29#include <sys/signal.h>
30#include <sys/param.h>
31

--- 26 unchanged lines hidden (view full) ---

58
59static void getsysctl(char *, void *, size_t);
60
61#define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var))
62
63extern char* printable(char *);
64int swapmode(int *retavail, int *retfree);
65static int smpmode;
66enum displaymodes displaymode;
66static int namelength;
67static int cmdlengthdelta;
68
69/* Prototypes for top internals */
70void quit(int);
67static int namelength;
68static int cmdlengthdelta;
69
70/* Prototypes for top internals */
71void quit(int);
72int compare_pid(const void *a, const void *b);
71
72/* get_process_info passes back a handle. This is what it looks like: */
73
74struct handle
75{
76 struct kinfo_proc **next_proc; /* points to next valid proc pointer */
77 int remaining; /* number of pointers remaining */
78};
79
80/* declarations for load_avg */
81#include "loadavg.h"
82
83/* define what weighted cpu is. */
84#define weighted_cpu(pct, pp) ((pp)->ki_swtime == 0 ? 0.0 : \
85 ((pct) / (1.0 - exp((pp)->ki_swtime * logcpu))))
86
87/* what we consider to be process size: */
88#define PROCSIZE(pp) ((pp)->ki_size / 1024)
89
73
74/* get_process_info passes back a handle. This is what it looks like: */
75
76struct handle
77{
78 struct kinfo_proc **next_proc; /* points to next valid proc pointer */
79 int remaining; /* number of pointers remaining */
80};
81
82/* declarations for load_avg */
83#include "loadavg.h"
84
85/* define what weighted cpu is. */
86#define weighted_cpu(pct, pp) ((pp)->ki_swtime == 0 ? 0.0 : \
87 ((pct) / (1.0 - exp((pp)->ki_swtime * logcpu))))
88
89/* what we consider to be process size: */
90#define PROCSIZE(pp) ((pp)->ki_size / 1024)
91
92#define RU(pp) (&(pp)->ki_rusage)
93#define RUTOT(pp) \
94 (RU(pp)->ru_inblock + RU(pp)->ru_oublock + RU(pp)->ru_majflt)
95
96
90/* definitions for indices in the nlist array */
91
92/*
93 * These definitions control the format of the per-process area
94 */
95
97/* definitions for indices in the nlist array */
98
99/*
100 * These definitions control the format of the per-process area
101 */
102
103static char io_header[] =
104 " PID %-*.*s READ WRITE FAULT TOTAL COMMAND";
105
106#define io_Proc_format \
107 "%5d %-*.*s %6d %6d %6d %6d %.*s"
108
96static char smp_header[] =
97 " PID %-*.*s PRI NICE SIZE RES STATE C TIME WCPU CPU COMMAND";
98
99#define smp_Proc_format \
100 "%5d %-*.*s %3d %4d%7s %6s %-6.6s %1x%7s %5.2f%% %5.2f%% %.*s"
101
102static char up_header[] =
103 " PID %-*.*s PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND";

--- 67 unchanged lines hidden (view full) ---

171
172/* these are for keeping track of the proc array */
173
174static int nproc;
175static int onproc = -1;
176static int pref_len;
177static struct kinfo_proc *pbase;
178static struct kinfo_proc **pref;
109static char smp_header[] =
110 " PID %-*.*s PRI NICE SIZE RES STATE C TIME WCPU CPU COMMAND";
111
112#define smp_Proc_format \
113 "%5d %-*.*s %3d %4d%7s %6s %-6.6s %1x%7s %5.2f%% %5.2f%% %.*s"
114
115static char up_header[] =
116 " PID %-*.*s PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND";

--- 67 unchanged lines hidden (view full) ---

184
185/* these are for keeping track of the proc array */
186
187static int nproc;
188static int onproc = -1;
189static int pref_len;
190static struct kinfo_proc *pbase;
191static struct kinfo_proc **pref;
192static struct kinfo_proc *previous_procs;
193static struct kinfo_proc **previous_pref;
194static int previous_proc_count = 0;
195static int previous_proc_count_max = 0;
179
180/* these are for getting the memory statistics */
181
182static int pageshift; /* log base 2 of the pagesize */
183
184/* define pagetok in terms of pageshift */
185
186#define pagetok(size) ((size) << pageshift)

--- 71 unchanged lines hidden (view full) ---

258}
259
260char *
261format_header(uname_field)
262 char *uname_field;
263
264{
265 static char Header[128];
196
197/* these are for getting the memory statistics */
198
199static int pageshift; /* log base 2 of the pagesize */
200
201/* define pagetok in terms of pageshift */
202
203#define pagetok(size) ((size) << pageshift)

--- 71 unchanged lines hidden (view full) ---

275}
276
277char *
278format_header(uname_field)
279 char *uname_field;
280
281{
282 static char Header[128];
283 const char *prehead;
266
284
267 snprintf(Header, sizeof(Header), smpmode ? smp_header : up_header,
285 switch (displaymode) {
286 case DISP_CPU:
287 prehead = smpmode ? smp_header : up_header;
288 break;
289 case DISP_IO:
290 prehead = io_header;
291 break;
292 }
293
294 snprintf(Header, sizeof(Header), prehead,
268 namelength, namelength, uname_field);
269
270 cmdlengthdelta = strlen(Header) - 7;
271
272 return Header;
273}
274
275static int swappgsin = -1;

--- 106 unchanged lines hidden (view full) ---

382 if (sysctl(mib, 2, &boottime, &bt_size, NULL, 0) != -1 &&
383 boottime.tv_sec != 0) {
384 si->boottime = boottime;
385 } else {
386 si->boottime.tv_sec = -1;
387 }
388}
389
295 namelength, namelength, uname_field);
296
297 cmdlengthdelta = strlen(Header) - 7;
298
299 return Header;
300}
301
302static int swappgsin = -1;

--- 106 unchanged lines hidden (view full) ---

409 if (sysctl(mib, 2, &boottime, &bt_size, NULL, 0) != -1 &&
410 boottime.tv_sec != 0) {
411 si->boottime = boottime;
412 } else {
413 si->boottime.tv_sec = -1;
414 }
415}
416
417const struct kinfo_proc *
418get_old_proc(struct kinfo_proc *pp)
419{
420 struct kinfo_proc **oldpp, *oldp;
421
422 if (previous_proc_count == 0)
423 return (NULL);
424 oldpp = bsearch(&pp, previous_pref, previous_proc_count,
425 sizeof(struct kinfo_proc *), compare_pid);
426 if (oldpp == NULL)
427 return (NULL);
428 oldp = *oldpp;
429 if (bcmp(&oldp->ki_start, &pp->ki_start, sizeof(pp->ki_start)) != 0)
430 return (NULL);
431 return (oldp);
432}
433
434long
435get_io_total(struct kinfo_proc *pp)
436{
437 const struct kinfo_proc *oldp;
438 static struct kinfo_proc dummy;
439 long ret;
440
441 oldp = get_old_proc(pp);
442 if (oldp == NULL) {
443 bzero(&dummy, sizeof(dummy));
444 oldp = &dummy;
445 }
446
447 ret =
448 (RU(pp)->ru_inblock - RU(oldp)->ru_inblock) +
449 (RU(pp)->ru_oublock - RU(oldp)->ru_oublock) +
450 (RU(pp)->ru_majflt - RU(oldp)->ru_majflt);
451 return (ret);
452}
453
390static struct handle handle;
391
392caddr_t
393get_process_info(si, sel, compare)
394 struct system_info *si;
395 struct process_select *sel;
396 int (*compare)();
397{

--- 6 unchanged lines hidden (view full) ---

404
405 /* these are copied out of sel for speed */
406 int show_idle;
407 int show_self;
408 int show_system;
409 int show_uid;
410 int show_command;
411
454static struct handle handle;
455
456caddr_t
457get_process_info(si, sel, compare)
458 struct system_info *si;
459 struct process_select *sel;
460 int (*compare)();
461{

--- 6 unchanged lines hidden (view full) ---

468
469 /* these are copied out of sel for speed */
470 int show_idle;
471 int show_self;
472 int show_system;
473 int show_uid;
474 int show_command;
475
476 /*
477 * Save the previous process info.
478 */
479 if (previous_proc_count_max < nproc) {
480 free(previous_procs);
481 previous_procs = malloc(nproc * sizeof(struct kinfo_proc));
482 free(previous_pref);
483 previous_pref = malloc(nproc * sizeof(struct kinfo_proc *));
484 if (previous_procs == NULL || previous_pref == NULL) {
485 (void) fprintf(stderr, "top: Out of memory.\n");
486 quit(23);
487 }
488 previous_proc_count_max = nproc;
489 }
490 if (nproc) {
491 for (i = 0; i < nproc; i++)
492 previous_pref[i] = &previous_procs[i];
493 bcopy(pbase, previous_procs, nproc * sizeof(struct kinfo_proc));
494 qsort(previous_pref, nproc,
495 sizeof(struct kinfo_proc *), compare_pid);
496 }
497 previous_proc_count = nproc;
498
412 pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc);
413 if (nproc > onproc)
414 pref = (struct kinfo_proc **) realloc(pref, sizeof(struct kinfo_proc *)
415 * (onproc = nproc));
416 if (pref == NULL || pbase == NULL) {
417 (void) fprintf(stderr, "top: Out of memory.\n");
418 quit(23);
419 }

--- 22 unchanged lines hidden (view full) ---

442 */
443 if (pp->ki_stat != 0 &&
444 (show_self != pp->ki_pid) &&
445 (show_system || ((pp->ki_flag & P_SYSTEM) == 0)))
446 {
447 total_procs++;
448 process_states[(unsigned char) pp->ki_stat]++;
449 if ((pp->ki_stat != SZOMB) &&
499 pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc);
500 if (nproc > onproc)
501 pref = (struct kinfo_proc **) realloc(pref, sizeof(struct kinfo_proc *)
502 * (onproc = nproc));
503 if (pref == NULL || pbase == NULL) {
504 (void) fprintf(stderr, "top: Out of memory.\n");
505 quit(23);
506 }

--- 22 unchanged lines hidden (view full) ---

529 */
530 if (pp->ki_stat != 0 &&
531 (show_self != pp->ki_pid) &&
532 (show_system || ((pp->ki_flag & P_SYSTEM) == 0)))
533 {
534 total_procs++;
535 process_states[(unsigned char) pp->ki_stat]++;
536 if ((pp->ki_stat != SZOMB) &&
450 (show_idle || (pp->ki_pctcpu != 0) ||
451 (pp->ki_stat == SRUN)) &&
537 (displaymode == DISP_CPU &&
538 (show_idle || (pp->ki_pctcpu != 0) || pp->ki_stat == SRUN)) ||
539 (show_idle || (displaymode == DISP_IO && get_io_total(pp))) &&
452 (!show_uid || pp->ki_ruid == (uid_t)sel->uid))
453 {
454 /*
455 * When not showing threads, take the first thread
456 * for output and add the fields that we can from
457 * the rest of the process's threads rather than
458 * using the system's mostly-broken KERN_PROC_PROC.
459 */

--- 29 unchanged lines hidden (view full) ---

489char fmt[128]; /* static area where result is built */
490
491char *
492format_next_process(handle, get_userid)
493 caddr_t handle;
494 char *(*get_userid)();
495{
496 struct kinfo_proc *pp;
540 (!show_uid || pp->ki_ruid == (uid_t)sel->uid))
541 {
542 /*
543 * When not showing threads, take the first thread
544 * for output and add the fields that we can from
545 * the rest of the process's threads rather than
546 * using the system's mostly-broken KERN_PROC_PROC.
547 */

--- 29 unchanged lines hidden (view full) ---

577char fmt[128]; /* static area where result is built */
578
579char *
580format_next_process(handle, get_userid)
581 caddr_t handle;
582 char *(*get_userid)();
583{
584 struct kinfo_proc *pp;
585 const struct kinfo_proc *oldp;
497 long cputime;
498 double pct;
499 struct handle *hp;
500 char status[16];
501 int state;
586 long cputime;
587 double pct;
588 struct handle *hp;
589 char status[16];
590 int state;
591 struct rusage ru, *rup;
502
503 /* find and remember the next proc structure */
504 hp = (struct handle *)handle;
505 pp = *(hp->next_proc++);
506 hp->remaining--;
507
508 /* get the process's command name */
509 if ((pp->ki_sflag & PS_INMEM) == 0) {

--- 46 unchanged lines hidden (view full) ---

556 if (state >= 0 &&
557 state < sizeof(state_abbrev) / sizeof(*state_abbrev))
558 sprintf(status, "%.6s", state_abbrev[(unsigned char) state]);
559 else
560 sprintf(status, "?%5d", state);
561 break;
562 }
563
592
593 /* find and remember the next proc structure */
594 hp = (struct handle *)handle;
595 pp = *(hp->next_proc++);
596 hp->remaining--;
597
598 /* get the process's command name */
599 if ((pp->ki_sflag & PS_INMEM) == 0) {

--- 46 unchanged lines hidden (view full) ---

646 if (state >= 0 &&
647 state < sizeof(state_abbrev) / sizeof(*state_abbrev))
648 sprintf(status, "%.6s", state_abbrev[(unsigned char) state]);
649 else
650 sprintf(status, "?%5d", state);
651 break;
652 }
653
654 if (displaymode == DISP_IO) {
655 oldp = get_old_proc(pp);
656 if (oldp != NULL) {
657 ru.ru_inblock = RU(pp)->ru_inblock - RU(oldp)->ru_inblock;
658 ru.ru_oublock = RU(pp)->ru_oublock - RU(oldp)->ru_oublock;
659 ru.ru_majflt = RU(pp)->ru_majflt - RU(oldp)->ru_majflt;
660 rup = &ru;
661 } else {
662 rup = RU(pp);
663 }
664
665 sprintf(fmt, io_Proc_format,
666 pp->ki_pid,
667 namelength, namelength,
668 (*get_userid)(pp->ki_ruid),
669 (int)rup->ru_inblock,
670 (int)rup->ru_oublock,
671 (int)rup->ru_majflt,
672 (int)(rup->ru_inblock + rup->ru_oublock + rup->ru_majflt),
673 screen_width > cmdlengthdelta ?
674 screen_width - cmdlengthdelta : 0,
675 printable(pp->ki_comm));
676 return (fmt);
677 }
564 /* format this entry */
565 sprintf(fmt,
566 smpmode ? smp_Proc_format : up_Proc_format,
567 pp->ki_pid,
568 namelength, namelength,
569 (*get_userid)(pp->ki_ruid),
570 pp->ki_pri.pri_level - PZERO,
571

--- 40 unchanged lines hidden (view full) ---

612 fprintf(stderr, "top: sysctl(%s...) expected %lu, got %lu\n", name,
613 (unsigned long)len, (unsigned long)nlen);
614 quit(23);
615 }
616}
617
618/* comparison routines for qsort */
619
678 /* format this entry */
679 sprintf(fmt,
680 smpmode ? smp_Proc_format : up_Proc_format,
681 pp->ki_pid,
682 namelength, namelength,
683 (*get_userid)(pp->ki_ruid),
684 pp->ki_pri.pri_level - PZERO,
685

--- 40 unchanged lines hidden (view full) ---

726 fprintf(stderr, "top: sysctl(%s...) expected %lu, got %lu\n", name,
727 (unsigned long)len, (unsigned long)nlen);
728 quit(23);
729 }
730}
731
732/* comparison routines for qsort */
733
734int
735compare_pid(p1, p2)
736 const void *p1, *p2;
737{
738 const struct kinfo_proc * const *pp1 = p1;
739 const struct kinfo_proc * const *pp2 = p2;
740
741 if ((*pp2)->ki_pid < 0 || (*pp1)->ki_pid < 0)
742 abort();
743
744 return ((*pp1)->ki_pid - (*pp2)->ki_pid);
745}
746
620/*
621 * proc_compare - comparison function for "qsort"
622 * Compares the resource consumption of two processes using five
623 * distinct keys. The keys (in descending order of importance) are:
624 * percent cpu, cpu ticks, state, resident set size, total virtual
625 * memory usage. The process states are ordered as follows (from least
626 * to most important): WAIT, zombie, sleep, stop, start, run. The
627 * array declaration below maps a process state index into a number

--- 181 unchanged lines hidden (view full) ---

809 ORDERKEY_RSSIZE
810 ORDERKEY_MEM
811 ;
812
813 return(result);
814}
815#endif
816
747/*
748 * proc_compare - comparison function for "qsort"
749 * Compares the resource consumption of two processes using five
750 * distinct keys. The keys (in descending order of importance) are:
751 * percent cpu, cpu ticks, state, resident set size, total virtual
752 * memory usage. The process states are ordered as follows (from least
753 * to most important): WAIT, zombie, sleep, stop, start, run. The
754 * array declaration below maps a process state index into a number

--- 181 unchanged lines hidden (view full) ---

936 ORDERKEY_RSSIZE
937 ORDERKEY_MEM
938 ;
939
940 return(result);
941}
942#endif
943
944int
945io_compare(pp1, pp2)
946 struct kinfo_proc **pp1, **pp2;
947{
948 long t1, t2;
949
950 t1 = get_io_total(*pp1);
951 t2 = get_io_total(*pp2);
952 return (t2 - t1);
953}
817/*
818 * proc_owner(pid) - returns the uid that owns process "pid", or -1 if
819 * the process does not exist.
820 * It is EXTREMLY IMPORTANT that this function work correctly.
821 * If top runs setuid root (as in SVR4), then this function
822 * is the only thing that stands in the way of a serious
823 * security problem. It validates requests for the "kill"
824 * and "renice" commands.

--- 49 unchanged lines hidden ---
954/*
955 * proc_owner(pid) - returns the uid that owns process "pid", or -1 if
956 * the process does not exist.
957 * It is EXTREMLY IMPORTANT that this function work correctly.
958 * If top runs setuid root (as in SVR4), then this function
959 * is the only thing that stands in the way of a serious
960 * security problem. It validates requests for the "kill"
961 * and "renice" commands.

--- 49 unchanged lines hidden ---