⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m_svr5.c

📁 unix系统下top命令的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  * top - a top users display for Unix * * SYNOPSIS:  For Intel based System V Release 5 (Unixware7) *  * DESCRIPTION: * System V release 5 for i[3456]86 * Works for: * i586-sco-sysv5uw7  i386 SCO UNIX_SVR5 (UnixWare 7) *  * LIBS:  -lelf -lmas *  * CFLAGS: -DHAVE_GETOPT -DORDER *  * AUTHORS: Mike Hopkirk       <hops@sco.com> *          David Cutter       <dpc@grail.com> *          Andrew Herbert     <andrew@werple.apana.org.au> *          Robert Boucher     <boucher@sofkin.ca> *//* build config *  SHOW_NICE - process nice fields don't seem to be being updated so changed *     default to display # of threads in use instead. *     define this to display nice fields (values always 0) * #define SHOW_NICE 1  */#define _KMEMUSER#define prpsinfo psinfo#include <sys/procfs.h>#define pr_state pr_lwp.pr_state#define pr_nice pr_lwp.pr_nice#define pr_pri pr_lwp.pr_pri#define pr_onpro pr_lwp.pr_onpro#define ZOMBIE(p)	((p)->pr_nlwp == 0)#define SIZE_K(p)	pagetok((p)->pr_size)#define RSS_K(p)	pagetok((p)->pr_rssize)#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <dirent.h>#include <nlist.h>#include <string.h>#include <sys/types.h>#include <sys/param.h>#include <sys/proc.h>#include <sys/sysmacros.h>#include <vm/anon.h> #include <sys/priocntl.h>#include <sys/tspriocntl.h> #include <sys/var.h>#include "top.h"#include "machine.h"#include "utils.h"#define UNIX "/stand/unix"#define KMEM "/dev/kmem"#define PROCFS "/proc"#define CPUSTATES	5#ifndef PRIO_MAX#define PRIO_MAX	20#endif#ifndef PRIO_MIN#define PRIO_MIN	-20#endif#ifndef FSCALE#define FSHIFT  8		/* bits to right of fixed binary point */#define FSCALE  (1<<FSHIFT)#endif#define loaddouble(x) ((double)x/FSCALE)#define pagetok(size) ((size) * pagesz) >> LOG1024/* definitions for the index in the nlist array */#define X_AVENRUN	0#define X_V		1#define X_MPID		2static struct nlist nlst[] ={   {"avenrun"},		        /* 0 */   {"v"},			/* 1 */   {"nextpid"},                 /* 2 */  {NULL}};static unsigned long avenrun_offset;static unsigned long mpid_offset;static unsigned int pagesz;static void reallocproc(int n);static int maxprocs;/* get_process_info passes back a handle.  This is what it looks like: */struct handle{    struct prpsinfo **next_proc;/* points to next valid proc pointer */    int remaining;		/* number of pointers remaining */};/* *  These definitions control the format of the per-process area */static char header[] =#ifdef SHOW_NICE"  PID X        PRI NICE  SIZE   RES STATE   TIME      CPU  COMMAND";#else"  PID X        PRI  THR  SIZE   RES STATE   TIME      CPU  COMMAND";#endif/* 0123456   -- field to fill in starts at header+6 */#define UNAME_START 6#define Proc_format \	"%5d %-8.8s %3d %4d %5s %5s %-5s %6s %8.4f%% %.16s"char *state_abbrev[] ={"oncpu", "run", "sleep",  "stop", "idle", "zombie"};#define sZOMB 5int process_states[8];char *procstatenames[] ={  " on cpu, ", " running, ", " sleeping, ", " stopped, ",  " idling ",  " zombie, ",   NULL};int cpu_states[CPUSTATES];char *cpustatenames[] ={"idle", "user", "kernel", "wait", NULL};/* these are for detailing the memory statistics */int memory_stats[5];char *memorynames[] ={"K phys, ", "K used, ", "K free, ", "K swapUsed, ", "K swapFree", NULL};/* these are names given to allowed sorting orders -- first is default */char *ordernames[] = {"state", "cpu", "size", "res", "time", "pid", "uid", "rpid", "ruid", NULL};/* forward definitions for comparison functions */int proc_compare();int compare_cpu();int compare_size();int compare_res();int compare_time();int compare_pid();int compare_uid();int compare_rpid();int compare_ruid();int (*proc_compares[])() = {    proc_compare,    compare_cpu,    compare_size,    compare_res,    compare_time,    compare_pid,    compare_uid,    compare_rpid,    compare_ruid,    NULL };static int kmem = -1;static int nproc;static int bytes;static struct prpsinfo *pbase;static struct prpsinfo **pref;static DIR *procdir;/* useful externals */extern int errno;extern char *sys_errlist[];extern char *myname;extern long percentages ();extern int check_nlist ();extern int getkval ();extern void perror ();extern void getptable ();extern void quit ();extern int nlist ();/* fwd dcls */static int kmet_init(void );static int get_cpustates(int *new);intmachine_init (struct statics *statics)  {    static struct var v;    int i;    /* fill in the statics information */    statics->procstate_names = procstatenames;    statics->cpustate_names = cpustatenames;    statics->memory_names = memorynames;    statics->order_names = ordernames;    /* get the list of symbols we want to access in the kernel */    if (nlist (UNIX, nlst))      {	(void) fprintf (stderr, "Unable to nlist %s\n", UNIX);	return (-1);      }    /* make sure they were all found */    if (check_nlist (nlst) > 0)      return (-1);    /* open kernel memory */    if ((kmem = open (KMEM, O_RDONLY)) == -1)      {	perror (KMEM);	return (-1);      }    v.v_proc=200;   /* arbitrary default */    /* get the symbol values out of kmem */    /* NPROC Tuning parameter for max number of processes */    (void) getkval (nlst[X_V].n_value, &v, sizeof (struct var), nlst[X_V].n_name);    nproc = v.v_proc;    maxprocs = nproc;    /* stash away certain offsets for later use */    mpid_offset = nlst[X_MPID].n_value;    avenrun_offset = nlst[X_AVENRUN].n_value;    /* allocate space for proc structure array and array of pointers */    bytes = nproc * sizeof (struct prpsinfo);    pbase = (struct prpsinfo *) malloc (bytes);    pref = (struct prpsinfo **) malloc (nproc * sizeof (struct prpsinfo *));    pagesz = sysconf(_SC_PAGESIZE);    /* Just in case ... */    if (pbase == (struct prpsinfo *) NULL || pref == (struct prpsinfo **) NULL)      {	(void) fprintf (stderr, "%s: can't allocate sufficient memory\n", myname);	return (-1);      }    if (!(procdir = opendir (PROCFS)))      {	(void) fprintf (stderr, "Unable to open %s\n", PROCFS);	return (-1);      }    if (chdir (PROCFS))    {				/* handy for later on when we're reading it */	(void) fprintf (stderr, "Unable to chdir to %s\n", PROCFS);	return (-1);    }    kmet_init();    /* all done! */    return (0);  }char *format_header (char *uname_field){  register char *ptr;  ptr = header + UNAME_START;  while (*uname_field != '\0')    *ptr++ = *uname_field++;  return (header);}voidget_system_info (struct system_info *si){  long avenrun[3];  long mem;  static time_t cp_old[CPUSTATES];  static time_t cp_diff[CPUSTATES];	/* for cpu state percentages */  register int i;  static long swap_total;  static long swap_free;  int new_states[CPUSTATES];  get_cpustates(new_states);  /* convert cp_time counts to percentages */  (void) percentages (CPUSTATES, cpu_states, new_states, cp_old, cp_diff);  si->last_pid = -1;  /* get mpid -- process id of last process   * svr5 is nextpid - next pid to be assigned (already incremented)   */   (void) getkval (mpid_offset, &(si->last_pid), sizeof (si->last_pid),   		  "nextpid");   (si->last_pid)--;    /* so we shld decrement for display */  /* get load average array */  (void) getkval (avenrun_offset, (int *) avenrun, sizeof (avenrun), "avenrun");  /* convert load averages to doubles */  for (i = 0; i < 3; i++)    si->load_avg[i] = loaddouble(avenrun[i]);  mem = sysconf(_SC_TOTAL_MEMORY);      /* physical mem */  memory_stats[0] = pagetok (mem);  mem = kmet_get_freemem();             /* free mem */  memory_stats[2] = pagetok (mem);  /* mem = sysconf(_SC_GENERAL_MEMORY);    */  memory_stats[1] = memory_stats[0] - memory_stats[2]; /* active */  get_swapinfo(&swap_total, &swap_free);  memory_stats[3] = pagetok(swap_total - swap_free);  memory_stats[4] = pagetok(swap_free);   /* set arrays and strings */  si->cpustates = cpu_states;  si->memory = memory_stats;}static struct handle handle;caddr_tget_process_info (		   struct system_info *si,		   struct process_select *sel,		   int (*compare) ()){  register int i;  register int total_procs;  register int active_procs;  register struct prpsinfo **prefp;  register struct prpsinfo *pp;  /* these are copied out of sel for speed */  int show_idle;  int show_system;  int show_uid;  /* Get current number of processes */  /* read all the proc structures */  getptable (pbase);  /* 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;  nproc = kmet_get_nproc();  /* count up process states and get pointers to interesting procs */  total_procs = 0;  active_procs = 0;  (void) memset (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 PR_ISSYS set are system	 *  processes---these get ignored unless show_sysprocs is set.	 */      if ((pp->pr_state >= SONPROC && pp->pr_state <= SIDL)  &&	  (show_system || ((pp->pr_flag & PR_ISSYS) == 0)))      {	  total_procs++;	  process_states[pp->pr_state]++;	  if ((!ZOMBIE(pp)) &&	      (show_idle || (pp->pr_state == SRUN) || (pp->pr_state == SONPROC)) &&	      (!show_uid || pp->pr_uid == (uid_t) sel->uid))	  {	      *prefp++ = pp;	      active_procs++;	  }	  if (ZOMBIE(pp))    	    process_states[sZOMB]++;    /* invented */      }  }  /* if requested, sort the "interesting" processes */  if (compare != NULL)      qsort ((char *) pref, active_procs, sizeof (struct prpsinfo *), compare);  /* remember active and total counts */  si->p_total = total_procs;  si->P_ACTIVE = active_procs;  /* pass back a handle */  handle.next_proc = pref;  handle.remaining = active_procs;  return ((caddr_t) & handle);}/* * cpu percentage calculation is as fm ps.c * seems to be ratio of (sys+user time used)/(elapsed time) * i.e percent of cpu utilised when on cpu */static double percent_cpu( struct prpsinfo *pp){    static time_t tim = 0L;       time_t starttime;    time_t ctime;    time_t etime;    /* if (tim == 0L) */        tim = time((time_t *) 0);    starttime = pp->pr_start.tv_sec;    if (pp->pr_start.tv_nsec > 500000000)            starttime++;    etime = (tim - starttime);    ctime = pp->pr_time.tv_sec;    if (pp->pr_time.tv_nsec > 500000000)    ctime++;    if (etime)     {        /* return  (float)(ctime * 100) / (unsigned)etime; */        /* this was ocasionally giving vals >100 for some         * unknown reason so the below normalises it         */                double pct;        pct = (float)(ctime * 100) / (unsigned)etime;        return (pct < 100.0) ? pct : 100.00;    }    return 0.00;}char fmt[MAX_COLS];			/* static area where result is built */char *format_next_process (		      caddr_t handle,		      char *(*get_userid) ()){  register struct prpsinfo *pp;  struct handle *hp;  register long cputime;  register double pctcpu;  /* find and remember the next proc structure */  hp = (struct handle *) handle;  pp = *(hp->next_proc++);  hp->remaining--;  /* get the cpu usage and calculate the cpu percentages */  cputime = pp->pr_time.tv_sec;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -