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

📄 m_macosx.c

📁 unix系统下top命令的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		 * first, we set the pointer to the reference in		 * the kproc list.		 */				proc_list[i].kproc = pp2;		/*		 * then, we load all of the task info for the process		 */		if(PP(pp2, p_stat) != SZOMB)			{			rc = task_by_unix_pid(task_self(), 				PP(pp2, p_pid), 				&(proc_list[i].the_task));			if(rc != KERN_SUCCESS)				{				puke("error:  get task info for pid %d failed with rc = %d", PP(pp2, p_pid), rc);				}			/*			 * load the task information			 */			rc = task_info(proc_list[i].the_task, TASK_BASIC_INFO, 				(task_info_t)&(proc_list[i].task_info),				&info_count);			if(rc != KERN_SUCCESS)				{				puke("error:  couldn't get task info (%s); rc = %d", strerror(errno), rc);				}			/*			 * load the thread summary information			 */			load_thread_info(&proc_list[i]);			}		}	/* 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 = proc_ref;	for(pp = proc_list, i = 0; i < nproc; pp++, i++)		{		/*		 *  Place pointers to each valid proc structure in 		 * proc_ref[].  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(MPP(pp, p_stat) != 0 && 				(show_system || ((MPP(pp, p_flag) & P_SYSTEM) == 0)))			{			total_procs++;			process_states[(unsigned char) MPP(pp, p_stat)]++;			if((MPP(pp, p_stat) != SZOMB) &&					(show_idle || (MPP(pp, p_pctcpu) != 0) || 			 		(MPP(pp, p_stat) == SRUN)) &&					(!show_uid || MEP(pp, e_pcred.p_ruid) == (uid_t)sel->uid))				{				*prefp++ = pp;				active_procs++;				}			}		}		/* 	 * if requested, sort the "interesting" processes	 */	if(compare != NULL)		qsort((char *)proc_ref, active_procs, sizeof(struct macos_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 = proc_ref;	handle.remaining = active_procs;	return((caddr_t)&handle);}/* * get_system_info() * * This function is responsible for geting the periodic * system information snapshot. */int get_system_info(struct system_info *si){	register long	total;	register int	i;	/*	 * get the cp_time array	 */	if(!kread(nlst[X_CP_TIME].n_value, cp_time,			sizeof(cp_time), nlst[X_CP_TIME].n_name))		return(0);#ifdef MAX_VERBOSE	/*	 * print out the entries	 */	for(i = 0; i < CPUSTATES; i++)		printf("cp_time[%d] = %d\n", i, cp_time[i]);#endif /* MAX_VERBOSE */	/*	 * get the load averages	 */	if(kvm_getloadavg(kd, si->load_avg, NUM_AVERAGES) == -1)		{		puke("error:  kvm_getloadavg() failed (%s)", strerror(errno));		return(0);		}#ifdef MAX_VERBOSE	printf("%-30s%03.2f, %03.2f, %03.2f\n", 			"load averages:", 			si->load_avg[0],			si->load_avg[1],			si->load_avg[2]);#endif /* MAX_VERBOSE */	total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff);	/*	 * get the memory statistics	 */	{		kern_return_t	status;		status = vm_statistics(task_self(), &vm_stats);		if(status != KERN_SUCCESS)			{			puke("error:  vm_statistics() failed (%s)", strerror(errno));			return(0);			}		/*		 * we already have the total memory, we just need		 * to get it in the right format.		 */		memory_stats[0] = pagetok(maxmem / vm_stats.pagesize);		memory_stats[1] = pagetok(vm_stats.free_count);		memory_stats[2] = pagetok(vm_stats.active_count);		memory_stats[3] = pagetok(vm_stats.inactive_count);		memory_stats[4] = pagetok(vm_stats.wire_count);		if(swappgsin < 0)			{			memory_stats[5] = 1;			memory_stats[6] = 1;			}		else			{			memory_stats[5] = pagetok(((vm_stats.pageins - swappgsin)));			memory_stats[6] = pagetok(((vm_stats.pageouts - swappgsout)));			}		swappgsin = vm_stats.pageins;		swappgsout = vm_stats.pageouts;	}		si->cpustates = cpu_states;	si->memory = memory_stats;	si->last_pid = -1;	return(1);}/* * machine_init() * * This function is responsible for filling in the values of the * statics structure. */int machine_init(struct statics *stat){	register int rc = 0;	register int i = 0;//	register int pagesize;	/*	 * open the kernel	 */	if((kd = kvm_open(VMUNIX, MEM, SWAP, O_RDONLY, "kvm_open")) == NULL)		{		puke("error:  couldn't open kernel (%s)", strerror(errno));		return(0);		}	/*	 * turn off super-user privs	 *///	seteuid(getuid());	/*	 * read the nlist we need	 */		rc = kvm_nlist(kd, nlst);	if(rc == -1)		{		puke("error:  unable to read kernel table (%s)", strerror(errno));		return(0);		}	if(rc > 0)		{		puke("error:  kvm_nlist() found %d invalid entries.\n", rc);		return(0);		}#ifdef MAX_VERBOSE	/*	 * print out the entries	 */	for(i = 0; i < NLIST_LAST; i++)		{		printf("symbol %10s is type 0x%02X at offset 0x%02X\n", 			nlst[i].n_name, 			nlst[i].n_type & N_TYPE, 			nlst[i].n_value);		}#endif /* MAX_VERBOSE */	/*	 * next, we get the data for the names	 *	 * get max number of processes	 */	if(!kread(nlst[X_NPROC].n_value, &nproc,			sizeof(nproc), nlst[X_NPROC].n_name))		return(0);#ifdef MAX_VERBOSE	printf("%-30s%10d\n", "max number of processes:", nproc);#endif /* MAX_VERBOSE */	/*	 * get clock rate	 */	if(!kread(nlst[X_HZ].n_value, &hz,			sizeof(hz), nlst[X_HZ].n_name))		return(0);#ifdef MAX_VERBOSE	printf("%-30s%10d\n", "clock rate:", hz);#endif /* MAX_VERBOSE */	/*	 * get memory size	 */	if(!kread(nlst[X_MAXMEM].n_value, &maxmem,			sizeof(maxmem), nlst[X_MAXMEM].n_name))		return(0);#ifdef MAX_VERBOSE	printf("%-30s%10d\n", "total system memory:", maxmem);#endif /* MAX_VERBOSE */	/*	 * calculate the pageshift from the system page size	 */	pagesize = getpagesize();	pageshift = 0;	while((pagesize >>= 1) > 0)		pageshift++;	pageshift -= LOG1024;	/*	 * fill in the statics information	 */	stat->procstate_names = procstates;	stat->cpustate_names = cpustates;	stat->memory_names = memnames;	return(0);}/* 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(struct macos_proc **pp1, struct macos_proc **pp2){    register struct macos_proc *p1;    register struct macos_proc *p2;    register int result;    register pctcpu lresult;    /* remove one level of indirection */    p1 = *(struct macos_proc **) pp1;    p2 = *(struct macos_proc **) pp2;    /* compare percent cpu (pctcpu) */    if ((lresult = RP(p2, cpu_usage) - RP(p1, cpu_usage)) == 0)    {	/* use cpticks to break the tie */	if ((result = MPP(p2, p_cpticks) - MPP(p1, p_cpticks)) == 0)	{	    /* use process state to break the tie */	    if ((result = sorted_state[(unsigned char) MPP(p2, p_stat)] -			  sorted_state[(unsigned char) MPP(p1, p_stat)])  == 0)	    {		/* use priority to break the tie */		if ((result = MPP(p2, p_priority) - MPP(p1, p_priority)) == 0)		{		    /* use resident set size (rssize) to break the tie */		    if ((result = MVP(p2, vm_rssize) - MVP(p1, vm_rssize)) == 0)		    {			/* use total memory to break the tie */			result = PROCSIZE(p2->kproc) - PROCSIZE(p1->kproc);		    }		}	    }	}    }    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(pid)int pid;{    register int cnt;    register struct macos_proc **prefp;    register struct macos_proc *pp;    prefp = proc_ref;    cnt = pref_len;    while (--cnt >= 0)    {	pp = *prefp++;		if (MPP(pp, p_pid) == (pid_t)pid)	{	    return((int)MEP(pp, e_pcred.p_ruid));	}    }    return(-1);}/* * load_thread_info() * * This function will attempt to load the thread summary info * for a Mach task.  The task is located as part of the macos_proc * structure. * * returns the kern_return_t value of any failed call or KERN_SUCCESS * if everything works. */int load_thread_info(struct macos_proc *mp){	register kern_return_t		rc = 0;	register int			i = 0;	register int			t_utime = 0;	register int			t_stime = 0;	register int			t_cpu = 0;	register int			t_state = 0;	register task_t			the_task = mp->the_task;	thread_array_t			thread_list = NULL;	/*	 * We need to load all of the threads for the 	 * given task so we can get the performance 	 * data from them.	 */	mp->thread_count = 0;	rc = task_threads(the_task, &thread_list, &(mp->thread_count));	if(rc != KERN_SUCCESS)		{//		puke("error:  unable to load threads for task (%s); rc = %d", strerror(errno), rc);		return(rc);		}	/*	 * now, for each of the threads, we need to sum the stats	 * so we can present the whole thing to the caller.	 */	for(i = 0; i < mp->thread_count; i++)		{		struct thread_basic_info	t_info;		int				icount = THREAD_BASIC_INFO_COUNT;		kern_return_t			rc = 0;		rc = thread_info(thread_list[i], THREAD_BASIC_INFO, 				(thread_info_t)&t_info, &icount);		if(rc != KERN_SUCCESS)			{			puke("error:  unable to load thread info for task (%s); rc = %d", strerror(errno), rc);			return(rc);			}		t_utime += t_info.user_time.seconds;		t_stime += t_info.system_time.seconds;		t_cpu += t_info.cpu_usage;		}	vm_deallocate(task_self(), (vm_address_t)thread_list, sizeof(thread_array_t)*(mp->thread_count));	/*	 * Now, we load the values in the structure above.	 */	RP(mp, user_time).seconds = t_utime;	RP(mp, system_time).seconds = t_stime;	RP(mp, cpu_usage) = t_cpu;	return(KERN_SUCCESS);}

⌨️ 快捷键说明

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