Exemplo n.º 1
0
caddr_t
get_process_info(struct system_info * si, struct process_select * sel, int x,
		char *conninfo)
{
	register int i;
	register int total_procs;
	register int active_procs;
	register struct macos_proc **prefp;
	register struct macos_proc *pp;
	register struct kinfo_proc *pp2;

	/*
	 * these are copied out of sel for speed
	 */

	int			show_idle;
	int			show_system;
	int			show_uid;
	int			show_command;

	/* begin mucking */
	/* kproc_list = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc); */
	PGconn *pgconn;
	PGresult *pgresult = NULL;

	nproc = 0;
	pgconn = connect_to_db(conninfo);
	if (pgconn != NULL)
	{
		pgresult = pg_processes(pgconn);
		nproc = PQntuples(pgresult);
		pbase = (struct kinfo_proc *) malloc(sizeof(struct kinfo_proc *));
	}
	PQfinish(pgconn);

	int mib[4];
	mib[0] = CTL_KERN;
	mib[1] = KERN_PROC;
	mib[2] = KERN_PROC_PID;

	size_t len = nproc;

	struct kinfo_proc *buffer;
	buffer = (struct kinfo_proc *) malloc( len * sizeof(struct kinfo_proc) );

	for (i = 0; i < nproc ; i++) {
		size_t size = sizeof(struct kinfo_proc);
		mib[3] = atoi(PQgetvalue(pgresult, i, 0));

		if (sysctl(mib, sizeof(mib)/sizeof(int), &buffer[i], &size, NULL,
				0) == -1) {
			perror("sysctl atoi loop");
			return "1";
		}

	}

	kproc_list = buffer;
	len = nproc;
	/* end selena's messing about */

	if (nproc > onproc)
	{
		proc_list = (struct macos_proc *) realloc(proc_list,
				sizeof(struct macos_proc) * nproc);
		proc_ref = (struct macos_proc **) realloc(proc_ref,
				sizeof(struct macos_proc *) * (onproc = nproc));
	}

	if (proc_ref == NULL || proc_list == NULL || kproc_list == NULL)
	{
		puke("error: out of memory (%s)", strerror(errno));
		return (NULL);
	}

	/*
	 * now, our task is to build the array of information we need to function
	 * correctly.  This involves setting a pointer to each real kinfo_proc
	 * structure returned by kvm_getprocs() in addition to getting the mach
	 * information for each of those processes.
	 */

	for (pp2 = kproc_list, i = 0; i < nproc; pp2++, i++)
	{

		/*
		 * 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)
		{
			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_uid = sel->uid != -1;
	show_command = sel->command != NULL;
	show_fullcmd = sel->fullcmd;

	/* 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
	 */

	qsort((char *) proc_ref, active_procs, sizeof(struct macos_proc *),
			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);
}
Exemplo n.º 2
0
caddr_t
get_process_info(struct system_info *si, struct process_select *sel,
    int compare_index, char *conninfo)
{
	int show_idle, show_system, show_threads, show_uid, show_cmd;
	int total_procs, active_procs;
	struct kinfo_proc2 **prefp, *pp;
	int mib[6];
	size_t size;

	int i;
	PGconn *pgconn;
	PGresult *pgresult = NULL;

	size = (size_t) sizeof(struct kinfo_proc2);
	mib[0] = CTL_KERN;
	mib[1] = KERN_PROC2;
	mib[2] = KERN_PROC_PID;
	mib[4] = sizeof(struct kinfo_proc2);
	mib[5] = 1;

	nproc = 0;
	pgconn = connect_to_db(conninfo);
	if (pgconn != NULL)
	{
		pgresult = pg_processes(pgconn);
		nproc = PQntuples(pgresult);
		pbase = (struct kinfo_proc2 *) realloc(pbase,
				sizeof(struct kinfo_proc2 *) * nproc);
	}
	PQfinish(pgconn);

	if (nproc > onproc)
		pref = (struct kinfo_proc2 **)realloc(pref,
		    sizeof(struct kinfo_proc2 *) * (onproc = nproc));
	if (pref == NULL) {
		warnx("Out of memory.");
		quit(23);
	}
	/* 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_uid = sel->uid != (uid_t)-1;
	show_cmd = 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 = pref;
	i = 0;
	for (pp = pbase; pp < &pbase[nproc]; pp++) {
		mib[3] = atoi(PQgetvalue(pgresult, i, 0));
		if (sysctl(mib, 6, &pbase[i++], &size, NULL, 0) != 0)
		{
			printf("\n\ndoh %d\n", errno);
			perror("\n\ndoh");
			exit(1);
		}

		/*
		 *  Place pointers to each valid proc structure in pref[].
		 *  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_system is set.
		 */
		if (pp->p_stat != 0 &&
		    (show_system || (pp->p_flag & P_SYSTEM) == 0) &&
		    (show_threads || (pp->p_flag & P_THREAD) == 0)) {
			total_procs++;
			process_states[(unsigned char) pp->p_stat]++;
			if (pp->p_stat != SZOMB &&
			    (show_idle || pp->p_pctcpu != 0 ||
			    pp->p_stat == SRUN) &&
			    (!show_uid || pp->p_ruid == sel->uid) &&
			    (!show_cmd || strstr(pp->p_comm,
				sel->command))) {
				*prefp++ = pp;
				active_procs++;
			}
		}
	}

	/* if requested, sort the "interesting" processes */
	if (compare_index != NULL)
		qsort((char *) pref, active_procs,
		    sizeof(struct kinfo_proc2 *), proc_compares[compare_index]);
	/* remember active and total counts */
	si->p_total = total_procs;
	si->p_active = pref_len = active_procs;

	/* pass back a handle */
	handle.next_proc = pref;
	handle.remaining = active_procs;
	return ((caddr_t) & handle);
}
Exemplo n.º 3
0
caddr_t
get_process_info(struct system_info * si,
				 struct process_select * sel,
				 int compare_index, char *conninfo, int mode)
{
	struct timeval thistime;
	double		timediff,
				alpha,
				beta;
	struct top_proc *proc;
	pid_t		pid;
	unsigned long now;
	unsigned long elapsed;
	int			i;

	/* calculate the time difference since our last check */
	gettimeofday(&thistime, 0);
	if (lasttime.tv_sec)
	{
		timediff = ((thistime.tv_sec - lasttime.tv_sec) +
					(thistime.tv_usec - lasttime.tv_usec) * 1e-6);
	}
	else
	{
		timediff = 0;
	}
	lasttime = thistime;

	/* round current time to a second */
	now = (unsigned long) thistime.tv_sec;
	if (thistime.tv_usec >= 500000)
	{
		now++;
	}

	/* calculate constants for the exponental average */
	if (timediff > 0.0 && timediff < 30.0)
	{
		alpha = 0.5 * (timediff / 30.0);
		beta = 1.0 - alpha;
	}
	else
	{
		alpha = beta = 0.5;
	}
	timediff *= HZ;				/* convert to ticks */

	/* mark all hash table entries as not seen */
	for (i = 0; i < HASH_SIZE; ++i)
	{
		for (proc = ptable[i]; proc; proc = proc->next)
		{
			proc->state = 0;
		}
	}

	/* read the process information */
	{
		int			total_procs = 0;
		struct top_proc **active;

		int			show_idle = sel->idle;
		int			show_uid = sel->uid != -1;

		int			i;
		int			rows;
		PGconn	   *pgconn;
		PGresult   *pgresult = NULL;

		memset(process_states, 0, sizeof(process_states));

		pgconn = connect_to_db(conninfo);
		if (pgconn != NULL)
		{
			pgresult = pg_processes(pgconn);
			rows = PQntuples(pgresult);
		}
		else
		{
			rows = 0;
		}
		for (i = 0; i < rows; i++)
		{
			char	   *procpid = PQgetvalue(pgresult, i, 0);
			struct top_proc *pp;
			unsigned long otime;

			pid = atoi(procpid);

			/* look up hash table entry */
			proc = pp = ptable[HASH(pid)];
			while (proc && proc->pid != pid)
			{
				proc = proc->next;
			}

			/* if we came up empty, create a new entry */
			if (proc == NULL)
			{
				proc = new_proc();
				proc->pid = pid;
				proc->next = pp;
				ptable[HASH(pid)] = proc;
				proc->time = 0;
				proc->wcpu = 0;
			}

			otime = proc->time;

			read_one_proc_stat(pid, proc, sel);
			if (sel->fullcmd == 2)
				update_procname(proc, PQgetvalue(pgresult, i, 1));

			if (proc->state == 0)
				continue;

			total_procs++;
			process_states[proc->state]++;

			if (timediff > 0.0)
			{
				if ((proc->pcpu = (proc->time - otime) / timediff) < 0.0001)
				{
					proc->pcpu = 0;
				}
				proc->wcpu = proc->pcpu * alpha + proc->wcpu * beta;
			}
			else if ((elapsed = (now - boottime) * HZ - proc->start_time) > 0)
			{
				/*
				 * What's with the noop statement? if ((proc->pcpu =
				 * (double)proc->time / (double)elapsed) < 0.0001) {
				 * proc->pcpu; }
				 */
				proc->wcpu = proc->pcpu;
			}
			else
			{
				proc->wcpu = proc->pcpu = 0.0;
			}
		}
		if (pgresult != NULL)
			PQclear(pgresult);
		PQfinish(pgconn);

		/* make sure we have enough slots for the active procs */
		if (activesize < total_procs)
		{
			pactive = (struct top_proc **) realloc(pactive,
									sizeof(struct top_proc *) * total_procs);
			activesize = total_procs;
		}

		/* set up the active procs and flush dead entries */
		active = pactive;
		for (i = 0; i < HASH_SIZE; i++)
		{
			struct top_proc *last;
			struct top_proc *ptmp;

			last = NULL;
			proc = ptable[i];
			while (proc != NULL)
			{
				if (proc->state == 0)
				{
					ptmp = proc;
					if (last)
					{
						proc = last->next = proc->next;
					}
					else
					{
						proc = ptable[i] = proc->next;
					}
					free_proc(ptmp);
				}
				else
				{
					if ((show_idle || proc->state == 1 || proc->pcpu) &&
						(!show_uid || proc->uid == sel->uid))
					{
						*active++ = proc;
						last = proc;
					}
					proc = proc->next;
				}
			}
		}

		si->p_active = active - pactive;
		si->p_total = total_procs;
		si->procstates = process_states;
	}

	/* if requested, sort the "active" procs */
	if (si->p_active) {
		if (mode == MODE_IO_STATS) {
			qsort(pactive, si->p_active, sizeof(struct top_proc *),
			  		io_compares[compare_index]);
		}
		else
		{
			qsort(pactive, si->p_active, sizeof(struct top_proc *),
			  		proc_compares[compare_index]);
		}
	}

	/* don't even pretend that the return value thing here isn't bogus */
	nextactive = pactive;
	return (caddr_t) 0;
}