[Lcdproc] Mac OS X machine_Darwin patch

Eric Pooch epooch@cox.net
Fri Dec 1 15:31:01 2006


--Apple-Mail-4--151259741
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed

This patch enables both the Iface and ProcSize lcdproc client screens  
for Mac OS X / Darwin


--Apple-Mail-4--151259741
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name=machine_Darwin_iface_procs.patch
Content-Disposition: attachment;
	filename=machine_Darwin_iface_procs.patch

--- machine_Darwin.c.old	2006-10-30 00:00:35.000000000 -0800
+++ machine_Darwin.c	2006-12-01 07:13:57.000000000 -0800
@@ -47,7 +47,9 @@
 #include <sys/user.h>
 #include <kvm.h>
 #include <errno.h>
-
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_mib.h>
 #include <mach/mach.h>
 
 #include "main.h"
@@ -70,7 +72,7 @@
 int machine_init()
 {
 	/* get the page size with "getpagesize" and calculate pageshift from it */
-	int pagesize = 0;
+	unsigned int pagesize = 0;
 	pageshift = 0;
 
 	lcdproc_port = mach_host_self();
@@ -307,39 +309,82 @@
 
 int machine_get_procs(LinkedList *procs)
 {
-	#warning machine_get_procs not implemented
-	return(FALSE);
-	/* FIX ME */
-	/* This needs to be finished. */
-	procinfo_type	*p;
-
-	processor_set_t *psets, pset;
-	task_t          *tasks;
-
-	unsigned int nproc, i;
-
-	if (host_processor_sets(lcdproc_port, &psets, &nproc))
-	{
-		perror("host_processor_sets");
-		return(FALSE);
-	}
-
-	for (i = 0; i < nproc; i++)
-	{
-		if (host_processor_set_priv(lcdproc_port, psets[i], &pset))
-		{
-			perror("host_processor_set_priv");
-			return(FALSE);
-		}
-
+	struct kinfo_proc *kprocs;
+	
+	procinfo_type *p;
+	int nproc, i;
+	int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
+
+	size_t size = 0;
+	
+	/* Call sysctl with a NULL buffer. */ 
+	if ( sysctl(mib, 4, NULL, &size, NULL, 0 ) < 0)
+	{
+		perror("Failure calling sysctl");
+		return FALSE;
+	}
+	/* Allocate a buffer based on previous results of sysctl. */ 
+	kprocs = (struct kinfo_proc *)malloc(size);
+	if (kprocs == NULL)
+	{
+		perror("mem_malloc");
+		return FALSE;
+	}
+	/* Call sysctl again with the new buffer. */
+	if ( sysctl(mib, 4, kprocs, &size, NULL, 0 ) < 0)
+	{
+		perror("Failure calling sysctl");
+		free(kprocs);
+		return FALSE;
+	}
+	
+	nproc = size / sizeof(struct kinfo_proc);		
+	
+	for (i = 0; i < nproc; i++, kprocs++)
+	{
+		mach_port_t task;
+		unsigned int status = kprocs->kp_proc.p_stat;
+		
+		if (status == SIDL ||status == SZOMB)
+			continue;
+		
 		p = malloc(sizeof(procinfo_type));
 		if (!p)
 		{
-			perror("mem_top_malloc");
-			return(FALSE);
+			perror("mem_malloc");
+			continue;
+		}
+		strncpy(p->name, kprocs->kp_proc.p_comm, 15);
+		p->name[15] = '\0';
+		
+		p->number = kprocs->kp_proc.p_pid;
+		
+		LL_Push(procs, (void *)p);
+		
+		/* Normal user can't get tasks for processes owned by root. */
+		if (kprocs->kp_eproc.e_pcred.p_ruid == 0)
+			continue;
+		
+		/* Get the memory data for each pid from Mach. */
+		if (task_for_pid(mach_task_self(), kprocs->kp_proc.p_pid, &task) == KERN_SUCCESS)
+		{
+			task_basic_info_data_t info;
+			mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
+			
+			if (task_info(task, TASK_BASIC_INFO, (task_info_t)&info, &count) == KERN_SUCCESS) {
+				p->totl = (unsigned long)(/*info.virtual_size*/ info.resident_size / 1024);
+			}
+		} else {
+			/* This error pops up very often and doesn't seem to be a serious problem. 
+			perror("task_for_pid");
+			printf("process: %s, owner:%d\n", kprocs->kp_proc.p_comm, kprocs->kp_eproc.e_pcred.p_ruid); */
+			p->totl = 0;
 		}
-
 	}
+	
+	kprocs -= i;
+	free(kprocs);
+	
 	return(TRUE);
 }
 
@@ -431,8 +476,60 @@
 /* Get network statistics */
 int machine_get_iface_stats (IfaceInfo *interface)
 {
-	/* Implementation missing */
-	return 0;
-}
+	static int      first_time = 1;	/* is it first time we call this function? */
+	int             rows;
+	int             name[6] = {CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT};
+	size_t          len;
+	struct ifmibdata ifmd; /* ifmibdata contains the network statistics */
+	
+	len = sizeof(rows);
+	/* get number of interfaces */
+	//if (sysctlbyname("net.link.generic.system.ifcount", &rows, &len, NULL, 0) == 0) {
+	if (sysctl(name, 5, &rows, &len, 0, 0) == 0) {
+		interface->status = down; /* set status down by default */
+		
+		name[3] = IFMIB_IFDATA;
+		name[4] = 0;
+		name[5] = IFDATA_GENERAL;
+		
+		len = sizeof(ifmd);
+		/* walk through all interfaces in the ifmib table from last to first */
+		for ( ; rows > 0; rows--) {
+			name[4] = rows; /* set the interface index */
+			/* retrive the ifmibdata for the current index */
+			if (sysctl(name, 6, &ifmd, &len, NULL, 0) == -1) {
+				perror("read sysctl");
+				break;
+			}
+			/* check if its interface name matches */
+			if (strcmp(ifmd.ifmd_name, interface->name) == 0) {
+				interface->last_online = time(NULL);	/* save actual time */
+				
+				if ((ifmd.ifmd_flags & IFF_UP) == IFF_UP)
+					interface->status = up;	/* is up */
+
+				interface->rc_byte = ifmd.ifmd_data.ifi_ibytes;
+				interface->tr_byte = ifmd.ifmd_data.ifi_obytes;
+				interface->rc_pkt = ifmd.ifmd_data.ifi_ipackets;
+				interface->tr_pkt = ifmd.ifmd_data.ifi_opackets;
+
+				if (first_time) {
+					interface->rc_byte_old = interface->rc_byte;
+					interface->tr_byte_old = interface->tr_byte;
+					interface->rc_pkt_old = interface->rc_pkt;
+					interface->tr_pkt_old = interface->tr_pkt;
+					first_time = 0;	/* now it isn't first time */
+				}
+				return 1;
+			}
+		}
+		/* if we are here there is no interface with the given name */
+		return 0;
+	} else {
+		perror("read sysctl IFMIB_IFCOUNT");
+		return 0;
+	}
+} /* get_iface_stats() */
+
 
 #endif /* __APPLE__ */

--Apple-Mail-4--151259741
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed


--Eric


On Nov 28, 2006, at 10:35 PM, Eric Pooch wrote:

> This patch enables the lcdproc network interface (iface) stats  
> screen for Mac OS X and Darwin
>
> <machine_Darwin_iface.patch>
>
> --Eric


--Apple-Mail-4--151259741--