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

📄 m_next32.c

📁 unix系统下top命令的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    	{				pref[j].p_self = pp;				if(thread_status==KERN_SUCCESS)				{					pref[j].run_state = threadInfo.run_state;					pref[j].flags = threadInfo.flags;					pref[j].p_pctcpu = threadInfo.cpu_usage;					pref[j].p_cptime = threadInfo.user_time.seconds + 				  					   threadInfo.system_time.seconds;					pref[j].cur_priority = threadInfo.cur_priority;					pref[j].nthreads = threadCount;				} else {					pref[j].run_state = 0;					pref[j].flags = 0;					pref[j].p_pctcpu = 0;					pref[j].p_cptime = 0;				}				/* Get processes memory usage and cputime */				if(task_status==KERN_SUCCESS)				{					pref[j].p_rsize = taskInfo.resident_size/1024;					pref[j].p_vsize = taskInfo.virtual_size/1024;				} else {					pref[j].p_rsize = 0;					pref[j].p_vsize = 0;				}				active_procs++;				j++;	    	}		}		i++;	} while(pp->p_nxt != 0);	pref[j].p_self = NULL;  /*  End list of processes with NULL */    /* if requested, sort the "interesting" processes */     if (compare != NULL)    {		qsort((char *)pref, active_procs, sizeof(struct proc_unix), compare);    }    /* remember active and total counts */    si->p_total = total_procs;    si->p_active = pref_count = active_procs;    /* pass back a handle */    handle.list = pref;    handle.count = active_procs;    handle.current = 0;    return((caddr_t)&handle);}char fmt[MAX_COLS];		/* static area where result is built */char *format_next_process(caddr_t handle, char *(*get_userid)()){    register struct proc *pp;    register long cputime;    register double pct, wcpu, pctmem;    int where;    struct user u;    struct handle *hp;	register int p_pctcpu;	register int rm_size;	register int vm_size;	register int run_state;	register int flags;	register int nthreads;	register int cur_priority;	char state_str[10];    /* find and remember the next proc structure */    hp = (struct handle *)handle;	pp = hp->list[hp->current].p_self;    p_pctcpu = hp->list[hp->current].p_pctcpu;    cputime = hp->list[hp->current].p_cptime;    rm_size = hp->list[hp->current].p_rsize;    vm_size = hp->list[hp->current].p_vsize;	run_state = hp->list[hp->current].run_state;	flags = hp->list[hp->current].flags;	nthreads = hp->list[hp->current].nthreads;	cur_priority = hp->list[hp->current].cur_priority;	hp->current++;    hp->count--;    /* get the process's user struct and set cputime */    where = getu(pp, &u);    if (where == -1)    {		(void) strcpy(u.u_comm, "<swapped>");		cputime = 0;    }    else    {		/* set u_comm for system processes */		if (u.u_comm[0] == '\0')		{	    	if (pp->p_pid == 0)	    	{				(void) strcpy(u.u_comm, "Swapper");	    	}	    	else if (pp->p_pid == 2)	    	{				(void) strcpy(u.u_comm, "Pager");	    	}			}		if (where == 1) {	    	/*	     	* Print swapped processes as <pname>	     	*/	    	char buf[sizeof(u.u_comm)];	    	(void) strncpy(buf, u.u_comm, sizeof(u.u_comm));	    	u.u_comm[0] = '<';	    	(void) strncpy(&u.u_comm[1], buf, sizeof(u.u_comm) - 2);	    	u.u_comm[sizeof(u.u_comm) - 2] = '\0';	    	(void) strncat(u.u_comm, ">", sizeof(u.u_comm) - 1);	    	u.u_comm[sizeof(u.u_comm) - 1] = '\0';		}/*	User structure does not work.  Use Thread Info to get cputime for process. *//*		cputime = u.u_ru.ru_utime.tv_sec + u.u_ru.ru_stime.tv_sec; */    }    /* calculate the base for cpu percentages */    pct = (double)(p_pctcpu)/TH_USAGE_SCALE;/*	wcpu = weighted_cpu(pct, pp); */	pctmem = (double)(rm_size*1024.) / (double)(host_stats.memory_size);		/* Get process state description */	if(run_state)	{		strcpy(state_str, mach_state[run_state]);		strcat(state_str, flags_state[flags]);	} else {		strcpy(state_str, state_abbrev[pp->p_stat]);	}	    /* format this entry */    sprintf(fmt,	    Proc_format,	    pp->p_pid,	    (*get_userid)(pp->p_uid),	    state_str,		cur_priority,/*	    pp->p_pri - PZERO, */	    pp->p_nice - NZERO,		nthreads,	    format_k(vm_size),	    format_k(rm_size),	    100.0 * pctmem,/*	    100.0 * wcpu, */	    100.0 * pct,	    format_time(cputime),	    printable(u.u_comm));    /* return the result */    return(fmt);}/* *  getu(p, u) - get the user structure for the process whose proc structure *	is pointed to by p.  The user structure is put in the buffer pointed *	to by u.  Return 0 if successful, -1 on failure (such as the process *	being swapped out). */getu(register struct proc *p, struct user *u){    register int nbytes, n;	struct task task;	struct utask utask;	struct uthread thread;    /*     *  Check if the process is currently loaded or swapped out.  The way we     *  get the u area is totally different for the two cases.  For this     *  application, we just don't bother if the process is swapped out.     */	/* NEXTSTEP proc.h	 * One structure allocated per active	 * process. It contains all data needed	 * about the process while the	 * process may be swapped out.	 * Other per process data (user.h)	 * is swapped with the process.	 */    if ((p->p_flag & SLOAD) == 0) {/* User info is always in core. * #ifdef DOSWAP * 		if (lseek(swap, (long)dtob(p->p_swaddr), 0) == -1) { * 	    	perror("lseek(swap)"); * 	    	return(-1); * 		} * 		if (read(swap, (char *) u, sizeof(struct user)) != sizeof(struct user))  { * 	    	perror("read(swap)"); * 	    	return(-1); * 		} * 		return (1); * #else */		return(-1);/*#endif */    }    /*     *  Process is currently in memory, we hope!     */	if(!getkval(p->task, (int *)&task, sizeof(struct task), "task")) {#ifdef DEBUG		perror("getkval(p->task)");#endif		/* we can't seem to get to it, so pretend it's swapped out */		return(-1);	}	if(!getkval(task.u_address, (int *)&utask, sizeof(struct utask), "task.u_address")) {#ifdef DEBUG		perror("getkval(task->utask)");#endif		/* we can't seem to get to it, so pretend it's swapped out */		return(-1);	}	/* Copy utask and uthread info into struct user *u */	/*  This is incomplete.  Only copied info needed. */	u->u_procp = utask.uu_procp;	u->u_ar0 = utask.uu_ar0;	u->u_ru = utask.uu_ru;	strcpy(u->u_comm, utask.uu_comm);	nbytes = strlen(u->u_comm);	for(n=nbytes; n<MAXCOMLEN; n++)		u->u_comm[n] = ' ';	u->u_comm[MAXCOMLEN] = '\0';	return(0);}/* * 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. */int check_nlist(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 */    i = 0;    while (nlst->n_un.n_name != NULL)    {	if (nlst->n_type == 0 && nlst->n_value == 0)	{	    /* this one wasn't found */	    fprintf(stderr, "kernel: no symbol named `%s'\n", nlst->n_un.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). *  	 */getkval(unsigned long offset, int *ptr, int size, char *refstr){    if (lseek(kmem, (long)offset, L_SET) == -1) {        if (*refstr == '!')            refstr++;        (void) fprintf(stderr, "%s: lseek to %s: %s\n", KMEM, 		       refstr, strerror(errno));        quit(23);    }    if (read(kmem, (char *) ptr, size) == -1) {        if (*refstr == '!')             return(0);        else {            (void) fprintf(stderr, "%s: reading %s: %s\n", KMEM, 			   refstr, strerror(errno));            quit(23);        }    }    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			*/}; proc_compare(struct proc_unix *pp1, struct proc_unix *pp2){    register struct proc *p1 = pp1->p_self;    register struct proc *p2 = pp2->p_self;    register int result;    register pctcpu lresult;    /* compare percent cpu (pctcpu) */    if ((lresult = pp2->p_pctcpu - pp1->p_pctcpu) == 0)    {	/* use cpticks to break the tie */	if ((result = P_CPTICKS(p2) - P_CPTICKS(p1)) == 0)	{	    /* use process state to break the tie */	    if ((result = sorted_state[p2->p_stat] - sorted_state[p1->p_stat])  == 0)	    {		/* use priority to break the tie */		if ((result = p2->p_pri - p1->p_pri) == 0)		{		    /* use resident set size (rssize) to break the tie */		    if ((result = pp2->p_rsize - pp1->p_rsize) == 0)		    {			/* use total memory to break the tie */			result = pp2->p_vsize - pp1->p_vsize;		    }		}	    }	}    }    else    {	result = lresult < 0 ? -1 : 1;    }    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(int pid){    register int cnt;    register struct proc *pp;    cnt = pref_count;    while (--cnt >= 0)    {		pp = pref[cnt].p_self;		if( pp->p_pid == pid ) 	/* Modified (pid_t)pid to pid, compiler error. */		{			return((int)pp->p_uid);		}    }    return(-1);}int thread_stats(int pid, struct thread_basic_info *info, int *thread_count){	int 					  i;	kern_return_t             status;	kern_return_t			  status_dealloc;	task_t					  p_task;	thread_array_t			  thread_list, list;	struct thread_basic_info  threadInfo;	unsigned int              info_count = THREAD_BASIC_INFO_COUNT;	/* Get the task pointer for the process. */	status = task_by_unix_pid( task_self(), pid, &p_task);	if (status!=KERN_SUCCESS)	{#ifdef DEBUG		printf("pid = %i\n", pid);    	mach_error("Error calling task_by_unix_pid()", status);#endif		return status;	}		/* Get the list of threads for the task. */	status = task_threads(p_task, &thread_list, thread_count);	if (status!=KERN_SUCCESS)	{#ifdef DEBUG    	mach_error("Error calling task_threads()", status);#endif		return status;	}	/* Get the pctcpu value for each thread and sum the values */	info->user_time.seconds = 0;	info->user_time.microseconds = 0;	info->system_time.seconds = 0;	info->system_time.microseconds = 0;	info->cpu_usage = 0;	info->sleep_time = 0;	for(i=0; i<*thread_count; i++)	{		status = thread_info(thread_list[i], THREAD_BASIC_INFO, 						(thread_info_t)&threadInfo, &info_count);		if (status!=KERN_SUCCESS)		{#ifdef DEBUG    		mach_error("Error calling thread_info()", status);#endif			break; 		} else {			if(i==0)			{				info->base_priority = threadInfo.base_priority;				info->cur_priority = threadInfo.cur_priority;				info->run_state = threadInfo.run_state;				info->flags = threadInfo.flags;				info->suspend_count = threadInfo.suspend_count;				info->sleep_time += threadInfo.sleep_time;			}			info->user_time.seconds += threadInfo.user_time.seconds;			info->user_time.microseconds += threadInfo.user_time.microseconds;			info->system_time.seconds += threadInfo.system_time.seconds;			info->system_time.microseconds += threadInfo.system_time.microseconds;			info->cpu_usage += threadInfo.cpu_usage;		}	}	/* Deallocate the list of threads. */    status_dealloc = vm_deallocate(task_self(), (vm_address_t)thread_list,						   sizeof(thread_list)*(*thread_count));    if (status_dealloc != KERN_SUCCESS)	{#ifdef DEBUG        mach_error("Trouble freeing thread_list", status_dealloc);#endif		status = status_dealloc;	}	return status;}int mach_load_avg(void){	kern_return_t                    status;	host_t                           host;	unsigned int                     info_count;	struct processor_set_basic_info  info;	processor_set_t                  default_set;	status=processor_set_default(host_self(), &default_set);	if (status!=KERN_SUCCESS){    	mach_error("Error calling processor_set_default", status);    	exit(1);	}	info_count=PROCESSOR_SET_BASIC_INFO_COUNT;	status=processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO,   							&host, (processor_set_info_t)&info, &info_count);#ifdef DEBUG	if (status != KERN_SUCCESS)    	mach_error("Error calling processor_set_info", status);#endif	return info.load_average;}kern_return_t task_stats(int pid, struct task_basic_info *info){	kern_return_t             status;	task_t					  p_task;	unsigned int              info_count=TASK_BASIC_INFO_COUNT;	/* Get the task pointer for the process. */	status = task_by_unix_pid( task_self(), pid, &p_task);	if (status!=KERN_SUCCESS) {#ifdef DEBUG		printf("pid = %i\n", pid);    	mach_error("Error calling task_by_unix_pid()", status);#endif		return(status);	}	status=task_info(p_task, TASK_BASIC_INFO, (task_info_t)info, &info_count);	if (status!=KERN_SUCCESS) {#ifdef DEBUG    	mach_error("Error calling task_info()", status);#endif		return(status);	}			return(KERN_SUCCESS);}

⌨️ 快捷键说明

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