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

📄 m_svr42mp.c

📁 unix系统下top命令的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * top - a top users display for Unix * * SYNOPSIS: For Intel based SysVr4.2MP  (UnixWare 2) * * DESCRIPTION: * System V release 4.2MP for i?86 (UnixWare2) * * LIBS:  	-lelf * * CFLAGS:	-DHAVE_GETOPT -DORDER * AUTHOR:  	Daniel Harris	<daniel@greencape.com.au> *              Mike Hopkirk    <hops@sco.com> * * BASED ON: 	Most of the work in this module is attributable to the *		authors of m_svr42.c and m_sunos5.c.  (Thanks!) * *		Originally written by Daniel Green as an implementation for *		Unixware7 (sysVr5) *		Incomplete for that but applied by Mike Hopkirk to svr4.2MP *		for which there was not a working port available. *               * NOTES: * *	You shouldn't make this setuid anything.  It doesn't flip between *	saved uids. * *	This module looks nothing like other top modules.  In my deluded *	world, function follows form.  Code needs to look good in order *	to work.  :-)  Apologies to anyone offended by by reformatting. * *	The number of processes is calculated by the number of entries in the *	/proc filesystem. * *	sysinfo structure should be available from the kernel in preference *	to following met_localdata_ptrs_p but if so its naming is obscure. * *	Ordering of tasks other than by the default isn't implemented yet. * *	Nice value is always displayed as 0 due bug in UW2 *  * * DATE		CHANGE * 03/09/1998	Couple of comment changes.  Prepare for release. * 13/06/1998	Cleaned out debugging code, prepared for limited release. * 09/07/1999	Modified for UnixWare 2 (2.1.2) build - hops *              Added use of system getopt and additional sort orders * *//* ************************************************************************** *//* build config *  SHOW_NICE - process nice fields always accessed as 0 so changed *     default to display # of threads in use instead. *     define this to display nice fields (values always 0) * #define SHOW_NICE 1  *//* * Defines */#define	_KMEMUSER	/* Needed to access appropriate system include file   */			/* structures.					      */#define UNIX	"/unix"	/* Miscellaneous paths.				      */#define PROCFS	"/proc"#define PATH_KMEM "/dev/kmem"/* * Maximum and minumum priorities. */#ifndef PRIO_MAX#define PRIO_MAX	20#endif#ifndef PRIO_MIN#define PRIO_MIN	-20#endif/* * Scaling factor used to adjust kernel load average numbers. * Unixware note: as I can't find any documentation on the avenrun * symbol, I'm not entirely sure if this is correct. */#ifndef FSCALE#define FSHIFT  8		/* bits to right of fixed binary point */#define FSCALE  (1<<FSHIFT)#endif/* Macro to convert between avenrun load average numbers and normal	*//* load average.							*/#define loaddouble(x) ((double)(x) / FSCALE)/* Convert number of pages to size in kB.				*/#define pagetok(size) ((size * PAGESIZE) >> 10)/* * Unixware doesn't explicitly track zombie processes. * However, they can be identified as processes with no threads. * Also, define an additional artificial process state to keep * track of how many zombies there are. */#define	ZOMBIE(z)	((z)->p.p_nlwp == 0)#define	ZOMBIESTATE	6/* * Definitions for the index in the nlist array. */#define X_AVENRUN	0#define X_NEXTPID	1#define X_V		2#define X_OFFSETS	3#define X_TOTALMEM	4/* * Hash function for the table of processes used to keep old information. */#define	HASH(x)	((x << 1) % numoldprocs)/* ************************************************************************** *//* * Include files */#include "utils.h"#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/procfs.h>#include <sys/sysinfo.h>#include <sys/sysmacros.h>#include <sys/vmmeter.h>#include <sys/ksym.h>#include <vm/anon.h>#include <sys/priocntl.h>#include <sys/rtpriocntl.h>#include <sys/tspriocntl.h>#include <sys/procset.h>#include <sys/var.h>#include <sys/metrics.h>#include <sys/time.h>#include "top.h"#include "machine.h"/* ************************************************************************** *//* * Structures *//* * A process is just a thread container under Unixware. * So, define the following structure which will aggregate * most of what we want. */struct	uwproc{	int		dummy;	struct	psinfo	ps;	struct	proc	p;	struct	lwp	l;	double		pctcpu;	double		wcpu;};/* defines to simplify access to some of contents of uwproc struct */#define PR_pri   ps.pr_lwp.pr_pri#define PR_state ps.pr_lwp.pr_state#define PR_time  ps.pr_lwp.pr_time/* * oldproc * Oldproc is used to hold process CPU history necessary to * calculate %CPU and WCPU figures. */struct oldproc{	int	oldpid;	double	oldtime;	/* Duration of process in ns.	*/	double	oldpct;};/* * nlist * An array of the kernel sybols used by this module. */static struct nlist nlst[] ={	{"avenrun"},			/* 0 X_AVENRUN	 */	{"nextpid"},			/* 1 X_NEXTPID	 */	{"v"},				/* 2 X_V	 */	{"met_localdata_ptrs_p"},	/* 3 X_OFFSETS */	{"totalmem"},			/* 4 X_TOTALMEM  */	{NULL}};/* * Get_process_info passes back a handle.  This is what it looks like: */struct handle{	struct uwproc	**next_proc;	/* points to next valid proc pointer */	int 		  remaining;	/* number of pointers remaining */};/* ************************************************************************** *//* * Globals */static unsigned long	avenrun_offset;static unsigned long	nextpid_offset;static unsigned long	v_offset;static unsigned long	offset_offset;static unsigned long	totalmem_offset;static int		kmem = -1;	/* FD to /dev/kmem.		      */static int		maxprocs;	/* Maximum number of processes that   */					/* can be running on the system.      */static int		numoldprocs;	/* Size of oldproc hash.	      */static int		numprocs = 0;	/* Number of processes currently      */					/* running on the system.  Updated    */					/* each time getptable() is called.   */static int		bytes;		/* Size of array of process structs.  */static struct uwproc   *pbase;		/* Pointer to array of process info.  */static struct uwproc  **pref;		/* Vector of uwbase pointers.	      */static struct oldproc  *oldbase;	/* Pointer to array of old proc info. */static DIR	       *procdir;extern int		errno;extern char	       *myname;/* * An abbreviation of the states each process may be in. */char *state_abbrev[] =	{ "oncpu", "run", "sleep", "stop", "idle", "zomb", NULL};/* * The states each process may be in. */int process_states[6];char *procstatenames[] ={	" on cpu, ", " running, ", " sleeping, ", " stopped, ",	" idle, ", " zombie", NULL};/* * CPU usage tracked by the kernel. */#define CPUSTATES	4int cpu_states[CPUSTATES];char *cpustatenames[] =	{"idle", "wait", "user", "sys", NULL};/* * These are for detailing the memory statistics. */int memory_stats[3];char *memorynames[] =	{"K phys, ", "K swap, ", "K swap free", NULL};/* *  These definitions control the format of the per-process area */static char header[] =#ifdef SHOW_NICE    "  PID X        PRI NICE  SIZE   RES STATE   TIME   WCPU    CPU COMMAND";#else    "  PID X        PRI  THR  SIZE   RES STATE   TIME   WCPU    CPU  COMMAND";#endif/* 0123456   -- field to fill in starts at header+6 */  /* XXXX */#define UNAME_START 6#define PROC_FORMAT "%5d %-8.8s %3d %4d %5s %5s %-5s %6s %5.2f%% %5.2f%% %s"/* these are names given to allowed sorting orders -- first is default */char *ordernames[] = {"cpu", "state", "size", "res", "time", "pid", "uid", "rpid", "ruid", NULL};/* ************************************************************************** *//* * Prototypes */int		machine_init(struct statics *);char		*format_header(char *);void		get_system_info(struct system_info *);caddr_t		get_process_info(struct system_info *,				 struct process_select *, int (*)());char		*format_next_process(caddr_t, char *(*)());int		check_nlist(register struct nlist *);int		getkval(unsigned long, void *, int, char *);int		proc_compare(void *, void *);void		getptable(struct uwproc *);uid_t		proc_owner(pid_t);int		setpriority(int, int, int);void		get_swapinfo(long *, long *);/* forward definitions for comparison functions */int compare_state(void *, void *);int compare_cpu(void *, void *);int compare_size(void *, void *);int compare_res(void *, void *);int compare_time(void *, void *);int compare_pid(void *, void *);int compare_uid(void *, void *);int compare_rpid(void *, void *);int compare_ruid(void *, void *);int (*proc_compares[])() = {    compare_cpu,    compare_state,    compare_size,    compare_res,    compare_time,    compare_pid,    compare_uid,    compare_rpid,    compare_ruid,    NULL };extern long	percentages ();extern void	quit ();/* ************************************************************************** *//* * machine_int * Perform once-off initialisation tasks. */intmachine_init (struct statics *statics){	static	 struct var 		 v;	struct	oldproc			*op;	int				 i;	/*	 * Fill in the statics information.	 */	statics->procstate_names	= procstatenames;	statics->cpustate_names		= cpustatenames;	statics->memory_names		= memorynames;        statics->order_names            = ordernames;	/*	 * Go through the kernel symbols required for this	 * module, and check that they are available.	 */	if (nlist (UNIX, nlst))	{		fprintf (stderr, "Unable to nlist %s\n", UNIX);		return -1;	}	/*	 * Make sure they were all found.	 */	if (check_nlist (nlst) > 0)		return -1;	/*	 * Open KMEM device for future use.	 */	kmem	= open(PATH_KMEM, O_RDONLY);	if (kmem == -1)	{		perror(PATH_KMEM);		return -1;	}	/*	 * Extract the maximum number of running processes.	 */	getkval(nlst[X_V].n_value, (void *)&v, sizeof(v), nlst[X_V].n_name);	maxprocs		= v.v_proc;	/*	 * Save pointers.	 */	avenrun_offset		= nlst[X_AVENRUN].n_value;	nextpid_offset		= nlst[X_NEXTPID].n_value;	v_offset		= nlst[X_V].n_value;	offset_offset		= nlst[X_OFFSETS].n_value;	totalmem_offset		= nlst[X_TOTALMEM].n_value;	/*	 * Allocate space for proc structure array and array of pointers.	 */	bytes	 = maxprocs * sizeof (struct uwproc);	pbase	 = (struct uwproc *) malloc (bytes);	pref	 = (struct uwproc **)		   malloc (maxprocs * sizeof (struct uwproc *));	numoldprocs = maxprocs * 2;	oldbase	 = (struct oldproc *)malloc(numoldprocs *					    sizeof(struct oldproc));	if (pbase == (struct uwproc *) NULL ||	    pref == (struct uwproc **) NULL ||	    oldbase == (struct oldproc *) NULL)	{		fprintf(stderr, "%s: can't allocate sufficient memory\n",			myname);		return -1;	}	/*	 * Obtain a handle on the /proc filesystem, and change into it.	 */	if (!(procdir = opendir (PROCFS)))	{		fprintf (stderr, "Unable to open %s\n", PROCFS);		return -1;	}	if (chdir (PROCFS))	{		fprintf (stderr, "Unable to chdir to %s\n", PROCFS);		return -1;	}	/*	 * Initialise the oldproc structures.	 */	for (op = oldbase, i = 0; i < numoldprocs; i++)	{		op[i].oldpid	= -1;	}	/*	 * All done!	 */	return (0);}/* ************************************************************************** *//* * format_header */char *format_header (char *uname_field){	register char *ptr;	ptr = header + UNAME_START;	while (*uname_field != '\0')		*ptr++ = *uname_field++;	return (header);}/* ************************************************************************** *//* * Extract information out of system data structures. */voidget_system_info (struct system_info *si){	long			avenrun[3];	static time_t		cp_old[CPUSTATES];	static time_t		cp_diff[CPUSTATES];/*for cpu state percentages*/	register int		i;	struct	met_localdata_ptrs	*mlpp;	struct	met_localdata_ptrs	 mlp;	struct	plocalmet		 plm;	struct	metp_cpu		 mc;	unsigned	long	totalmem;	long			totalswap;	long			totalswapfree;

⌨️ 快捷键说明

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