diff options
Diffstat (limited to 'sysutils/top')
-rw-r--r-- | sysutils/top/patches/patch-aa | 3333 |
1 files changed, 1462 insertions, 1871 deletions
diff --git a/sysutils/top/patches/patch-aa b/sysutils/top/patches/patch-aa index 9b903b87c40..d82395dc6f9 100644 --- a/sysutils/top/patches/patch-aa +++ b/sysutils/top/patches/patch-aa @@ -1,1876 +1,1467 @@ -Return-Path: <current-users-owner-agc=amdahl.com@NetBSD.ORG> -Received: by juno.ccc.amdahl.com (/\==/\ Smail #25.1) - id <m0we38A-0000SaC@juno.ccc.amdahl.com>; Tue, 17 Jun 97 11:37 PDT -Received: from vega.oes.amdahl.com by orpheus.amdahl.com with smtp - (Smail3.1.29.1 #3) id m0we38J-0004u0C; Tue, 17 Jun 97 11:37 PDT -Received: from minerva.amdahl.com by vega.oes.amdahl.com with SMTP - (OES Smail-3.1.29.1) id m0we38I-000B1FC; Tue, 17 Jun 97 11:37 PDT -Received: from orpheus.amdahl.com by minerva.amdahl.com with smtp - (Smail3.1.29.1 #5) id m0we38H-0002AQC; Tue, 17 Jun 97 11:37 PDT -Received: from mail.NetBSD.ORG by orpheus.amdahl.com with smtp - (Smail3.1.29.1 #3) id m0we38F-0004tyC; Tue, 17 Jun 97 11:37 PDT -Received: (qmail 27809 invoked by uid 605); 17 Jun 1997 18:25:18 -0000 -Received: (qmail 27786 invoked by uid 1032); 17 Jun 1997 18:25:13 -0000 -Received: (qmail 28031 invoked from network); 17 Jun 1997 07:53:22 -0000 -Received: from shara.off.connect.com.au (192.94.41.9) - by homeworld.cygnus.com with SMTP; 17 Jun 1997 07:53:22 -0000 -Received: from connect.com.au (lukem@localhost) by shara.off.connect.com.au with ESMTP id RAA00046 - (8.8.5/IDA-1.6 for <current-users@netbsd.org>); Tue, 17 Jun 1997 17:51:49 +1000 (EST) -Message-ID: <199706170751.RAA00046@shara.off.connect.com.au> -From: Luke Mewburn <lukem@connect.com.au> -Reply-to: lukem@connect.com.au -To: current-users@netbsd.org -Subject: top 3.5b5 patches for -current and not so -current -Date: Tue, 17 Jun 1997 17:51:49 +1000 -Sender: current-users-owner@NetBSD.ORG -Precedence: list -Delivered-To: current-users@NetBSD.ORG +--- Configure Fri Dec 20 16:52:30 1996 ++++ Configure Sat Oct 4 03:25:02 1997 +@@ -348,3 +348,2 @@ + set t_mode = 4711 +- set mode = 4711 + else if (-e /dev/kmem) then +diff -1 -uBbNr commands.c commands.c +--- commands.c Tue Aug 27 16:13:57 1996 ++++ commands.c Sat Oct 4 03:25:02 1997 +@@ -25,4 +25,7 @@ ++#include "top.h" ++#include "top.local.h" + #include "sigdesc.h" /* generated automatically */ + #include "boolean.h" ++#include "machine.h" + #include "utils.h" +@@ -44,4 +47,4 @@ -Here's a patch to top3.5-beta5 that does the following: - * fixes up a minor bug in the configure script. - * adds process ordering (sorting on cpu, pri, res, size, - state, or time) - * removes attempted support for LASTPID - it didn't work, - and in any case, it's a security issue. - * adds a new module for netbsd 1.3 (and netbsd1.2G) - - m_netbsd13.c, which supports the new swap code. +-show_help() +- ++show_help(statics) ++ struct statics *statics; + { +@@ -74,4 +77,11 @@ + #ifdef ORDER ++ { ++ int i; ++ + fputs("\ +-o - specify sort order (size, res, cpu, time)\n", stdout); ++o - specify sort order (", stdout); ++ for (i = 0; statics->order_names[i] != NULL; i++) ++ printf("%s%s", i == 0 ? "" : ", ", statics->order_names[i]); ++ puts(")"); ++ } + #endif +diff -1 -uBbNr machine/m_netbsd10.c machine/m_netbsd10.c +--- machine/m_netbsd10.c Fri Jan 26 06:27:18 1996 ++++ machine/m_netbsd10.c Sat Oct 4 03:27:03 1997 +@@ -3,3 +3,3 @@ + * +- * SYNOPSIS: For a NetBSD-1.0 (4.4BSD) system ++ * SYNOPSIS: For a NetBSD-1.0 through NetBSD-1.2.1 system + * Note process resident sizes could be wrong, but ps shows +@@ -9,5 +9,5 @@ + * Originally written for BSD4.4 system by Christos Zoulas. +- * Based on the FreeBSD 2.0 version by Steven Wallace && Wolfram Schneider +- * NetBSD-1.0 port by Arne Helme +- * . ++ * Based on the FreeBSD 2.0 version by Steven Wallace && Wolfram Schneider. ++ * NetBSD-1.0 port by Arne Helme. Process ordering added by Luke Mewburn. ++ * + * This is the machine-dependent module for NetBSD-1.0 +@@ -15,2 +15,5 @@ + * NetBSD-1.0 ++ * NetBSD-1.1 ++ * NetBSD-1.2 ++ * NetBSD-1.2.1 + * +@@ -18,3 +21,3 @@ + * +- * CFLAGS: -DHAVE_GETOPT ++ * CFLAGS: -DHAVE_GETOPT -DORDER + * +@@ -24,2 +27,4 @@ + * Arne Helme <arne@acm.org> ++ * Luke Mewburn <lukem@netbsd.org> ++ * + * +@@ -30,4 +35,4 @@ -You can get the source from: - ftp://ftp.groupsys.com/pub/top/top-3.5beta5.tar.gz - -[agc - I've modified the filenames below so that the patches -work within the packages system] +-#define LASTPID /**/ /* use last pid, compiler depended */ +-/* #define LASTPID_FIXED /**/ ++/* #define LASTPID */ /* use last pid, compiler depended */ ++/* #define LASTPID_FIXED */ + #define VM_REAL /**/ /* use the same values as vmstat -s */ +@@ -53,2 +58,11 @@ -Here's the diff: ++#include "os.h" ++ ++#include <err.h> ++#include <kvm.h> ++#include <math.h> ++#include <nlist.h> ++#include <stdio.h> ++#include <unistd.h> ++ + #ifdef USE_SWAP +@@ -87,3 +101,4 @@ + /* what we consider to be process size: */ +-#define PROCSIZE(pp) (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize)) ++#define PROCSIZE(pp) \ ++ (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize)) -*** Configure Sat Dec 21 02:52:30 1996 ---- Configure Tue Apr 22 19:19:34 1997 -*************** -*** 346,352 **** - - EOF - set t_mode = 4711 -- set mode = 4711 - else if (-e /dev/kmem) then - $ls /dev/kmem >/tmp/$$.b - grep '^....r..r..' /tmp/$$.b >&/dev/null ---- 346,351 ---- -*** commands.c Wed Aug 28 00:13:57 1996 ---- commands.c Tue Apr 22 19:19:34 1997 -*************** -*** 23,30 **** ---- 23,33 ---- - #include <sys/time.h> - #include <sys/resource.h> - -+ #include "top.h" -+ #include "top.local.h" - #include "sigdesc.h" /* generated automatically */ - #include "boolean.h" -+ #include "machine.h" - #include "utils.h" - - extern int errno; -*************** -*** 42,49 **** - * either 'h' or '?'. - */ - -! show_help() -! - { - printf("Top version %s, %s\n", version_string(), copyright); - fputs("\n\n\ ---- 45,52 ---- - * either 'h' or '?'. - */ - -! show_help(statics) -! struct statics *statics; - { - printf("Top version %s, %s\n", version_string(), copyright); - fputs("\n\n\ -*************** -*** 72,79 **** - k - kill processes; send a signal to a list of processes\n\ - n or # - change number of processes to display\n", stdout); - #ifdef ORDER -! fputs("\ -! o - specify sort order (size, res, cpu, time)\n", stdout); - #endif - fputs("\ - r - renice a process\n\ ---- 75,89 ---- - k - kill processes; send a signal to a list of processes\n\ - n or # - change number of processes to display\n", stdout); - #ifdef ORDER -! { -! int i; -! -! fputs("\ -! o - specify sort order (", stdout); -! for (i = 0; statics->order_names[i] != NULL; i++) -! printf("%s%s", i == 0 ? "" : ", ", statics->order_names[i]); -! puts(")"); -! } - #endif - fputs("\ - r - renice a process\n\ -*** machine/m_netbsd10.c Fri Jan 26 16:27:18 1996 ---- machine/m_netbsd10.c Tue Jun 17 16:57:08 1997 -*************** -*** 1,49 **** - /* - * top - a top users display for Unix - * -! * SYNOPSIS: For a NetBSD-1.0 (4.4BSD) system - * Note process resident sizes could be wrong, but ps shows - * zero for them too.. - * - * DESCRIPTION: - * Originally written for BSD4.4 system by Christos Zoulas. -! * Based on the FreeBSD 2.0 version by Steven Wallace && Wolfram Schneider -! * NetBSD-1.0 port by Arne Helme -! * . -! * This is the machine-dependent module for NetBSD-1.0 - * Works for: - * NetBSD-1.0 - * - * LIBS: -lkvm - * -! * CFLAGS: -DHAVE_GETOPT - * -- * AUTHOR: Christos Zoulas <christos@ee.cornell.edu> -- * Steven Wallace <swallace@freebsd.org> -- * Wolfram Schneider <wosch@cs.tu-berlin.de> -- * Arne Helme <arne@acm.org> - * - * $Id: patch-aa,v 1.1 1997/10/03 11:45:34 agc Exp $ - */ - - -! -! #define LASTPID /**/ /* use last pid, compiler depended */ -! /* #define LASTPID_FIXED /**/ - #define VM_REAL /**/ /* use the same values as vmstat -s */ - #define USE_SWAP /**/ /* use swap usage (pstat -s), - need to much cpu time */ -- /* #define DEBUG 1 /**/ - - #include <sys/types.h> - #include <sys/signal.h> - #include <sys/param.h> -- -- #include "os.h" -- #include <stdio.h> -- #include <nlist.h> -- #include <math.h> -- #include <kvm.h> - #include <sys/errno.h> - #include <sys/sysctl.h> - #include <sys/dir.h> ---- 1,46 ---- - /* - * top - a top users display for Unix - * -! * SYNOPSIS: For a NetBSD-1.0 through NetBSD-1.2.1 system - * Note process resident sizes could be wrong, but ps shows - * zero for them too.. - * - * DESCRIPTION: - * Originally written for BSD4.4 system by Christos Zoulas. -! * Based on the FreeBSD 2.0 version by Steven Wallace and Wolfram Schneider. -! * NetBSD-1.0 port by Arne Helme. Process ordering added by Luke Mewburn. -! * -! * This is the machine-dependent module for NetBSD-1.0 and later - * Works for: - * NetBSD-1.0 -+ * NetBSD-1.1 -+ * NetBSD-1.2 -+ * NetBSD-1.2.1 - * - * LIBS: -lkvm - * -! * CFLAGS: -DHAVE_GETOPT -DORDER -! * -! * AUTHORS: Christos Zoulas <christos@ee.cornell.edu> -! * Steven Wallace <swallace@freebsd.org> -! * Wolfram Schneider <wosch@cs.tu-berlin.de> -! * Arne Helme <arne@acm.org> -! * Luke Mewburn <lukem@netbsd.org> - * - * - * $Id: patch-aa,v 1.1 1997/10/03 11:45:34 agc Exp $ - */ - - -! /* #define LASTPID */ /* use last pid, compiler depended */ -! /* #define LASTPID_FIXED */ - #define VM_REAL /**/ /* use the same values as vmstat -s */ - #define USE_SWAP /**/ /* use swap usage (pstat -s), - need to much cpu time */ - - #include <sys/types.h> - #include <sys/signal.h> - #include <sys/param.h> - #include <sys/errno.h> - #include <sys/sysctl.h> - #include <sys/dir.h> -*************** -*** 51,56 **** ---- 48,61 ---- - #include <sys/file.h> - #include <sys/time.h> - -+ #include "os.h" -+ #include <err.h> -+ #include <kvm.h> -+ #include <math.h> -+ #include <nlist.h> -+ #include <stdio.h> -+ #include <unistd.h> -+ - #ifdef USE_SWAP - #include <stdlib.h> - #include <sys/map.h> -*************** -*** 85,91 **** - ((pct) / (1.0 - exp(PP((pp), p_swtime) * logcpu)))) - - /* what we consider to be process size: */ -! #define PROCSIZE(pp) (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize)) - - /* definitions for indices in the nlist array */ - ---- 90,97 ---- - ((pct) / (1.0 - exp(PP((pp), p_swtime) * logcpu)))) - - /* what we consider to be process size: */ -! #define PROCSIZE(pp) \ -! (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize)) - - /* definitions for indices in the nlist array */ - -*************** -*** 169,175 **** - - char *state_abbrev[] = - { -! "", "start", "run\0\0\0", "sleep", "stop", "zomb", "WAIT" - }; - - ---- 175,181 ---- - - char *state_abbrev[] = - { -! "", "start", "run\0\0\0", "sleep", "stop", "zomb" - }; - - -*************** -*** 194,200 **** - #endif - #ifdef VM_REAL - static unsigned long cnt_offset; -- static long cnt; - #endif - /* these are for calculating cpu state percentages */ - ---- 200,205 ---- -*************** -*** 237,242 **** ---- 242,278 ---- - #endif - }; - -+ -+ /* these are names given to allowed sorting orders -- first is default */ -+ char *ordernames[] = { -+ "cpu", -+ "pri", -+ "res", -+ "size", -+ "state", -+ "time", -+ NULL -+ }; -+ -+ /* forward definitions for comparison functions */ -+ int compare_cpu(); -+ int compare_prio(); -+ int compare_res(); -+ int compare_size(); -+ int compare_state(); -+ int compare_time(); -+ -+ int (*proc_compares[])() = { -+ compare_cpu, -+ compare_prio, -+ compare_res, -+ compare_size, -+ compare_state, -+ compare_time, -+ NULL -+ }; -+ -+ - /* these are for keeping track of the proc array */ - - static int nproc; -*************** -*** 258,269 **** - - int - machine_init(statics) -! -! struct statics *statics; -! - { -! register int i = 0; -! register int pagesize; - - if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) - return -1; ---- 294,303 ---- - - int - machine_init(statics) -! struct statics *statics; - { -! int i = 0; -! int pagesize; - - if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) - return -1; -*************** -*** 291,300 **** - } - - -- #if (defined DEBUG) -- fprintf(stderr, "Hertz: %d\n", hz); -- #endif -- - (void) getkval(nlst[X_CCPU].n_value, (int *)(&ccpu), sizeof(ccpu), - nlst[X_CCPU].n_name); - ---- 325,330 ---- -*************** -*** 331,347 **** - statics->procstate_names = procstatenames; - statics->cpustate_names = cpustatenames; - statics->memory_names = memorynames; - - /* all done! */ - return(0); - } - -! char *format_header(uname_field) -! -! register char *uname_field; -! - { -! register char *ptr; - - ptr = header + UNAME_START; - while (*uname_field != '\0') ---- 361,377 ---- - statics->procstate_names = procstatenames; - statics->cpustate_names = cpustatenames; - statics->memory_names = memorynames; -+ statics->order_names = ordernames; - - /* all done! */ - return(0); - } - -! char * -! format_header(uname_field) -! char *uname_field; - { -! char *ptr; - - ptr = header + UNAME_START; - while (*uname_field != '\0') -*************** -*** 358,402 **** - - void - get_system_info(si) -! -! struct system_info *si; -! - { - long total; -- load_avg avenrun[3]; - - /* get the cp_time array */ - (void) getkval(cp_time_offset, (int *)cp_time, sizeof(cp_time), - nlst[X_CP_TIME].n_name); -- (void) getkval(avenrun_offset, (int *)avenrun, sizeof(avenrun), -- nlst[X_AVENRUN].n_name); - - #ifdef LASTPID -! (void) getkval(lastpid_offset, (int *)(&lastpid), sizeof(lastpid), -! "!"); - #endif - -! /* convert load averages to doubles */ -! { -! register int i; -! register double *infoloadp; -! load_avg *avenrunp; -! -! #ifdef notyet -! struct loadavg sysload; -! int size; -! getkerninfo(KINFO_LOADAVG, &sysload, &size, 0); -! #endif - -! infoloadp = si->load_avg; -! avenrunp = avenrun; -! for (i = 0; i < 3; i++) -! { -! #ifdef notyet -! *infoloadp++ = ((double) sysload.ldavg[i]) / sysload.fscale; -! #endif -! *infoloadp++ = loaddouble(*avenrunp++); -! } - } - - /* convert cp_time counts to percentages */ ---- 388,411 ---- - - void - get_system_info(si) -! struct system_info *si; - { - long total; - - /* get the cp_time array */ - (void) getkval(cp_time_offset, (int *)cp_time, sizeof(cp_time), - nlst[X_CP_TIME].n_name); - - #ifdef LASTPID -! (void) getkval(lastpid_offset, (int *)(&lastpid), sizeof(lastpid), "!"); - #endif - -! if (getloadavg(si->load_avg, NUM_AVERAGES) < 0) { -! int i; - -! warn("can't getloadavg"); -! for (i = 0; i < NUM_AVERAGES; i++) -! si->load_avg[i] = 0.0; - } - - /* convert cp_time counts to percentages */ -*************** -*** 424,431 **** - memory_stats[5] = pagetok(total.t_vm); - memory_stats[6] = -1; - memory_stats[7] = pagetok(total.t_free); -! } -! #else - struct vmmeter sum; - static unsigned int swap_delay = 0; - ---- 433,440 ---- - memory_stats[5] = pagetok(total.t_vm); - memory_stats[6] = -1; - memory_stats[7] = pagetok(total.t_free); -! -! #else /* !VM_REAL */ - struct vmmeter sum; - static unsigned int swap_delay = 0; - -*************** -*** 453,466 **** - memory_stats[4] = swapmode(); - } - /* swap_delay++; XXX Arne */ -! #else - memory_stats[4] = 0; -! #endif - - - memory_stats[7] = -1; - } -! #endif - /* set arrays and strings */ - si->cpustates = cpu_states; - si->memory = memory_stats; ---- 462,476 ---- - memory_stats[4] = swapmode(); - } - /* swap_delay++; XXX Arne */ -! #else /* !USE_SWAP */ - memory_stats[4] = 0; -! #endif /* !USE_SWAP */ - - - memory_stats[7] = -1; -+ #endif /* !VM_REAL */ - } -! - /* set arrays and strings */ - si->cpustates = cpu_states; - si->memory = memory_stats; -*************** -*** 473,495 **** - #else - si->last_pid = -1; - #endif -- - } - - static struct handle handle; - -! caddr_t get_process_info(si, sel, compare) -! -! struct system_info *si; -! struct process_select *sel; -! int (*compare)(); -! - { -! register int i; -! register int total_procs; -! register int active_procs; -! register struct kinfo_proc **prefp; -! register struct kinfo_proc *pp; - - /* these are copied out of sel for speed */ - int show_idle; ---- 483,503 ---- - #else - si->last_pid = -1; - #endif - } - - static struct handle handle; - -! caddr_t -! get_process_info(si, sel, compare) -! struct system_info *si; -! struct process_select *sel; -! int (*compare)(); - { -! int i; -! int total_procs; -! int active_procs; -! struct kinfo_proc **prefp; -! struct kinfo_proc *pp; - - /* these are copied out of sel for speed */ - int show_idle; -*************** -*** 562,576 **** - - char fmt[128]; /* static area where result is built */ - -! char *format_next_process(handle, get_userid) -! -! caddr_t handle; -! char *(*get_userid)(); -! - { -! register struct kinfo_proc *pp; -! register long cputime; -! register double pct; - struct handle *hp; - - /* find and remember the next proc structure */ ---- 570,583 ---- - - char fmt[128]; /* static area where result is built */ - -! char * -! format_next_process(handle, get_userid) -! caddr_t handle; -! char *(*get_userid)(); - { -! struct kinfo_proc *pp; -! long cputime; -! double pct; - struct handle *hp; - - /* find and remember the next proc structure */ -*************** -*** 631,642 **** - * number of symbols NOT found. - */ - -! static int check_nlist(nlst) -! -! register struct nlist *nlst; -! - { -! register int i; - - /* check to see if we got ALL the symbols we requested */ - /* this will write one line to stderr for every symbol not found */ ---- 638,648 ---- - * number of symbols NOT found. - */ - -! static int -! check_nlist(nlst) -! struct nlist *nlst; - { -! int i; - - /* check to see if we got ALL the symbols we requested */ - /* this will write one line to stderr for every symbol not found */ -*************** -*** 670,682 **** - * - */ - -! static int getkval(offset, ptr, size, refstr) -! -! unsigned long offset; -! int *ptr; -! int size; -! char *refstr; -! - { - if (kvm_read(kd, offset, (char *) ptr, size) != size) - { ---- 676,687 ---- - * - */ - -! static int -! getkval(offset, ptr, size, refstr) -! unsigned long offset; -! int *ptr; -! int size; -! char *refstr; - { - if (kvm_read(kd, offset, (char *) ptr, size) != size) - { -*************** -*** 694,768 **** - return(1); - } - -! /* comparison routine for qsort */ - - /* -! * proc_compare - comparison function for "qsort" -! * Compares the resource consumption of two processes using five -! * distinct keys. The keys (in descending order of importance) are: -! * percent cpu, cpu ticks, state, resident set size, total virtual -! * memory usage. The process states are ordered as follows (from least -! * to most important): WAIT, zombie, sleep, stop, start, run. The -! * array declaration below maps a process state index into a number -! * that reflects this ordering. - */ - -! static unsigned char sorted_state[] = -! { -! 0, /* not used */ -! 3, /* sleep */ -! 1, /* ABANDONED (WAIT) */ -! 6, /* run */ -! 5, /* start */ -! 2, /* zombie */ -! 4 /* stop */ - }; -! - int -! proc_compare(pp1, pp2) - -! struct proc **pp1; -! struct proc **pp2; - - { -! register struct kinfo_proc *p1; -! register struct kinfo_proc *p2; -! register int result; -! register pctcpu lresult; - - /* remove one level of indirection */ - p1 = *(struct kinfo_proc **) pp1; - p2 = *(struct kinfo_proc **) pp2; - -! /* compare percent cpu (pctcpu) */ -! if ((lresult = PP(p2, p_pctcpu) - PP(p1, p_pctcpu)) == 0) -! { -! /* use cpticks to break the tie */ -! if ((result = PP(p2, p_cpticks) - PP(p1, p_cpticks)) == 0) -! { -! /* use process state to break the tie */ -! if ((result = sorted_state[(unsigned char) PP(p2, p_stat)] - -! sorted_state[(unsigned char) PP(p1, p_stat)]) == 0) -! { -! /* use priority to break the tie */ -! if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0) -! { -! /* use resident set size (rssize) to break the tie */ -! if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) -! { -! /* use total memory to break the tie */ -! result = PROCSIZE(p2) - PROCSIZE(p1); -! } -! } -! } -! } -! } -! else -! { -! result = lresult < 0 ? -1 : 1; -! } - -! return(result); - } - - ---- 699,913 ---- - return(1); - } - -! /* comparison routines for qsort */ - - /* -! * There are currently four possible comparison routines. main selects -! * one of these by indexing in to the array proc_compares. -! * -! * Possible keys are defined as macros below. Currently these keys are -! * defined: percent cpu, cpu ticks, process state, resident set size, -! * total virtual memory usage. The process states are ordered as follows -! * (from least to most important): WAIT, zombie, sleep, stop, start, run. -! * The array declaration below maps a process state index into a number -! * that reflects this ordering. - */ - -! /* -! * First, the possible comparison keys. These are defined in such a way -! * that they can be merely listed in the source code to define the actual -! * desired ordering. -! */ -! -! #define ORDERKEY_PCTCPU \ -! if (lresult = PP(p2, p_pctcpu) - PP(p1, p_pctcpu),\ -! (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) -! -! #define ORDERKEY_CPTICKS \ -! if (lresult = PP(p2, p_rtime).tv_sec - PP(p1, p_rtime).tv_sec,\ -! (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) -! -! #define ORDERKEY_STATE \ -! if ((result = sorted_state[(int)PP(p2, p_stat)] - \ -! sorted_state[(int)PP(p1, p_stat)] ) == 0) -! -! #define ORDERKEY_PRIO \ -! if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0) -! -! #define ORDERKEY_RSSIZE \ -! if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) -! -! #define ORDERKEY_MEM \ -! if ((result = (PROCSIZE(p2) - PROCSIZE(p1))) == 0) -! -! /* -! * Now the array that maps process state to a weight. -! * The order of the elements should match those in state_abbrev[] -! */ -! -! static int sorted_state[] = { -! 0, /* (not used) ? */ -! 4, /* "start" SIDL */ -! 5, /* "run" SRUN */ -! 2, /* "sleep" SSLEEP */ -! 3, /* "stop" SSTOP */ -! 1, /* "zomb" SZOMB */ - }; -! -! /* compare_cpu - the comparison function for sorting by cpu percentage */ -! - int -! compare_cpu(pp1, pp2) -! struct proc **pp1, **pp2; -! { -! struct kinfo_proc *p1; -! struct kinfo_proc *p2; -! int result; -! pctcpu lresult; - -! /* remove one level of indirection */ -! p1 = *(struct kinfo_proc **) pp1; -! p2 = *(struct kinfo_proc **) pp2; -! -! ORDERKEY_PCTCPU -! ORDERKEY_CPTICKS -! ORDERKEY_STATE -! ORDERKEY_PRIO -! ORDERKEY_RSSIZE -! ORDERKEY_MEM -! ; -! -! return (result); -! } - -+ /* compare_prio - the comparison function for sorting by process priority */ -+ -+ int -+ compare_prio(pp1, pp2) -+ struct proc **pp1, **pp2; - { -! struct kinfo_proc *p1; -! struct kinfo_proc *p2; -! int result; -! pctcpu lresult; - - /* remove one level of indirection */ - p1 = *(struct kinfo_proc **) pp1; - p2 = *(struct kinfo_proc **) pp2; - -! ORDERKEY_PRIO -! ORDERKEY_PCTCPU -! ORDERKEY_CPTICKS -! ORDERKEY_STATE -! ORDERKEY_RSSIZE -! ORDERKEY_MEM -! ; -! -! return (result); -! } -! -! /* compare_res - the comparison function for sorting by resident set size */ -! -! int -! compare_res(pp1, pp2) -! struct proc **pp1, **pp2; -! { -! struct kinfo_proc *p1; -! struct kinfo_proc *p2; -! int result; -! pctcpu lresult; -! -! /* remove one level of indirection */ -! p1 = *(struct kinfo_proc **) pp1; -! p2 = *(struct kinfo_proc **) pp2; - -! ORDERKEY_RSSIZE -! ORDERKEY_MEM -! ORDERKEY_PCTCPU -! ORDERKEY_CPTICKS -! ORDERKEY_STATE -! ORDERKEY_PRIO -! ; -! -! return (result); -! } -! -! /* compare_size - the comparison function for sorting by total memory usage */ -! -! int -! compare_size(pp1, pp2) -! struct proc **pp1, **pp2; -! { -! struct kinfo_proc *p1; -! struct kinfo_proc *p2; -! int result; -! pctcpu lresult; -! -! /* remove one level of indirection */ -! p1 = *(struct kinfo_proc **) pp1; -! p2 = *(struct kinfo_proc **) pp2; -! -! ORDERKEY_MEM -! ORDERKEY_RSSIZE -! ORDERKEY_PCTCPU -! ORDERKEY_CPTICKS -! ORDERKEY_STATE -! ORDERKEY_PRIO -! ; -! -! return (result); -! } -! -! /* compare_state - the comparison function for sorting by process state */ -! -! int -! compare_state(pp1, pp2) -! struct proc **pp1, **pp2; -! { -! struct kinfo_proc *p1; -! struct kinfo_proc *p2; -! int result; -! pctcpu lresult; -! -! /* remove one level of indirection */ -! p1 = *(struct kinfo_proc **) pp1; -! p2 = *(struct kinfo_proc **) pp2; -! -! ORDERKEY_STATE -! ORDERKEY_PCTCPU -! ORDERKEY_CPTICKS -! ORDERKEY_PRIO -! ORDERKEY_RSSIZE -! ORDERKEY_MEM -! ; -! -! return (result); -! } -! -! /* compare_time - the comparison function for sorting by total cpu time */ -! -! int -! compare_time(pp1, pp2) -! struct proc **pp1, **pp2; -! { -! struct kinfo_proc *p1; -! struct kinfo_proc *p2; -! int result; -! pctcpu lresult; -! -! /* remove one level of indirection */ -! p1 = *(struct kinfo_proc **) pp1; -! p2 = *(struct kinfo_proc **) pp2; -! -! ORDERKEY_CPTICKS -! ORDERKEY_PCTCPU -! ORDERKEY_STATE -! ORDERKEY_PRIO -! ORDERKEY_MEM -! ORDERKEY_RSSIZE -! ; -! -! return (result); - } - - -*************** -*** 776,789 **** - * and "renice" commands. - */ - -! int proc_owner(pid) -! -! int pid; -! - { -! register int cnt; -! register struct kinfo_proc **prefp; -! register struct kinfo_proc *pp; - - prefp = pref; - cnt = pref_len; ---- 921,933 ---- - * and "renice" commands. - */ - -! int -! proc_owner(pid) -! int pid; - { -! int cnt; -! struct kinfo_proc **prefp; -! struct kinfo_proc *pp; - - prefp = pref; - cnt = pref_len; -*************** -*** 830,835 **** ---- 974,980 ---- - struct map *swapmap, *kswapmap; - struct mapent *mp, *freemp; - -+ l = 0; - KGET(VM_NSWAP, nswap); - KGET(VM_NSWDEV, nswdev); - KGET(VM_DMMAX, dmmax); -*************** -*** 936,941 **** - return (int)(((double)used / (double)avail * 100.0) + 0.5); - } - -! -! #endif -! ---- 1081,1084 ---- - return (int)(((double)used / (double)avail * 100.0) + 0.5); - } - -! #endif /* USE_SWAP */ -*** /dev/null Thu Jan 1 10:00:00 1970 ---- machine/m_netbsd13.c Tue Jun 17 17:41:07 1997 -*************** -*** 0 **** ---- 1,841 ---- -+ /* -+ * top - a top users display for Unix -+ * -+ * SYNOPSIS: For a NetBSD-1.3 (or later) system -+ * -+ * DESCRIPTION: -+ * Originally written for BSD4.4 system by Christos Zoulas. -+ * Based on the FreeBSD 2.0 version by Steven Wallace and Wolfram Schneider. -+ * NetBSD-1.0 port by Arne Helme. Process ordering by Luke Mewburn. -+ * NetBSD-1.3 port by Luke Mewburn, based on code by Matthew Green. -+ * -+ * This is the machine-dependent module for NetBSD-1.3 and later -+ * Works for: -+ * NetBSD-1.3 -+ * -+ * LIBS: -lkvm -+ * -+ * CFLAGS: -DHAVE_GETOPT -DORDER -+ * -+ * AUTHORS: Christos Zoulas <christos@ee.cornell.edu> -+ * Steven Wallace <swallace@freebsd.org> -+ * Wolfram Schneider <wosch@cs.tu-berlin.de> -+ * Arne Helme <arne@acm.org> -+ * Luke Mewburn <lukem@netbsd.org> -+ * Matthew Green <mrg@eterna.com.au> -+ * -+ * -+ * $Id: patch-aa,v 1.1 1997/10/03 11:45:34 agc Exp $ -+ */ -+ -+ #include <sys/types.h> -+ #include <sys/signal.h> -+ #include <sys/param.h> -+ #include <sys/stat.h> -+ #include <sys/errno.h> -+ #include <sys/sysctl.h> -+ #include <sys/dir.h> -+ #include <sys/dkstat.h> -+ #include <sys/file.h> -+ #include <sys/time.h> -+ -+ #include <vm/vm_swap.h> -+ -+ #include "os.h" -+ #include <err.h> -+ #include <errno.h> -+ #include <kvm.h> -+ #include <math.h> -+ #include <nlist.h> -+ #include <stdio.h> -+ #include <stdlib.h> -+ #include <string.h> -+ #include <unistd.h> -+ -+ static int check_nlist __P((struct nlist *)); -+ static int getkval __P((unsigned long, int *, int, char *)); -+ extern char* printable __P((char *)); -+ -+ #include "top.h" -+ #include "machine.h" -+ #include "utils.h" -+ -+ -+ /* get_process_info passes back a handle. This is what it looks like: */ -+ -+ struct handle -+ { -+ struct kinfo_proc **next_proc; /* points to next valid proc pointer */ -+ int remaining; /* number of pointers remaining */ -+ }; -+ -+ /* declarations for load_avg */ -+ #include "loadavg.h" -+ -+ #define PP(pp, field) ((pp)->kp_proc . field) -+ #define EP(pp, field) ((pp)->kp_eproc . field) -+ #define VP(pp, field) ((pp)->kp_eproc.e_vm . field) -+ -+ /* define what weighted cpu is. */ -+ #define weighted_cpu(pct, pp) (PP((pp), p_swtime) == 0 ? 0.0 : \ -+ ((pct) / (1.0 - exp(PP((pp), p_swtime) * logcpu)))) -+ -+ /* what we consider to be process size: */ -+ #define PROCSIZE(pp) \ -+ (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize)) -+ -+ /* definitions for indices in the nlist array */ -+ -+ -+ static struct nlist nlst[] = { -+ #define X_CCPU 0 -+ { "_ccpu" }, /* 0 */ -+ #define X_CP_TIME 1 -+ { "_cp_time" }, /* 1 */ -+ #define X_HZ 2 -+ { "_hz" }, /* 2 */ -+ #define X_STATHZ 3 -+ { "_stathz" }, /* 3 */ -+ #define X_AVENRUN 4 -+ { "_averunnable" }, /* 4 */ -+ #define X_CNT 5 -+ { "_cnt" }, -+ -+ { 0 } -+ }; -+ -+ /* -+ * These definitions control the format of the per-process area -+ */ -+ -+ static char header[] = -+ " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; -+ /* 0123456 -- field to fill in starts at header+6 */ -+ #define UNAME_START 6 -+ -+ #define Proc_format \ -+ "%5d %-8.8s %3d %4d%7s %5s %-5s%7s %5.2f%% %5.2f%% %.14s" -+ -+ -+ /* process state names for the "STATE" column of the display */ -+ /* the extra nulls in the string "run" are for adding a slash and -+ the processor number when needed */ -+ -+ char *state_abbrev[] = -+ { -+ "", "start", "run\0\0\0", "sleep", "stop", "zomb" -+ }; -+ -+ -+ static kvm_t *kd; -+ -+ /* values that we stash away in _init and use in later routines */ -+ -+ static double logcpu; -+ -+ /* these are retrieved from the kernel in _init */ -+ -+ static long hz; -+ static load_avg ccpu; -+ -+ /* these are offsets obtained via nlist and used in the get_ functions */ -+ -+ static unsigned long cp_time_offset; -+ static unsigned long avenrun_offset; -+ static unsigned long cnt_offset; -+ /* these are for calculating cpu state percentages */ -+ -+ static long cp_time[CPUSTATES]; -+ static long cp_old[CPUSTATES]; -+ static long cp_diff[CPUSTATES]; -+ -+ /* these are for detailing the process states */ -+ -+ int process_states[7]; -+ char *procstatenames[] = { -+ "", " starting, ", " running, ", " sleeping, ", " stopped, ", -+ " zombie, ", " ABANDONED, ", -+ NULL -+ }; -+ -+ /* these are for detailing the cpu states */ -+ -+ int cpu_states[CPUSTATES]; -+ char *cpustatenames[] = { -+ "user", "nice", "system", "interrupt", "idle", NULL -+ }; -+ -+ /* these are for detailing the memory statistics */ -+ -+ int memory_stats[7]; -+ char *memorynames[] = { -+ "K Act ", "K Inact ", "K Wired ", "K Free ", -+ "K Swap ", "K Swap free ", -+ NULL -+ }; -+ -+ -+ /* these are names given to allowed sorting orders -- first is default */ -+ char *ordernames[] = { -+ "cpu", -+ "pri", -+ "res", -+ "size", -+ "state", -+ "time", -+ NULL -+ }; -+ -+ /* forward definitions for comparison functions */ -+ int compare_cpu(); -+ int compare_prio(); -+ int compare_res(); -+ int compare_size(); -+ int compare_state(); -+ int compare_time(); -+ -+ int (*proc_compares[])() = { -+ compare_cpu, -+ compare_prio, -+ compare_res, -+ compare_size, -+ compare_state, -+ compare_time, -+ NULL -+ }; -+ -+ -+ /* these are for keeping track of the proc array */ -+ -+ static int nproc; -+ static int onproc = -1; -+ static int pref_len; -+ static struct kinfo_proc *pbase; -+ static struct kinfo_proc **pref; -+ -+ /* these are for getting the memory statistics */ -+ -+ static int pageshift; /* log base 2 of the pagesize */ -+ -+ /* define pagetok in terms of pageshift */ -+ -+ #define pagetok(size) ((size) << pageshift) -+ -+ /* useful externals */ -+ long percentages(); -+ -+ int -+ machine_init(statics) -+ struct statics *statics; -+ { -+ int i = 0; -+ int pagesize; -+ -+ if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) -+ return -1; -+ -+ -+ /* get the list of symbols we want to access in the kernel */ -+ (void) kvm_nlist(kd, nlst); -+ if (nlst[0].n_type == 0) -+ { -+ fprintf(stderr, "top: nlist failed\n"); -+ return(-1); -+ } -+ -+ /* make sure they were all found */ -+ if (i > 0 && check_nlist(nlst) > 0) -+ { -+ return(-1); -+ } -+ -+ /* get the symbol values out of kmem */ -+ (void) getkval(nlst[X_STATHZ].n_value, (int *)(&hz), sizeof(hz), "!"); -+ if (!hz) { -+ (void) getkval(nlst[X_HZ].n_value, (int *)(&hz), sizeof(hz), -+ nlst[X_HZ].n_name); -+ } -+ -+ -+ (void) getkval(nlst[X_CCPU].n_value, (int *)(&ccpu), sizeof(ccpu), -+ nlst[X_CCPU].n_name); -+ -+ /* stash away certain offsets for later use */ -+ cp_time_offset = nlst[X_CP_TIME].n_value; -+ avenrun_offset = nlst[X_AVENRUN].n_value; -+ cnt_offset = nlst[X_CNT].n_value; -+ -+ /* this is used in calculating WCPU -- calculate it ahead of time */ -+ logcpu = log(loaddouble(ccpu)); -+ -+ pbase = NULL; -+ pref = NULL; -+ nproc = 0; -+ onproc = -1; -+ /* get the page size with "getpagesize" and calculate pageshift from it */ -+ pagesize = getpagesize(); -+ pageshift = 0; -+ while (pagesize > 1) -+ { -+ pageshift++; -+ pagesize >>= 1; -+ } -+ -+ /* we only need the amount of log(2)1024 for our conversion */ -+ pageshift -= LOG1024; -+ -+ /* fill in the statics information */ -+ statics->procstate_names = procstatenames; -+ statics->cpustate_names = cpustatenames; -+ statics->memory_names = memorynames; -+ statics->order_names = ordernames; -+ -+ /* all done! */ -+ return(0); -+ } -+ -+ char * -+ format_header(uname_field) -+ char *uname_field; -+ { -+ char *ptr; -+ -+ ptr = header + UNAME_START; -+ while (*uname_field != '\0') -+ { -+ *ptr++ = *uname_field++; -+ } -+ -+ return(header); -+ } -+ -+ void -+ get_system_info(si) -+ struct system_info *si; -+ { -+ long total; -+ struct vmmeter sum; -+ struct swapent *sep; -+ int totalsize, size, totalinuse, inuse, ncounted; -+ int rnswap, nswap; -+ -+ /* get the cp_time array */ -+ (void) getkval(cp_time_offset, (int *)cp_time, sizeof(cp_time), -+ nlst[X_CP_TIME].n_name); -+ -+ if (getloadavg(si->load_avg, NUM_AVERAGES) < 0) { -+ int i; -+ -+ warn("can't getloadavg"); -+ for (i = 0; i < NUM_AVERAGES; i++) -+ si->load_avg[i] = 0.0; -+ } -+ -+ /* convert cp_time counts to percentages */ -+ total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); -+ -+ /* sum memory statistics */ -+ -+ (void) getkval(cnt_offset, (int *)(&sum), sizeof(sum), "_cnt"); -+ -+ /* convert memory stats to Kbytes */ -+ memory_stats[0] = pagetok(sum.v_active_count); -+ memory_stats[1] = pagetok(sum.v_inactive_count); -+ memory_stats[2] = pagetok(sum.v_wire_count); -+ memory_stats[3] = pagetok(sum.v_free_count); -+ -+ memory_stats[4] = memory_stats[5] = 0; -+ -+ sep = NULL; -+ do { -+ nswap = swapctl(SWAP_NSWAP, 0, 0); -+ if (nswap < 1) -+ break; -+ sep = (struct swapent *)malloc(nswap * sizeof(*sep)); -+ if (sep == NULL) -+ break; -+ rnswap = swapctl(SWAP_STATS, (void *)sep, nswap); -+ if (nswap != rnswap) -+ break; -+ -+ totalsize = totalinuse = ncounted = 0; -+ for (; rnswap-- > 0; sep++) { -+ ncounted++; -+ size = sep->se_nblks; -+ inuse = sep->se_inuse; -+ totalsize += size; -+ totalinuse += inuse; -+ } -+ memory_stats[4] = dbtob(totalinuse) / 1024; -+ memory_stats[5] = dbtob(totalsize) / 1024 - memory_stats[4]; -+ } while (0); -+ if (sep) -+ free(sep); -+ -+ memory_stats[6] = -1; -+ -+ /* set arrays and strings */ -+ si->cpustates = cpu_states; -+ si->memory = memory_stats; -+ si->last_pid = -1; -+ } -+ -+ static struct handle handle; -+ -+ caddr_t -+ get_process_info(si, sel, compare) -+ struct system_info *si; -+ struct process_select *sel; -+ int (*compare)(); -+ { -+ int i; -+ int total_procs; -+ int active_procs; -+ struct kinfo_proc **prefp; -+ struct kinfo_proc *pp; -+ -+ /* these are copied out of sel for speed */ -+ int show_idle; -+ int show_system; -+ int show_uid; -+ int show_command; -+ -+ -+ pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc); -+ if (nproc > onproc) -+ pref = (struct kinfo_proc **) realloc(pref, sizeof(struct kinfo_proc *) -+ * (onproc = nproc)); -+ if (pref == NULL || pbase == NULL) { -+ (void) fprintf(stderr, "top: Out of memory.\n"); -+ quit(23); -+ } -+ /* get a pointer to the states summary array */ -+ si->procstates = process_states; -+ -+ /* set up flags which define what we are going to select */ -+ show_idle = sel->idle; -+ show_system = sel->system; -+ show_uid = sel->uid != -1; -+ show_command = sel->command != NULL; -+ -+ /* count up process states and get pointers to interesting procs */ -+ total_procs = 0; -+ active_procs = 0; -+ memset((char *)process_states, 0, sizeof(process_states)); -+ prefp = pref; -+ for (pp = pbase, i = 0; i < nproc; pp++, i++) -+ { -+ /* -+ * Place pointers to each valid proc structure in pref[]. -+ * Process slots that are actually in use have a non-zero -+ * status field. Processes with P_SYSTEM set are system -+ * processes---these get ignored unless show_sysprocs is set. -+ */ -+ if (PP(pp, p_stat) != 0 && -+ (show_system || ((PP(pp, p_flag) & P_SYSTEM) == 0))) -+ { -+ total_procs++; -+ process_states[(unsigned char) PP(pp, p_stat)]++; -+ if ((PP(pp, p_stat) != SZOMB) && -+ (show_idle || (PP(pp, p_pctcpu) != 0) || -+ (PP(pp, p_stat) == SRUN)) && -+ (!show_uid || EP(pp, e_pcred.p_ruid) == (uid_t)sel->uid)) -+ { -+ *prefp++ = pp; -+ active_procs++; -+ } -+ } -+ } -+ -+ /* if requested, sort the "interesting" processes */ -+ if (compare != NULL) -+ { -+ qsort((char *)pref, active_procs, sizeof(struct kinfo_proc *), compare); -+ } -+ -+ /* remember active and total counts */ -+ si->p_total = total_procs; -+ si->p_active = pref_len = active_procs; -+ -+ /* pass back a handle */ -+ handle.next_proc = pref; -+ handle.remaining = active_procs; -+ return((caddr_t)&handle); -+ } -+ -+ char fmt[128]; /* static area where result is built */ -+ -+ char * -+ format_next_process(handle, get_userid) -+ caddr_t handle; -+ char *(*get_userid)(); -+ { -+ struct kinfo_proc *pp; -+ long cputime; -+ double pct; -+ struct handle *hp; -+ -+ /* find and remember the next proc structure */ -+ hp = (struct handle *)handle; -+ pp = *(hp->next_proc++); -+ hp->remaining--; -+ -+ -+ /* get the process's user struct and set cputime */ -+ if ((PP(pp, p_flag) & P_INMEM) == 0) { -+ /* -+ * Print swapped processes as <pname> -+ */ -+ char *comm = PP(pp, p_comm); -+ #define COMSIZ sizeof(PP(pp, p_comm)) -+ char buf[COMSIZ]; -+ (void) strncpy(buf, comm, COMSIZ); -+ comm[0] = '<'; -+ (void) strncpy(&comm[1], buf, COMSIZ - 2); -+ comm[COMSIZ - 2] = '\0'; -+ (void) strncat(comm, ">", COMSIZ - 1); -+ comm[COMSIZ - 1] = '\0'; -+ } -+ -+ #if 0 -+ /* This does not produce the correct results */ -+ cputime = PP(pp, p_uticks) + PP(pp, p_sticks) + PP(pp, p_iticks); -+ #endif -+ cputime = PP(pp, p_rtime).tv_sec; /* This does not count interrupts */ -+ -+ /* calculate the base for cpu percentages */ -+ pct = pctdouble(PP(pp, p_pctcpu)); -+ -+ #define Proc_format \ -+ "%5d %-8.8s %3d %4d%7s %5s %-5s%7s %5.2f%% %5.2f%% %.14s" -+ -+ /* format this entry */ -+ sprintf(fmt, -+ Proc_format, -+ PP(pp, p_pid), -+ (*get_userid)(EP(pp, e_pcred.p_ruid)), -+ PP(pp, p_priority) - PZERO, -+ PP(pp, p_nice) - NZERO, -+ format_k(pagetok(PROCSIZE(pp))), -+ format_k(pagetok(VP(pp, vm_rssize))), -+ state_abbrev[(unsigned char) PP(pp, p_stat)], -+ format_time(cputime), -+ 10000.0 * weighted_cpu(pct, pp) / hz, -+ 10000.0 * pct / hz, -+ printable(PP(pp, p_comm))); -+ -+ /* return the result */ -+ return(fmt); -+ } -+ -+ -+ /* -+ * check_nlist(nlst) - checks the nlist to see if any symbols were not -+ * found. For every symbol that was not found, a one-line -+ * message is printed to stderr. The routine returns the -+ * number of symbols NOT found. -+ */ -+ -+ static int -+ check_nlist(nlst) -+ struct nlist *nlst; -+ { -+ int i; -+ -+ /* check to see if we got ALL the symbols we requested */ -+ /* this will write one line to stderr for every symbol not found */ -+ -+ i = 0; -+ while (nlst->n_name != NULL) -+ { -+ if (nlst->n_type == 0) -+ { -+ /* this one wasn't found */ -+ (void) fprintf(stderr, "kernel: no symbol named `%s'\n", -+ nlst->n_name); -+ i = 1; -+ } -+ nlst++; -+ } -+ -+ return(i); -+ } -+ -+ -+ /* -+ * getkval(offset, ptr, size, refstr) - get a value out of the kernel. -+ * "offset" is the byte offset into the kernel for the desired value, -+ * "ptr" points to a buffer into which the value is retrieved, -+ * "size" is the size of the buffer (and the object to retrieve), -+ * "refstr" is a reference string used when printing error meessages, -+ * if "refstr" starts with a '!', then a failure on read will not -+ * be fatal (this may seem like a silly way to do things, but I -+ * really didn't want the overhead of another argument). -+ * -+ */ -+ -+ static int -+ getkval(offset, ptr, size, refstr) -+ unsigned long offset; -+ int *ptr; -+ int size; -+ char *refstr; -+ { -+ if (kvm_read(kd, offset, (char *) ptr, size) != size) -+ { -+ if (*refstr == '!') -+ { -+ return(0); -+ } -+ else -+ { -+ fprintf(stderr, "top: kvm_read for %s: %s\n", -+ refstr, strerror(errno)); -+ quit(23); -+ } -+ } -+ return(1); -+ } -+ -+ /* comparison routines for qsort */ -+ -+ /* -+ * There are currently four possible comparison routines. main selects -+ * one of these by indexing in to the array proc_compares. -+ * -+ * Possible keys are defined as macros below. Currently these keys are -+ * defined: percent cpu, cpu ticks, process state, resident set size, -+ * total virtual memory usage. The process states are ordered as follows -+ * (from least to most important): WAIT, zombie, sleep, stop, start, run. -+ * The array declaration below maps a process state index into a number -+ * that reflects this ordering. -+ */ -+ -+ /* -+ * First, the possible comparison keys. These are defined in such a way -+ * that they can be merely listed in the source code to define the actual -+ * desired ordering. -+ */ -+ -+ #define ORDERKEY_PCTCPU \ -+ if (lresult = PP(p2, p_pctcpu) - PP(p1, p_pctcpu),\ -+ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) -+ -+ #define ORDERKEY_CPTICKS \ -+ if (lresult = PP(p2, p_rtime).tv_sec - PP(p1, p_rtime).tv_sec,\ -+ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) -+ -+ #define ORDERKEY_STATE \ -+ if ((result = sorted_state[(int)PP(p2, p_stat)] - \ -+ sorted_state[(int)PP(p1, p_stat)] ) == 0) -+ -+ #define ORDERKEY_PRIO \ -+ if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0) -+ -+ #define ORDERKEY_RSSIZE \ -+ if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) -+ -+ #define ORDERKEY_MEM \ -+ if ((result = (PROCSIZE(p2) - PROCSIZE(p1))) == 0) -+ -+ /* -+ * Now the array that maps process state to a weight. -+ * The order of the elements should match those in state_abbrev[] -+ */ -+ -+ static int sorted_state[] = { -+ 0, /* (not used) ? */ -+ 4, /* "start" SIDL */ -+ 5, /* "run" SRUN */ -+ 2, /* "sleep" SSLEEP */ -+ 3, /* "stop" SSTOP */ -+ 1, /* "zomb" SZOMB */ -+ }; -+ -+ /* compare_cpu - the comparison function for sorting by cpu percentage */ -+ -+ int -+ compare_cpu(pp1, pp2) -+ struct proc **pp1, **pp2; -+ { -+ struct kinfo_proc *p1; -+ struct kinfo_proc *p2; -+ int result; -+ pctcpu lresult; -+ -+ /* remove one level of indirection */ -+ p1 = *(struct kinfo_proc **) pp1; -+ p2 = *(struct kinfo_proc **) pp2; -+ -+ ORDERKEY_PCTCPU -+ ORDERKEY_CPTICKS -+ ORDERKEY_STATE -+ ORDERKEY_PRIO -+ ORDERKEY_RSSIZE -+ ORDERKEY_MEM -+ ; -+ -+ return (result); -+ } -+ -+ /* compare_prio - the comparison function for sorting by process priority */ -+ -+ int -+ compare_prio(pp1, pp2) -+ struct proc **pp1, **pp2; -+ { -+ struct kinfo_proc *p1; -+ struct kinfo_proc *p2; -+ int result; -+ pctcpu lresult; -+ -+ /* remove one level of indirection */ -+ p1 = *(struct kinfo_proc **) pp1; -+ p2 = *(struct kinfo_proc **) pp2; -+ -+ ORDERKEY_PRIO -+ ORDERKEY_PCTCPU -+ ORDERKEY_CPTICKS -+ ORDERKEY_STATE -+ ORDERKEY_RSSIZE -+ ORDERKEY_MEM -+ ; -+ -+ return (result); -+ } -+ -+ /* compare_res - the comparison function for sorting by resident set size */ -+ -+ int -+ compare_res(pp1, pp2) -+ struct proc **pp1, **pp2; -+ { -+ struct kinfo_proc *p1; -+ struct kinfo_proc *p2; -+ int result; -+ pctcpu lresult; -+ -+ /* remove one level of indirection */ -+ p1 = *(struct kinfo_proc **) pp1; -+ p2 = *(struct kinfo_proc **) pp2; -+ -+ ORDERKEY_RSSIZE -+ ORDERKEY_MEM -+ ORDERKEY_PCTCPU -+ ORDERKEY_CPTICKS -+ ORDERKEY_STATE -+ ORDERKEY_PRIO -+ ; -+ -+ return (result); -+ } -+ -+ /* compare_size - the comparison function for sorting by total memory usage */ -+ -+ int -+ compare_size(pp1, pp2) -+ struct proc **pp1, **pp2; -+ { -+ struct kinfo_proc *p1; -+ struct kinfo_proc *p2; -+ int result; -+ pctcpu lresult; -+ -+ /* remove one level of indirection */ -+ p1 = *(struct kinfo_proc **) pp1; -+ p2 = *(struct kinfo_proc **) pp2; -+ -+ ORDERKEY_MEM -+ ORDERKEY_RSSIZE -+ ORDERKEY_PCTCPU -+ ORDERKEY_CPTICKS -+ ORDERKEY_STATE -+ ORDERKEY_PRIO -+ ; -+ -+ return (result); -+ } -+ -+ /* compare_state - the comparison function for sorting by process state */ -+ -+ int -+ compare_state(pp1, pp2) -+ struct proc **pp1, **pp2; -+ { -+ struct kinfo_proc *p1; -+ struct kinfo_proc *p2; -+ int result; -+ pctcpu lresult; -+ -+ /* remove one level of indirection */ -+ p1 = *(struct kinfo_proc **) pp1; -+ p2 = *(struct kinfo_proc **) pp2; -+ -+ ORDERKEY_STATE -+ ORDERKEY_PCTCPU -+ ORDERKEY_CPTICKS -+ ORDERKEY_PRIO -+ ORDERKEY_RSSIZE -+ ORDERKEY_MEM -+ ; -+ -+ return (result); -+ } -+ -+ /* compare_time - the comparison function for sorting by total cpu time */ -+ -+ int -+ compare_time(pp1, pp2) -+ struct proc **pp1, **pp2; -+ { -+ struct kinfo_proc *p1; -+ struct kinfo_proc *p2; -+ int result; -+ pctcpu lresult; -+ -+ /* remove one level of indirection */ -+ p1 = *(struct kinfo_proc **) pp1; -+ p2 = *(struct kinfo_proc **) pp2; -+ -+ ORDERKEY_CPTICKS -+ ORDERKEY_PCTCPU -+ ORDERKEY_STATE -+ ORDERKEY_PRIO -+ ORDERKEY_MEM -+ ORDERKEY_RSSIZE -+ ; -+ -+ return (result); -+ } -+ -+ -+ /* -+ * proc_owner(pid) - returns the uid that owns process "pid", or -1 if -+ * the process does not exist. -+ * It is EXTREMLY IMPORTANT that this function work correctly. -+ * If top runs setuid root (as in SVR4), then this function -+ * is the only thing that stands in the way of a serious -+ * security problem. It validates requests for the "kill" -+ * and "renice" commands. -+ */ -+ -+ int -+ proc_owner(pid) -+ int pid; -+ { -+ int cnt; -+ struct kinfo_proc **prefp; -+ struct kinfo_proc *pp; -+ -+ prefp = pref; -+ cnt = pref_len; -+ while (--cnt >= 0) -+ { -+ pp = *prefp++; -+ if (PP(pp, p_pid) == (pid_t)pid) -+ { -+ return((int)EP(pp, e_pcred.p_ruid)); -+ } -+ } -+ return(-1); -+ } -*** top.c Fri Sep 13 05:50:53 1996 ---- top.c Tue Apr 22 19:19:34 1997 -*************** -*** 714,720 **** - case CMD_help2: - reset_display(); - clear(); -! show_help(); - standout("Hit any key to continue: "); - fflush(stdout); - (void) read(0, &ch, 1); ---- 714,720 ---- - case CMD_help2: - reset_display(); - clear(); -! show_help(&statics); - standout("Hit any key to continue: "); - fflush(stdout); - (void) read(0, &ch, 1); -*** utils.c Wed Sep 11 06:15:14 1996 ---- utils.c Tue Apr 22 19:19:34 1997 -*************** -*** 16,21 **** ---- 16,23 ---- - #include "top.h" - #include "os.h" - -+ #include <errno.h> -+ - int atoiwi(str) - - char *str; +@@ -171,3 +186,3 @@ + { +- "", "start", "run\0\0\0", "sleep", "stop", "zomb", "WAIT" ++ "", "start", "run\0\0\0", "sleep", "stop", "zomb" + }; +@@ -196,3 +211,2 @@ + static unsigned long cnt_offset; +-static long cnt; + #endif +@@ -239,2 +253,33 @@ + ++ ++/* these are names given to allowed sorting orders -- first is default */ ++char *ordernames[] = { ++ "cpu", ++ "pri", ++ "res", ++ "size", ++ "state", ++ "time", ++ NULL ++}; ++ ++/* forward definitions for comparison functions */ ++int compare_cpu(); ++int compare_prio(); ++int compare_res(); ++int compare_size(); ++int compare_state(); ++int compare_time(); ++ ++int (*proc_compares[])() = { ++ compare_cpu, ++ compare_prio, ++ compare_res, ++ compare_size, ++ compare_state, ++ compare_time, ++ NULL ++}; ++ ++ + /* these are for keeping track of the proc array */ +@@ -260,8 +305,6 @@ + machine_init(statics) +- +-struct statics *statics; +- ++ struct statics *statics; + { +- register int i = 0; +- register int pagesize; ++ int i = 0; ++ int pagesize; + +@@ -293,6 +336,2 @@ + +-#if (defined DEBUG) +- fprintf(stderr, "Hertz: %d\n", hz); +-#endif +- + (void) getkval(nlst[X_CCPU].n_value, (int *)(&ccpu), sizeof(ccpu), +@@ -333,2 +372,3 @@ + statics->memory_names = memorynames; ++ statics->order_names = ordernames; + +@@ -338,8 +378,7 @@ + +-char *format_header(uname_field) +- +-register char *uname_field; +- ++char * ++format_header(uname_field) ++ char *uname_field; + { +- register char *ptr; ++ char *ptr; + +@@ -360,8 +399,5 @@ + get_system_info(si) +- +-struct system_info *si; +- ++ struct system_info *si; + { + long total; +- load_avg avenrun[3]; + +@@ -370,31 +406,13 @@ + nlst[X_CP_TIME].n_name); +- (void) getkval(avenrun_offset, (int *)avenrun, sizeof(avenrun), +- nlst[X_AVENRUN].n_name); + + #ifdef LASTPID +- (void) getkval(lastpid_offset, (int *)(&lastpid), sizeof(lastpid), +- "!"); ++ (void) getkval(lastpid_offset, (int *)(&lastpid), sizeof(lastpid), "!"); + #endif + +- /* convert load averages to doubles */ +- { +- register int i; +- register double *infoloadp; +- load_avg *avenrunp; ++ if (getloadavg(si->load_avg, NUM_AVERAGES) < 0) { ++ int i; + +-#ifdef notyet +- struct loadavg sysload; +- int size; +- getkerninfo(KINFO_LOADAVG, &sysload, &size, 0); +-#endif +- +- infoloadp = si->load_avg; +- avenrunp = avenrun; +- for (i = 0; i < 3; i++) +- { +-#ifdef notyet +- *infoloadp++ = ((double) sysload.ldavg[i]) / sysload.fscale; +-#endif +- *infoloadp++ = loaddouble(*avenrunp++); +- } ++ warn("can't getloadavg"); ++ for (i = 0; i < NUM_AVERAGES; i++) ++ si->load_avg[i] = 0.0; + } +@@ -426,4 +444,4 @@ + memory_stats[7] = pagetok(total.t_free); +- } +-#else ++ ++#else /* !VM_REAL */ + struct vmmeter sum; +@@ -455,5 +473,5 @@ + /* swap_delay++; XXX Arne */ +-#else ++#else /* !USE_SWAP */ + memory_stats[4] = 0; +-#endif ++#endif /* !USE_SWAP */ + +@@ -461,4 +479,5 @@ + memory_stats[7] = -1; ++#endif /* !VM_REAL */ + } +-#endif ++ + /* set arrays and strings */ +@@ -480,14 +498,13 @@ + +-caddr_t get_process_info(si, sel, compare) +- +-struct system_info *si; +-struct process_select *sel; +-int (*compare)(); +- ++caddr_t ++get_process_info(si, sel, compare) ++ struct system_info *si; ++ struct process_select *sel; ++ int (*compare)(); + { +- register int i; +- register int total_procs; +- register int active_procs; +- register struct kinfo_proc **prefp; +- register struct kinfo_proc *pp; ++ int i; ++ int total_procs; ++ int active_procs; ++ struct kinfo_proc **prefp; ++ struct kinfo_proc *pp; + +@@ -564,11 +581,10 @@ + +-char *format_next_process(handle, get_userid) +- +-caddr_t handle; +-char *(*get_userid)(); +- ++char * ++format_next_process(handle, get_userid) ++ caddr_t handle; ++ char *(*get_userid)(); + { +- register struct kinfo_proc *pp; +- register long cputime; +- register double pct; ++ struct kinfo_proc *pp; ++ long cputime; ++ double pct; + struct handle *hp; +@@ -633,8 +649,7 @@ + +-static int check_nlist(nlst) +- +-register struct nlist *nlst; +- ++static int ++check_nlist(nlst) ++ struct nlist *nlst; + { +- register int i; ++ int i; + +@@ -672,9 +687,8 @@ + +-static int getkval(offset, ptr, size, refstr) +- +-unsigned long offset; +-int *ptr; +-int size; +-char *refstr; +- ++static int ++getkval(offset, ptr, size, refstr) ++ unsigned long offset; ++ int *ptr; ++ int size; ++ char *refstr; + { +@@ -696,12 +710,13 @@ + +-/* comparison routine for qsort */ ++/* comparison routines for qsort */ + + /* +- * proc_compare - comparison function for "qsort" +- * Compares the resource consumption of two processes using five +- * distinct keys. The keys (in descending order of importance) are: +- * percent cpu, cpu ticks, state, resident set size, total virtual +- * memory usage. The process states are ordered as follows (from least +- * to most important): WAIT, zombie, sleep, stop, start, run. The +- * array declaration below maps a process state index into a number ++ * There are currently four possible comparison routines. main selects ++ * one of these by indexing in to the array proc_compares. ++ * ++ * Possible keys are defined as macros below. Currently these keys are ++ * defined: percent cpu, cpu ticks, process state, resident set size, ++ * total virtual memory usage. The process states are ordered as follows ++ * (from least to most important): WAIT, zombie, sleep, stop, start, run. ++ * The array declaration below maps a process state index into a number + * that reflects this ordering. +@@ -709,24 +724,79 @@ + +-static unsigned char sorted_state[] = +-{ +- 0, /* not used */ +- 3, /* sleep */ +- 1, /* ABANDONED (WAIT) */ +- 6, /* run */ +- 5, /* start */ +- 2, /* zombie */ +- 4 /* stop */ ++/* ++ * First, the possible comparison keys. These are defined in such a way ++ * that they can be merely listed in the source code to define the actual ++ * desired ordering. ++ */ ++ ++#define ORDERKEY_PCTCPU \ ++ if (lresult = PP(p2, p_pctcpu) - PP(p1, p_pctcpu),\ ++ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) ++ ++#define ORDERKEY_CPTICKS \ ++ if (lresult = PP(p2, p_rtime).tv_sec - PP(p1, p_rtime).tv_sec,\ ++ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) ++ ++#define ORDERKEY_STATE \ ++ if ((result = sorted_state[(int)PP(p2, p_stat)] - \ ++ sorted_state[(int)PP(p1, p_stat)] ) == 0) ++ ++#define ORDERKEY_PRIO \ ++ if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0) ++ ++#define ORDERKEY_RSSIZE \ ++ if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) ++ ++#define ORDERKEY_MEM \ ++ if ((result = (PROCSIZE(p2) - PROCSIZE(p1))) == 0) ++ ++/* ++ * Now the array that maps process state to a weight. ++ * The order of the elements should match those in state_abbrev[] ++ */ ++ ++static int sorted_state[] = { ++ 0, /* (not used) ? */ ++ 4, /* "start" SIDL */ ++ 5, /* "run" SRUN */ ++ 2, /* "sleep" SSLEEP */ ++ 3, /* "stop" SSTOP */ ++ 1, /* "zomb" SZOMB */ + }; + ++/* compare_cpu - the comparison function for sorting by cpu percentage */ ++ + int +-proc_compare(pp1, pp2) ++compare_cpu(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; + +-struct proc **pp1; +-struct proc **pp2; ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ; + ++ return (result); ++} ++ ++/* compare_prio - the comparison function for sorting by process priority */ ++ ++int ++compare_prio(pp1, pp2) ++ struct proc **pp1, **pp2; + { +- register struct kinfo_proc *p1; +- register struct kinfo_proc *p2; +- register int result; +- register pctcpu lresult; ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; + +@@ -736,31 +806,115 @@ + +- /* compare percent cpu (pctcpu) */ +- if ((lresult = PP(p2, p_pctcpu) - PP(p1, p_pctcpu)) == 0) +- { +- /* use cpticks to break the tie */ +- if ((result = PP(p2, p_cpticks) - PP(p1, p_cpticks)) == 0) +- { +- /* use process state to break the tie */ +- if ((result = sorted_state[(unsigned char) PP(p2, p_stat)] - +- sorted_state[(unsigned char) PP(p1, p_stat)]) == 0) +- { +- /* use priority to break the tie */ +- if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0) +- { +- /* use resident set size (rssize) to break the tie */ +- if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) +- { +- /* use total memory to break the tie */ +- result = PROCSIZE(p2) - PROCSIZE(p1); +- } +- } +- } +- } +- } +- else +- { +- result = lresult < 0 ? -1 : 1; +- } ++ ORDERKEY_PRIO ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ; + +- return(result); ++ return (result); ++} ++ ++/* compare_res - the comparison function for sorting by resident set size */ ++ ++int ++compare_res(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ; ++ ++ return (result); ++} ++ ++/* compare_size - the comparison function for sorting by total memory usage */ ++ ++int ++compare_size(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_MEM ++ ORDERKEY_RSSIZE ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ; ++ ++ return (result); ++} ++ ++/* compare_state - the comparison function for sorting by process state */ ++ ++int ++compare_state(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_STATE ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_PRIO ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ; ++ ++ return (result); ++} ++ ++/* compare_time - the comparison function for sorting by total cpu time */ ++ ++int ++compare_time(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_CPTICKS ++ ORDERKEY_PCTCPU ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ORDERKEY_MEM ++ ORDERKEY_RSSIZE ++ ; ++ ++ return (result); + } +@@ -778,10 +932,9 @@ + +-int proc_owner(pid) +- +-int pid; +- ++int ++proc_owner(pid) ++ int pid; + { +- register int cnt; +- register struct kinfo_proc **prefp; +- register struct kinfo_proc *pp; ++ int cnt; ++ struct kinfo_proc **prefp; ++ struct kinfo_proc *pp; + +@@ -832,2 +985,3 @@ + ++ l = 0; + KGET(VM_NSWAP, nswap); +@@ -938,4 +1092,2 @@ + +- +-#endif +- ++#endif /* USE_SWAP */ +diff -1 -uBbNr machine/m_netbsd13.c machine/m_netbsd13.c +--- machine/m_netbsd13.c Thu Jan 1 01:00:00 1970 ++++ machine/m_netbsd13.c Sat Oct 4 03:25:02 1997 +@@ -0,0 +1,841 @@ ++/* ++ * top - a top users display for Unix ++ * ++ * SYNOPSIS: For a NetBSD-1.3 (or later) system ++ * ++ * DESCRIPTION: ++ * Originally written for BSD4.4 system by Christos Zoulas. ++ * Based on the FreeBSD 2.0 version by Steven Wallace and Wolfram Schneider. ++ * NetBSD-1.0 port by Arne Helme. Process ordering by Luke Mewburn. ++ * NetBSD-1.3 port by Luke Mewburn, based on code by Matthew Green. ++ * ++ * This is the machine-dependent module for NetBSD-1.3 and later ++ * Works for: ++ * NetBSD-1.3 ++ * ++ * LIBS: -lkvm ++ * ++ * CFLAGS: -DHAVE_GETOPT -DORDER ++ * ++ * AUTHORS: Christos Zoulas <christos@ee.cornell.edu> ++ * Steven Wallace <swallace@freebsd.org> ++ * Wolfram Schneider <wosch@cs.tu-berlin.de> ++ * Arne Helme <arne@acm.org> ++ * Luke Mewburn <lukem@netbsd.org> ++ * Matthew Green <mrg@eterna.com.au> ++ * ++ * ++ * $Id: patch-aa,v 1.2 1997/10/06 09:37:47 agc Exp $ ++ */ ++ ++#include <sys/types.h> ++#include <sys/signal.h> ++#include <sys/param.h> ++#include <sys/stat.h> ++#include <sys/errno.h> ++#include <sys/sysctl.h> ++#include <sys/dir.h> ++#include <sys/dkstat.h> ++#include <sys/file.h> ++#include <sys/time.h> ++ ++#include <vm/vm_swap.h> ++ ++#include "os.h" ++#include <err.h> ++#include <errno.h> ++#include <kvm.h> ++#include <math.h> ++#include <nlist.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <unistd.h> ++ ++static int check_nlist __P((struct nlist *)); ++static int getkval __P((unsigned long, int *, int, char *)); ++extern char* printable __P((char *)); ++ ++#include "top.h" ++#include "machine.h" ++#include "utils.h" ++ ++ ++/* get_process_info passes back a handle. This is what it looks like: */ ++ ++struct handle ++{ ++ struct kinfo_proc **next_proc; /* points to next valid proc pointer */ ++ int remaining; /* number of pointers remaining */ ++}; ++ ++/* declarations for load_avg */ ++#include "loadavg.h" ++ ++#define PP(pp, field) ((pp)->kp_proc . field) ++#define EP(pp, field) ((pp)->kp_eproc . field) ++#define VP(pp, field) ((pp)->kp_eproc.e_vm . field) ++ ++/* define what weighted cpu is. */ ++#define weighted_cpu(pct, pp) (PP((pp), p_swtime) == 0 ? 0.0 : \ ++ ((pct) / (1.0 - exp(PP((pp), p_swtime) * logcpu)))) ++ ++/* what we consider to be process size: */ ++#define PROCSIZE(pp) \ ++ (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize)) ++ ++/* definitions for indices in the nlist array */ ++ ++ ++static struct nlist nlst[] = { ++#define X_CCPU 0 ++ { "_ccpu" }, /* 0 */ ++#define X_CP_TIME 1 ++ { "_cp_time" }, /* 1 */ ++#define X_HZ 2 ++ { "_hz" }, /* 2 */ ++#define X_STATHZ 3 ++ { "_stathz" }, /* 3 */ ++#define X_AVENRUN 4 ++ { "_averunnable" }, /* 4 */ ++#define X_CNT 5 ++ { "_cnt" }, ++ ++ { 0 } ++}; ++ ++/* ++ * These definitions control the format of the per-process area ++ */ ++ ++static char header[] = ++ " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; ++/* 0123456 -- field to fill in starts at header+6 */ ++#define UNAME_START 6 ++ ++#define Proc_format \ ++ "%5d %-8.8s %3d %4d%7s %5s %-5s%7s %5.2f%% %5.2f%% %.14s" ++ ++ ++/* process state names for the "STATE" column of the display */ ++/* the extra nulls in the string "run" are for adding a slash and ++ the processor number when needed */ ++ ++char *state_abbrev[] = ++{ ++ "", "start", "run\0\0\0", "sleep", "stop", "zomb" ++}; ++ ++ ++static kvm_t *kd; ++ ++/* values that we stash away in _init and use in later routines */ ++ ++static double logcpu; ++ ++/* these are retrieved from the kernel in _init */ ++ ++static long hz; ++static load_avg ccpu; ++ ++/* these are offsets obtained via nlist and used in the get_ functions */ ++ ++static unsigned long cp_time_offset; ++static unsigned long avenrun_offset; ++static unsigned long cnt_offset; ++/* these are for calculating cpu state percentages */ ++ ++static long cp_time[CPUSTATES]; ++static long cp_old[CPUSTATES]; ++static long cp_diff[CPUSTATES]; ++ ++/* these are for detailing the process states */ ++ ++int process_states[7]; ++char *procstatenames[] = { ++ "", " starting, ", " running, ", " sleeping, ", " stopped, ", ++ " zombie, ", " ABANDONED, ", ++ NULL ++}; ++ ++/* these are for detailing the cpu states */ ++ ++int cpu_states[CPUSTATES]; ++char *cpustatenames[] = { ++ "user", "nice", "system", "interrupt", "idle", NULL ++}; ++ ++/* these are for detailing the memory statistics */ ++ ++int memory_stats[7]; ++char *memorynames[] = { ++ "K Act ", "K Inact ", "K Wired ", "K Free ", ++ "K Swap ", "K Swap free ", ++ NULL ++}; ++ ++ ++/* these are names given to allowed sorting orders -- first is default */ ++char *ordernames[] = { ++ "cpu", ++ "pri", ++ "res", ++ "size", ++ "state", ++ "time", ++ NULL ++}; ++ ++/* forward definitions for comparison functions */ ++int compare_cpu(); ++int compare_prio(); ++int compare_res(); ++int compare_size(); ++int compare_state(); ++int compare_time(); ++ ++int (*proc_compares[])() = { ++ compare_cpu, ++ compare_prio, ++ compare_res, ++ compare_size, ++ compare_state, ++ compare_time, ++ NULL ++}; ++ ++ ++/* these are for keeping track of the proc array */ ++ ++static int nproc; ++static int onproc = -1; ++static int pref_len; ++static struct kinfo_proc *pbase; ++static struct kinfo_proc **pref; ++ ++/* these are for getting the memory statistics */ ++ ++static int pageshift; /* log base 2 of the pagesize */ ++ ++/* define pagetok in terms of pageshift */ ++ ++#define pagetok(size) ((size) << pageshift) ++ ++/* useful externals */ ++long percentages(); ++ ++int ++machine_init(statics) ++ struct statics *statics; ++{ ++ int i = 0; ++ int pagesize; ++ ++ if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) ++ return -1; ++ ++ ++ /* get the list of symbols we want to access in the kernel */ ++ (void) kvm_nlist(kd, nlst); ++ if (nlst[0].n_type == 0) ++ { ++ fprintf(stderr, "top: nlist failed\n"); ++ return(-1); ++ } ++ ++ /* make sure they were all found */ ++ if (i > 0 && check_nlist(nlst) > 0) ++ { ++ return(-1); ++ } ++ ++ /* get the symbol values out of kmem */ ++ (void) getkval(nlst[X_STATHZ].n_value, (int *)(&hz), sizeof(hz), "!"); ++ if (!hz) { ++ (void) getkval(nlst[X_HZ].n_value, (int *)(&hz), sizeof(hz), ++ nlst[X_HZ].n_name); ++ } ++ ++ ++ (void) getkval(nlst[X_CCPU].n_value, (int *)(&ccpu), sizeof(ccpu), ++ nlst[X_CCPU].n_name); ++ ++ /* stash away certain offsets for later use */ ++ cp_time_offset = nlst[X_CP_TIME].n_value; ++ avenrun_offset = nlst[X_AVENRUN].n_value; ++ cnt_offset = nlst[X_CNT].n_value; ++ ++ /* this is used in calculating WCPU -- calculate it ahead of time */ ++ logcpu = log(loaddouble(ccpu)); ++ ++ pbase = NULL; ++ pref = NULL; ++ nproc = 0; ++ onproc = -1; ++ /* get the page size with "getpagesize" and calculate pageshift from it */ ++ pagesize = getpagesize(); ++ pageshift = 0; ++ while (pagesize > 1) ++ { ++ pageshift++; ++ pagesize >>= 1; ++ } ++ ++ /* we only need the amount of log(2)1024 for our conversion */ ++ pageshift -= LOG1024; ++ ++ /* fill in the statics information */ ++ statics->procstate_names = procstatenames; ++ statics->cpustate_names = cpustatenames; ++ statics->memory_names = memorynames; ++ statics->order_names = ordernames; ++ ++ /* all done! */ ++ return(0); ++} ++ ++char * ++format_header(uname_field) ++ char *uname_field; ++{ ++ char *ptr; ++ ++ ptr = header + UNAME_START; ++ while (*uname_field != '\0') ++ { ++ *ptr++ = *uname_field++; ++ } ++ ++ return(header); ++} ++ ++void ++get_system_info(si) ++ struct system_info *si; ++{ ++ long total; ++ struct vmmeter sum; ++ struct swapent *sep; ++ int totalsize, size, totalinuse, inuse, ncounted; ++ int rnswap, nswap; ++ ++ /* get the cp_time array */ ++ (void) getkval(cp_time_offset, (int *)cp_time, sizeof(cp_time), ++ nlst[X_CP_TIME].n_name); ++ ++ if (getloadavg(si->load_avg, NUM_AVERAGES) < 0) { ++ int i; ++ ++ warn("can't getloadavg"); ++ for (i = 0; i < NUM_AVERAGES; i++) ++ si->load_avg[i] = 0.0; ++ } ++ ++ /* convert cp_time counts to percentages */ ++ total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); ++ ++ /* sum memory statistics */ ++ ++ (void) getkval(cnt_offset, (int *)(&sum), sizeof(sum), "_cnt"); ++ ++ /* convert memory stats to Kbytes */ ++ memory_stats[0] = pagetok(sum.v_active_count); ++ memory_stats[1] = pagetok(sum.v_inactive_count); ++ memory_stats[2] = pagetok(sum.v_wire_count); ++ memory_stats[3] = pagetok(sum.v_free_count); ++ ++ memory_stats[4] = memory_stats[5] = 0; ++ ++ sep = NULL; ++ do { ++ nswap = swapctl(SWAP_NSWAP, 0, 0); ++ if (nswap < 1) ++ break; ++ sep = (struct swapent *)malloc(nswap * sizeof(*sep)); ++ if (sep == NULL) ++ break; ++ rnswap = swapctl(SWAP_STATS, (void *)sep, nswap); ++ if (nswap != rnswap) ++ break; ++ ++ totalsize = totalinuse = ncounted = 0; ++ for (; rnswap-- > 0; sep++) { ++ ncounted++; ++ size = sep->se_nblks; ++ inuse = sep->se_inuse; ++ totalsize += size; ++ totalinuse += inuse; ++ } ++ memory_stats[4] = dbtob(totalinuse) / 1024; ++ memory_stats[5] = dbtob(totalsize) / 1024 - memory_stats[4]; ++ } while (0); ++ if (sep) ++ free(sep); ++ ++ memory_stats[6] = -1; ++ ++ /* set arrays and strings */ ++ si->cpustates = cpu_states; ++ si->memory = memory_stats; ++ si->last_pid = -1; ++} ++ ++static struct handle handle; ++ ++caddr_t ++get_process_info(si, sel, compare) ++ struct system_info *si; ++ struct process_select *sel; ++ int (*compare)(); ++{ ++ int i; ++ int total_procs; ++ int active_procs; ++ struct kinfo_proc **prefp; ++ struct kinfo_proc *pp; ++ ++ /* these are copied out of sel for speed */ ++ int show_idle; ++ int show_system; ++ int show_uid; ++ int show_command; ++ ++ ++ pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc); ++ if (nproc > onproc) ++ pref = (struct kinfo_proc **) realloc(pref, sizeof(struct kinfo_proc *) ++ * (onproc = nproc)); ++ if (pref == NULL || pbase == NULL) { ++ (void) fprintf(stderr, "top: Out of memory.\n"); ++ quit(23); ++ } ++ /* get a pointer to the states summary array */ ++ si->procstates = process_states; ++ ++ /* set up flags which define what we are going to select */ ++ show_idle = sel->idle; ++ show_system = sel->system; ++ show_uid = sel->uid != -1; ++ show_command = sel->command != NULL; ++ ++ /* count up process states and get pointers to interesting procs */ ++ total_procs = 0; ++ active_procs = 0; ++ memset((char *)process_states, 0, sizeof(process_states)); ++ prefp = pref; ++ for (pp = pbase, i = 0; i < nproc; pp++, i++) ++ { ++ /* ++ * Place pointers to each valid proc structure in pref[]. ++ * Process slots that are actually in use have a non-zero ++ * status field. Processes with P_SYSTEM set are system ++ * processes---these get ignored unless show_sysprocs is set. ++ */ ++ if (PP(pp, p_stat) != 0 && ++ (show_system || ((PP(pp, p_flag) & P_SYSTEM) == 0))) ++ { ++ total_procs++; ++ process_states[(unsigned char) PP(pp, p_stat)]++; ++ if ((PP(pp, p_stat) != SZOMB) && ++ (show_idle || (PP(pp, p_pctcpu) != 0) || ++ (PP(pp, p_stat) == SRUN)) && ++ (!show_uid || EP(pp, e_pcred.p_ruid) == (uid_t)sel->uid)) ++ { ++ *prefp++ = pp; ++ active_procs++; ++ } ++ } ++ } ++ ++ /* if requested, sort the "interesting" processes */ ++ if (compare != NULL) ++ { ++ qsort((char *)pref, active_procs, sizeof(struct kinfo_proc *), compare); ++ } ++ ++ /* remember active and total counts */ ++ si->p_total = total_procs; ++ si->p_active = pref_len = active_procs; ++ ++ /* pass back a handle */ ++ handle.next_proc = pref; ++ handle.remaining = active_procs; ++ return((caddr_t)&handle); ++} ++ ++char fmt[128]; /* static area where result is built */ ++ ++char * ++format_next_process(handle, get_userid) ++ caddr_t handle; ++ char *(*get_userid)(); ++{ ++ struct kinfo_proc *pp; ++ long cputime; ++ double pct; ++ struct handle *hp; ++ ++ /* find and remember the next proc structure */ ++ hp = (struct handle *)handle; ++ pp = *(hp->next_proc++); ++ hp->remaining--; ++ ++ ++ /* get the process's user struct and set cputime */ ++ if ((PP(pp, p_flag) & P_INMEM) == 0) { ++ /* ++ * Print swapped processes as <pname> ++ */ ++ char *comm = PP(pp, p_comm); ++#define COMSIZ sizeof(PP(pp, p_comm)) ++ char buf[COMSIZ]; ++ (void) strncpy(buf, comm, COMSIZ); ++ comm[0] = '<'; ++ (void) strncpy(&comm[1], buf, COMSIZ - 2); ++ comm[COMSIZ - 2] = '\0'; ++ (void) strncat(comm, ">", COMSIZ - 1); ++ comm[COMSIZ - 1] = '\0'; ++ } ++ ++#if 0 ++ /* This does not produce the correct results */ ++ cputime = PP(pp, p_uticks) + PP(pp, p_sticks) + PP(pp, p_iticks); ++#endif ++ cputime = PP(pp, p_rtime).tv_sec; /* This does not count interrupts */ ++ ++ /* calculate the base for cpu percentages */ ++ pct = pctdouble(PP(pp, p_pctcpu)); ++ ++#define Proc_format \ ++ "%5d %-8.8s %3d %4d%7s %5s %-5s%7s %5.2f%% %5.2f%% %.14s" ++ ++ /* format this entry */ ++ sprintf(fmt, ++ Proc_format, ++ PP(pp, p_pid), ++ (*get_userid)(EP(pp, e_pcred.p_ruid)), ++ PP(pp, p_priority) - PZERO, ++ PP(pp, p_nice) - NZERO, ++ format_k(pagetok(PROCSIZE(pp))), ++ format_k(pagetok(VP(pp, vm_rssize))), ++ state_abbrev[(unsigned char) PP(pp, p_stat)], ++ format_time(cputime), ++ 10000.0 * weighted_cpu(pct, pp) / hz, ++ 10000.0 * pct / hz, ++ printable(PP(pp, p_comm))); ++ ++ /* return the result */ ++ return(fmt); ++} ++ ++ ++/* ++ * check_nlist(nlst) - checks the nlist to see if any symbols were not ++ * found. For every symbol that was not found, a one-line ++ * message is printed to stderr. The routine returns the ++ * number of symbols NOT found. ++ */ ++ ++static int ++check_nlist(nlst) ++ struct nlist *nlst; ++{ ++ int i; ++ ++ /* check to see if we got ALL the symbols we requested */ ++ /* this will write one line to stderr for every symbol not found */ ++ ++ i = 0; ++ while (nlst->n_name != NULL) ++ { ++ if (nlst->n_type == 0) ++ { ++ /* this one wasn't found */ ++ (void) fprintf(stderr, "kernel: no symbol named `%s'\n", ++ nlst->n_name); ++ i = 1; ++ } ++ nlst++; ++ } ++ ++ return(i); ++} ++ ++ ++/* ++ * getkval(offset, ptr, size, refstr) - get a value out of the kernel. ++ * "offset" is the byte offset into the kernel for the desired value, ++ * "ptr" points to a buffer into which the value is retrieved, ++ * "size" is the size of the buffer (and the object to retrieve), ++ * "refstr" is a reference string used when printing error meessages, ++ * if "refstr" starts with a '!', then a failure on read will not ++ * be fatal (this may seem like a silly way to do things, but I ++ * really didn't want the overhead of another argument). ++ * ++ */ ++ ++static int ++getkval(offset, ptr, size, refstr) ++ unsigned long offset; ++ int *ptr; ++ int size; ++ char *refstr; ++{ ++ if (kvm_read(kd, offset, (char *) ptr, size) != size) ++ { ++ if (*refstr == '!') ++ { ++ return(0); ++ } ++ else ++ { ++ fprintf(stderr, "top: kvm_read for %s: %s\n", ++ refstr, strerror(errno)); ++ quit(23); ++ } ++ } ++ return(1); ++} ++ ++/* comparison routines for qsort */ ++ ++/* ++ * There are currently four possible comparison routines. main selects ++ * one of these by indexing in to the array proc_compares. ++ * ++ * Possible keys are defined as macros below. Currently these keys are ++ * defined: percent cpu, cpu ticks, process state, resident set size, ++ * total virtual memory usage. The process states are ordered as follows ++ * (from least to most important): WAIT, zombie, sleep, stop, start, run. ++ * The array declaration below maps a process state index into a number ++ * that reflects this ordering. ++ */ ++ ++/* ++ * First, the possible comparison keys. These are defined in such a way ++ * that they can be merely listed in the source code to define the actual ++ * desired ordering. ++ */ ++ ++#define ORDERKEY_PCTCPU \ ++ if (lresult = PP(p2, p_pctcpu) - PP(p1, p_pctcpu),\ ++ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) ++ ++#define ORDERKEY_CPTICKS \ ++ if (lresult = PP(p2, p_rtime).tv_sec - PP(p1, p_rtime).tv_sec,\ ++ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) ++ ++#define ORDERKEY_STATE \ ++ if ((result = sorted_state[(int)PP(p2, p_stat)] - \ ++ sorted_state[(int)PP(p1, p_stat)] ) == 0) ++ ++#define ORDERKEY_PRIO \ ++ if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0) ++ ++#define ORDERKEY_RSSIZE \ ++ if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) ++ ++#define ORDERKEY_MEM \ ++ if ((result = (PROCSIZE(p2) - PROCSIZE(p1))) == 0) ++ ++/* ++ * Now the array that maps process state to a weight. ++ * The order of the elements should match those in state_abbrev[] ++ */ ++ ++static int sorted_state[] = { ++ 0, /* (not used) ? */ ++ 4, /* "start" SIDL */ ++ 5, /* "run" SRUN */ ++ 2, /* "sleep" SSLEEP */ ++ 3, /* "stop" SSTOP */ ++ 1, /* "zomb" SZOMB */ ++}; ++ ++/* compare_cpu - the comparison function for sorting by cpu percentage */ ++ ++int ++compare_cpu(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ; ++ ++ return (result); ++} ++ ++/* compare_prio - the comparison function for sorting by process priority */ ++ ++int ++compare_prio(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_PRIO ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ; ++ ++ return (result); ++} ++ ++/* compare_res - the comparison function for sorting by resident set size */ ++ ++int ++compare_res(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ; ++ ++ return (result); ++} ++ ++/* compare_size - the comparison function for sorting by total memory usage */ ++ ++int ++compare_size(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_MEM ++ ORDERKEY_RSSIZE ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ; ++ ++ return (result); ++} ++ ++/* compare_state - the comparison function for sorting by process state */ ++ ++int ++compare_state(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_STATE ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_PRIO ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ; ++ ++ return (result); ++} ++ ++/* compare_time - the comparison function for sorting by total cpu time */ ++ ++int ++compare_time(pp1, pp2) ++ struct proc **pp1, **pp2; ++{ ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_CPTICKS ++ ORDERKEY_PCTCPU ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ORDERKEY_MEM ++ ORDERKEY_RSSIZE ++ ; ++ ++ return (result); ++} ++ ++ ++/* ++ * proc_owner(pid) - returns the uid that owns process "pid", or -1 if ++ * the process does not exist. ++ * It is EXTREMLY IMPORTANT that this function work correctly. ++ * If top runs setuid root (as in SVR4), then this function ++ * is the only thing that stands in the way of a serious ++ * security problem. It validates requests for the "kill" ++ * and "renice" commands. ++ */ ++ ++int ++proc_owner(pid) ++ int pid; ++{ ++ int cnt; ++ struct kinfo_proc **prefp; ++ struct kinfo_proc *pp; ++ ++ prefp = pref; ++ cnt = pref_len; ++ while (--cnt >= 0) ++ { ++ pp = *prefp++; ++ if (PP(pp, p_pid) == (pid_t)pid) ++ { ++ return((int)EP(pp, e_pcred.p_ruid)); ++ } ++ } ++ return(-1); ++} +diff -1 -uBbNr top.c top.c +--- top.c Thu Sep 12 21:50:53 1996 ++++ top.c Sat Oct 4 03:25:02 1997 +@@ -716,3 +716,3 @@ + clear(); +- show_help(); ++ show_help(&statics); + standout("Hit any key to continue: "); +diff -1 -uBbNr utils.c utils.c +--- utils.c Tue Sep 10 22:15:14 1996 ++++ utils.c Sat Oct 4 03:25:02 1997 +@@ -18,2 +18,4 @@ + ++#include <errno.h> ++ + int atoiwi(str) |