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

📄 m_dgux.c

📁 查看系统硬件和内存资源使用情况;以及各个进程的使用情况
💻 C
字号:
/* * top - a top users display for Unix * * SYNOPSIS:  for DG AViiON with DG/UX 5.4+ * * DESCRIPTION: * A top module for DG/UX 5.4 systems. * Uses DG/UX system calls to get info from the kernel. * (NB. top DOES NOT need to be installed setuid root under DG/UX 5.4.2) * * AUTHOR:  Mike Williams <mike@inform.co.nz> *//* * NOTE: This module will only work with top versions 3.1 and later! */#include <stdlib.h> #include <unistd.h>#include <stdio.h>#include <sys/dg_sys_info.h>#include <sys/dg_process_info.h>#include <sys/systeminfo.h> #include <sys/sysmacros.h> #include "top.h"#include "machine.h"#include "utils.h"/*--- process formatting --------------------------------------------------*/static char header[] =  "  PID X         PRI NICE C    SIZE STATE    TIME    CPU COMMAND";/* ddddd ssssssss dddd ddd dd ddddddK ssssssdddd:dd dd.dd% sssssssssssssssss... * 0123456   -- field to fill in starts at header+6 */#define UNAME_START 6#define Proc_format \     "%5d %-8.8s %4d %3d %2d %7s %-6s %6s %5.2f%% %.20s"/*--- process states ------------------------------------------------------*/static char* procStateNames[] = {    "", " sleeping, ", " waiting, ", " running, ", " starting, ",    " zombie, ", " stopped, ",    NULL};static char* procStateAbbrevs[] = {    "", "sleep", "wait", "run", "start", "zombie", "stop",    NULL};#define N_PROCESS_STATES \(sizeof (procStateNames) / sizeof (procStateNames[0]) - 1)static int processStats[N_PROCESS_STATES];/*--- cpu states ----------------------------------------------------------*/enum {    CPU_user,    CPU_system,    CPU_idle,    CPU_io_wait,};static char* cpuStateNames[] = {    "user", "system", "idle", "io_wait",    NULL};#define N_CPU_STATES \(sizeof (cpuStateNames) / sizeof (cpuStateNames[0]) - 1)static int cpuStats[N_CPU_STATES];/*--- memory statistics ---------------------------------------------------*/enum {    MEM_available,    MEM_used,    MEM_free,    MEM_freeswap,};static char* memoryNames[] = {    "K physical, ", "K in use, ", "K free, ", "K free swap, ", NULL};#define N_MEMORY_STATS \(sizeof (memoryNames) / sizeof (memoryNames[0]) - 1)static int memoryStats[N_MEMORY_STATS];/*--- conversion macros ---------------------------------------------------*//* Convert clicks (kernel pages) to kbytes ... */#define pagetok(size) ctob(size) >> LOG1024/* Convert timeval's to double */#define tvtod(tval) (1000000.0 * (tval).tv_sec + 1.0 * (tval).tv_usec)/* Scale timeval's onto longs */#define scaledtv(tval) (tvtod (tval) / 4096) /*--- process table -------------------------------------------------------*/typedef struct _ProcInfo {    struct dg_process_info    p_info;    double 		      cpu_time;    double 		      fraction_cpu;} ProcInfo;static ProcInfo* 	      processInfo;static ProcInfo** 	      activeProcessInfo;int 			      activeIndex;typedef struct _ProcTime {    pid_t 		      pid;    double 		      cpu_time;} ProcTime;static ProcTime* 	      oldProcessTimes;static int 		      n_oldProcessTimes;static double 		      lastTime;static double 		      thisTime;static double 		      timeSlice;/*=========================================================================*//*=== top "Callback" routines =============================================*/static int IntCmp (i1, i2)  int* 			i1;  int* 			i2;{    return (*i2 - *i1);}/*=== Data collection =====================================================*/int machine_init (statics)  /*~~~~~~~~~~~~   */  struct statics *statics;{    struct dg_sys_info_pm_info pm_info;    int 		      table_size;    /* fill in the statics information */    statics->procstate_names = procStateNames;    statics->cpustate_names = cpuStateNames;    statics->memory_names = memoryNames;    dg_sys_info ((long *)&pm_info,		 DG_SYS_INFO_PM_INFO_TYPE,		 DG_SYS_INFO_PM_VERSION_0);    table_size = pm_info.process_table_size + 1;    processInfo = (ProcInfo *) 	malloc (sizeof (processInfo[0]) * table_size);    activeProcessInfo = (ProcInfo **) 	malloc (sizeof (activeProcessInfo[0]) * table_size);    oldProcessTimes = (ProcTime *) 	malloc (sizeof (oldProcessTimes[0]) * table_size);    lastTime = 0;    return(0);}int get_system_info (si)  /*~~~~~~~~~~~~~~~   */  struct system_info *si;{    struct dg_sys_info_vm_info    vm_info;    struct dg_sys_info_pm_info    pm_info;    struct dg_sys_info_load_info  load_info;    static long cpu_time [N_CPU_STATES];    static long cpu_old [N_CPU_STATES];    static long cpu_diff [N_CPU_STATES];    /* memory info */        dg_sys_info ((long *)&vm_info,		 DG_SYS_INFO_VM_INFO_TYPE,		 DG_SYS_INFO_VM_VERSION_0);    memoryStats[MEM_available] = sysconf (_SC_AVAILMEM);    memoryStats[MEM_free]      = pagetok (vm_info.freemem);    memoryStats[MEM_used]      = memoryStats[0] - memoryStats[2];    memoryStats[MEM_freeswap]  = pagetok (vm_info.freeswap);    si->memory 		       = memoryStats;    /* process info */        dg_sys_info ((long *)&pm_info,		 DG_SYS_INFO_PM_INFO_TYPE,		 DG_SYS_INFO_PM_VERSION_0);    si->last_pid 	      = 0;    si->p_total 	      = pm_info.process_count;    si->p_active 	      = pm_info.bound_runnable_process_count;    cpu_time[CPU_user]        = scaledtv (pm_info.user_time);    cpu_time[CPU_system]      = scaledtv (pm_info.system_time);    cpu_time[CPU_idle] 	      = scaledtv (pm_info.idle_time);    cpu_time[CPU_io_wait]     = scaledtv (pm_info.io_wait_time);    percentages (N_CPU_STATES, cpuStats, cpu_time, cpu_old, cpu_diff);    si->cpustates 	      = cpuStats;    /* calculate timescale */    thisTime = tvtod (pm_info.current_time);    timeSlice = thisTime - lastTime;    lastTime = thisTime;        /* load info */        dg_sys_info ((long *)&load_info,		 DG_SYS_INFO_LOAD_INFO_TYPE,		 DG_SYS_INFO_LOAD_VERSION_0);    si->load_avg[0] 	= load_info.one_minute;    si->load_avg[1] 	= load_info.five_minute;    si->load_avg[2] 	= load_info.fifteen_minute;    return 1;}caddr_t get_process_info (si, sel, compare)  /*    ~~~~~~~~~~~~~~~~    */  struct system_info* 	si;  struct process_select* sel;  int 			(*compare)();{    long 		key = DG_PROCESS_INFO_INITIAL_KEY; 			    int 		n_total = 0;    int 		n_active = 0;    ProcInfo* 		pp;    int 		i;    bzero((char *)processStats, sizeof(processStats));    while (dg_process_info (DG_PROCESS_INFO_SELECTOR_ALL_PROCESSES, 0,			    DG_PROCESS_INFO_CMD_NAME_ONLY,			    &key,			    &(processInfo[n_total].p_info),			    DG_PROCESS_INFO_CURRENT_VERSION) == 1) {	ProcInfo*       pp = &(processInfo[n_total++]);	int 		pid = pp->p_info.process_id;	ProcTime* 	old_time;	/* Increment count for this process state */	++processStats[pp->p_info.state];	/* Calculate % CPU usage */	pp->cpu_time = (tvtod (pp->p_info.system_time) + 			tvtod (pp->p_info.user_time));	old_time = (ProcTime *) 	    bsearch (&pid, oldProcessTimes, 		     n_oldProcessTimes, sizeof (ProcTime),		     IntCmp);	pp->fraction_cpu = (old_time 			    ? ((pp->cpu_time - old_time->cpu_time)			       / timeSlice) 			    : 0.0);	/* Skip if process not classed as "active" */	if ((pp->p_info.state == DG_PROCESS_INFO_STATUS_TERMINATED) ||	    (!sel->idle 	     && (pp->p_info.state != DG_PROCESS_INFO_STATUS_RUNNING)	     && (pp->p_info.state != DG_PROCESS_INFO_STATUS_WAITING)) ||	    (sel->uid != -1 && pp->p_info.user_id != (uid_t)sel->uid) ||	    (!sel->system && (pp->p_info.user_id == 0 &&			     pp->p_info.parent_process_id == 1)) ||	    (sel->command && strcmp (pp->p_info.cmd, sel->command) != 0))	    continue;	activeProcessInfo[n_active++] = pp;	    }    activeProcessInfo[n_active] = NULL;    si->p_total 	= n_total;    si->p_active 	= n_active;    si->procstates 	= processStats;    /* If requested, sort the "interesting" processes */    if (compare != NULL) qsort((void *)activeProcessInfo, 			       n_active, 			       sizeof (ProcInfo *), 			       compare);    /* Record scaled CPU totals, for calculating %CPU */    n_oldProcessTimes = n_total;    for (i = 0; i < n_oldProcessTimes; i++) {	oldProcessTimes[i].pid = processInfo[i].p_info.process_id;	oldProcessTimes[i].cpu_time = processInfo[i].cpu_time;    }    qsort (oldProcessTimes, n_oldProcessTimes, sizeof (ProcTime), IntCmp);    /* pass back a handle */    activeIndex = 0;    return ((caddr_t) &activeIndex);}/*=== Process comparison routine ==========================================*//* * Sort keys are (in descending order of importance): *     - percent cpu *     - cpu ticks *     - state *     - resident set size *      * The process states are ordered as follows: *     - zombie *     - wait *     - sleep *     - stop *     - start *     - run */static unsigned char sortedState[] ={    0,	                                /* not used */    3,	                                /* sleep */    1,	                                /* wait	*/    6,	                                /* run */    5,	                                /* start */    2,	                                /* zombie */    4,	                                /* stop */};int proc_compare(pp1, pp2)  /*~~~~~~~~~~~~   */  ProcInfo** 		pp1;  ProcInfo** 		pp2;{    register ProcInfo* 	p1;    register ProcInfo* 	p2;    register int 	result;    register float 	lresult;    register long 	p1_cpu;    register long 	p2_cpu;    /* remove one level of indirection */    p1 = *pp1;    p2 = *pp2;    /* calculate cpu totals */    p1_cpu = p1->p_info.system_time.tv_sec + p1->p_info.user_time.tv_sec;    p2_cpu = p2->p_info.system_time.tv_sec + p2->p_info.user_time.tv_sec;    /* Compare %CPU usage */    if ((lresult = (p2->fraction_cpu - p1->fraction_cpu)) != 0)	return lresult < 0 ? -1 : 1;    /* Compare other fields until one differs */    ((result = (p2->p_info.cpu_usage - p1->p_info.cpu_usage)) ||     (result = (sortedState [p2->p_info.state] - 		sortedState [p1->p_info.state])) ||     (result = (p2->p_info.priority - p1->p_info.priority)) ||     (result = (p2->p_info.resident_process_size - 		p1->p_info.resident_process_size)) ||     (result = (p1->p_info.process_id - p2->p_info.process_id)));    return result;}/*=== Process owner validation ============================================*//* * 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;{    register int      i;    ProcInfo* 	      pp;    for (i = 0; (pp = activeProcessInfo [i]); i++) {	if (pp->p_info.process_id == pid) 	    return (int)pp->p_info.user_id;    }    return(-1);}/*=== Output formatting ===================================================*/char* format_header (uname_field)  /*  ~~~~~~~~~~~~~   */  register char* 	uname_field;{    register char* 	ptr;    ptr = header + UNAME_START;    while (*uname_field != '\0')    {	*ptr++ = *uname_field++;    }    return(header);}char* format_next_process (index_ptr, get_userid)  /*  ~~~~~~~~~~~~~~~~~~~   */  int* 			index_ptr;  char* 		(*get_userid)();{    static char 	fmt[MAX_COLS];    int 		proc_index;    ProcInfo* 		pp;    long 		proc_cpu;    proc_index = (*index_ptr)++;    pp = activeProcessInfo [proc_index];    proc_cpu = pp->p_info.system_time.tv_sec + pp->p_info.user_time.tv_sec;    /* format this entry */    sprintf (fmt,	     Proc_format,	     pp->p_info.process_id,	     (*get_userid) (pp->p_info.user_id),	     pp->p_info.priority,	     pp->p_info.nice_value,	     pp->p_info.cpu_usage,	     format_k(pagetok (pp->p_info.resident_process_size)),	     procStateAbbrevs[pp->p_info.state],	     format_time(proc_cpu),	     100.0 * pp->fraction_cpu,	     pp->p_info.cmd);        return(fmt);}/*=== END of m_dgux.c =====================================================*/

⌨️ 快捷键说明

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