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

📄 darwin.c

📁 系统任务管理器
💻 C
字号:
/* GKrellM|  Copyright (C) 1999-2006 Bill Wilson||  Author:  Bill Wilson    billw@gkrellm.net|  Latest versions might be found at:  http://gkrellm.net||  Darwin code: Ben Hines <bhines@alumni.ucsd.edu>||  This program is free software which I release under the GNU General Public|  License. You may redistribute and/or modify this program under the terms|  of that license as published by the Free Software Foundation; either|  version 2 of the License, or (at your option) any later version.||  This program is distributed in the hope that it will be useful,|  but WITHOUT ANY WARRANTY; without even the implied warranty of|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the|  GNU General Public License for more details.  Version 2 is in the|  COPYRIGHT file in the top level directory of this distribution.| |  To get a copy of the GNU General Puplic License, write to the Free Software|  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include <kvm.h>#include <mach/mach_init.h>#include <mach/mach_host.h>#include <mach/vm_map.h>kvm_t	*kvmd = NULL;char	errbuf[_POSIX2_LINE_MAX];voidgkrellm_sys_main_init(void)	{	/* We just ignore error, here.  Even if GKrellM doesn't have	|  kmem privilege, it runs with available information.	*/	kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);	if (setgid(getgid()) != 0)		{		fprintf(stderr, "Can't drop setgid privileges.");		exit(1);		}	}voidgkrellm_sys_main_cleanup(void)	{	}/* ===================================================================== *//* CPU monitor interface */static gint		n_cpus;voidgkrellm_sys_cpu_read_data(void)	{		processor_cpu_load_info_data_t *pinfo;		mach_msg_type_number_t info_count;		int i = 0;		if (host_processor_info (mach_host_self (),						   PROCESSOR_CPU_LOAD_INFO,						   &n_cpus,						   (processor_info_array_t*)&pinfo,						   &info_count)) {			return;		}        for (i = 0; i < n_cpus; i++) {			gkrellm_cpu_assign_data(i,					pinfo[i].cpu_ticks [CPU_STATE_USER],					pinfo[i].cpu_ticks [CPU_STATE_NICE],							pinfo[i].cpu_ticks [CPU_STATE_SYSTEM],					pinfo[i].cpu_ticks [CPU_STATE_IDLE]);		}		vm_deallocate (mach_task_self (), (vm_address_t) pinfo, info_count);	}gbooleangkrellm_sys_cpu_init(void)	{	processor_cpu_load_info_data_t *pinfo;	mach_msg_type_number_t info_count;	n_cpus = 0;		if (host_processor_info (mach_host_self (),						  PROCESSOR_CPU_LOAD_INFO,						  &n_cpus,						  (processor_info_array_t*)&pinfo,						  &info_count)) {		return FALSE;	}	gkrellm_cpu_set_number_of_cpus(n_cpus);	return TRUE;	}/* ===================================================================== *//* Proc monitor interface */#include <sys/sysctl.h>#include <sys/user.h>#define	PID_MAX		30000#include <kvm.h>#include <limits.h>#include <paths.h>#include <utmp.h>static int	oid_v_forks[CTL_MAXNAME + 2];static int	oid_v_vforks[CTL_MAXNAME + 2];static int	oid_v_rforks[CTL_MAXNAME + 2];static size_t	oid_v_forks_len = sizeof(oid_v_forks);static size_t	oid_v_vforks_len = sizeof(oid_v_vforks);static size_t	oid_v_rforks_len = sizeof(oid_v_rforks);static int	have_v_forks = 0;gbooleangkrellm_sys_proc_init(void)	{	static int	oid_name2oid[2] = { 0, 3 };	static char	*name = "vm.stats.vm.v_forks";	static char	*vname = "vm.stats.vm.v_vforks";	static char	*rname = "vm.stats.vm.v_rforks";	/* check if vm.stats.vm.v_forks is available */	if (sysctl(oid_name2oid, 2, oid_v_forks, &oid_v_forks_len,		   (void *)name, strlen(name)) < 0)		return TRUE;	if (sysctl(oid_name2oid, 2, oid_v_vforks, &oid_v_vforks_len,		   (void *)vname, strlen(vname)) < 0)		return TRUE;	if (sysctl(oid_name2oid, 2, oid_v_rforks, &oid_v_rforks_len,		   (void *)rname, strlen(rname)) < 0)		return TRUE;	oid_v_forks_len /= sizeof(int);	oid_v_vforks_len /= sizeof(int);	oid_v_rforks_len /= sizeof(int);	++have_v_forks;	return TRUE;	}voidgkrellm_sys_proc_read_data(void)	{	static int	oid_proc[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };	double		avenrun;	static u_int	n_processes, n_forks = 0, curpid = -1;	u_int		n_vforks, n_rforks;	gint		r_forks, r_vforks, r_rforks;	size_t		len;	gint		nextpid, nforked;	static struct nlist nl[] = {#define N_NEXTPID	0		{ "_nextpid" },		{ "" }	};	if (getloadavg(&avenrun, 1) <= 0)		avenrun = 0;	if (have_v_forks)		{		/* We don't want to just use sysctlbyname().  Because,                 * we call it so often. */		len = sizeof(n_forks);		r_forks = sysctl(oid_v_forks, oid_v_forks_len,				 &n_forks, &len, NULL, 0);		len = sizeof(n_vforks);		r_vforks = sysctl(oid_v_vforks, oid_v_vforks_len,				  &n_vforks, &len, NULL, 0);		len = sizeof(n_rforks);		r_rforks = sysctl(oid_v_rforks, oid_v_rforks_len,				  &n_rforks, &len, NULL, 0);		if (r_forks >= 0 && r_vforks >= 0 && r_rforks >= 0)			n_forks = n_forks + n_vforks + n_rforks;		}	else		{		/* workaround: Can I get total number of processes? */		if (kvmd != NULL)			{			if (nl[0].n_type == 0)				kvm_nlist(kvmd, nl);			if (nl[0].n_type != 0 &&			    kvm_read(kvmd, nl[N_NEXTPID].n_value,				     (char *)&nextpid,				     sizeof(nextpid)) == sizeof(nextpid))				{				if (curpid < 0)					curpid = nextpid;				if ((nforked = nextpid - curpid) < 0)					n_forks += PID_MAX - 100;				n_forks += nforked;				curpid = nextpid;				n_forks = n_forks;				}			}		}	if (sysctl(oid_proc, 3, NULL, &len, NULL, 0) >= 0)		n_processes = len / sizeof(struct kinfo_proc);	gkrellm_proc_assign_data(n_processes, 0, n_forks, avenrun);	}voidgkrellm_sys_proc_read_users(void)	{	gint		n_users;	struct stat	sb, s;	gchar		ttybuf[MAXPATHLEN];	FILE		*ut;	struct utmp	utmp;	static time_t	utmp_mtime;	if (stat(_PATH_UTMP, &s) != 0 || s.st_mtime == utmp_mtime)		return;	if ((ut = fopen(_PATH_UTMP, "r")) != NULL)		{		n_users = 0;		while (fread(&utmp, sizeof(utmp), 1, ut))			{			if (utmp.ut_name[0] == '\0')				continue;			(void)snprintf(ttybuf, sizeof(ttybuf), "%s/%s",				       _PATH_DEV, utmp.ut_line);			/* corrupted record */			if (stat(ttybuf, &sb))				continue;			++n_users;			}		(void)fclose(ut);		gkrellm_proc_assign_users(n_users);		}	utmp_mtime = s.st_mtime;	}/* ===================================================================== *//* Disk monitor interface */#include <CoreFoundation/CoreFoundation.h>#include <IOKit/IOKitLib.h>#include <IOKit/storage/IOBlockStorageDriver.h>io_iterator_t       drivelist  = 0;  /* needs release */mach_port_t         masterPort = 0;static GList	*disk_list;		/* list of names */gchar *gkrellm_sys_disk_name_from_device(gint device_number, gint unit_number,			gint *order)	{	return NULL;	/* Not implemented */	}gintgkrellm_sys_disk_order_from_name(gchar *name)	{	/* implement this if you want disk charts to show up in a particular	|  order in gkrellm.	*/	return -1;	/* Not implemented, disks show up in same order as disk_list */	}voidgkrellm_sys_disk_read_data(void){    io_registry_entry_t drive      = 0;  /* needs release */    UInt64         totalReadBytes  = 0;    UInt64         totalReadCount  = 0;    UInt64         totalWriteBytes = 0;    UInt64         totalWriteCount = 0;    kern_return_t status = 0;	GList		*list;	list = disk_list;     while ( (drive = IOIteratorNext(drivelist)) )    {        CFNumberRef number          = 0;  /* don't release */        CFDictionaryRef properties  = 0;  /* needs release */        CFDictionaryRef statistics  = 0;  /* don't release */        UInt64 value                = 0;            /* Obtain the properties for this drive object */                        status = IORegistryEntryCreateCFProperties (drive,                                                    (CFMutableDictionaryRef *) &properties,                                                    kCFAllocatorDefault,                                                    kNilOptions);        if (properties) {                /* Obtain the statistics from the drive properties */            statistics = (CFDictionaryRef) CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey));                if (statistics) {                /* Obtain the number of bytes read from the drive statistics */                number = (CFNumberRef) CFDictionaryGetValue (statistics,                                                            CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey));                if (number) {                        status = CFNumberGetValue(number, kCFNumberSInt64Type, &value);                        totalReadBytes += value;                }                /* Obtain the number of reads from the drive statistics */                number = (CFNumberRef) CFDictionaryGetValue (statistics,                                                            CFSTR(kIOBlockStorageDriverStatisticsReadsKey));                if (number) {                        status = CFNumberGetValue(number, kCFNumberSInt64Type, &value);                        totalReadCount += value;                }                    /* Obtain the number of writes from the drive statistics */                number = (CFNumberRef) CFDictionaryGetValue (statistics,                                                            CFSTR(kIOBlockStorageDriverStatisticsWritesKey));                if (number) {                        status = CFNumberGetValue(number, kCFNumberSInt64Type, &value);                        totalWriteCount += value;                }                /* Obtain the number of bytes written from the drive statistics */                number = (CFNumberRef) CFDictionaryGetValue (statistics,                                                            CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey));                if (number) {                        status = CFNumberGetValue(number, kCFNumberSInt64Type, &value);                        totalWriteBytes += value;                }                /* Release resources */                CFRelease(properties); properties = 0;            }        }        IOObjectRelease(drive); drive = 0;		if (list)			{			gkrellm_disk_assign_data_by_name((gchar *) list->data,					totalReadCount, totalWriteCount, FALSE);	        list = list->next;			}            }    IOIteratorReset(drivelist);}gbooleangkrellm_sys_disk_init(void)    {    io_registry_entry_t drive      = 0;  /* needs release */    io_registry_entry_t child      = 0;  /* needs release */        /* get ports and services for drive stats */    /* Obtain the I/O Kit communication handle */    if (IOMasterPort(MACH_PORT_NULL, &masterPort)) return FALSE;    /* Obtain the list of all drive objects */    if (IOServiceGetMatchingServices(masterPort,				     IOServiceMatching("IOBlockStorageDriver"),				     &drivelist))      return FALSE;    while ( (drive = IOIteratorNext(drivelist)) )    {        gchar * name = malloc(128); /* io_name_t is char[128] */	kern_return_t status = 0;        int ptr = 0;   		   		if(!name) return FALSE;   		        /* Obtain the properties for this drive object */           	status = IORegistryEntryGetChildEntry(drive, kIOServicePlane, &child );        if(!status)	status = IORegistryEntryGetName(child, name );        /* Convert spaces to underscores, for prefs safety */        if(!status)        {            for(ptr = 0; ptr < strlen(name); ptr++)             {                if(name[ptr] == ' ')                     name[ptr] = '_';            }            disk_list = g_list_append(disk_list, name);        }        IOObjectRelease(drive); drive = 0;    }    IOIteratorReset(drivelist);        return (disk_list != NULL) ? TRUE : FALSE;}/* ===================================================================== *//* Inet monitor interface - not implemented */voidgkrellm_sys_inet_read_tcp_data(void)	{	}gbooleangkrellm_sys_inet_init(void)	{	return FALSE;	}/* ===================================================================== *//* Memory/Swap monitor interface */#include <mach/mach_init.h>#include <mach/mach_host.h>#include <mach/host_info.h>#include <mach/mach_error.h>#include <sys/types.h>#include <dirent.h>#include <mach/mach_types.h>#include <mach/machine/vm_param.h>static guint64	swapin,		swapout,		swap_total,		swap_used;voidgkrellm_sys_mem_read_data(void)	{	static gint	psize, pshift, first_time_done = 0;	vm_statistics_data_t vm_info;	mach_msg_type_number_t info_count;	kern_return_t	error;	static DIR *dirp;	struct dirent *dp;	guint64		total, used, free, shared, buffers, cached;	info_count = HOST_VM_INFO_COUNT;	error = host_statistics (mach_host_self (), HOST_VM_INFO, (host_info_t)&vm_info, &info_count);	if (error != KERN_SUCCESS)	{		mach_error("host_info", error);		return;	}	if (pshift == 0)	{		for (psize = getpagesize(); psize > 1; psize >>= 1)			pshift++;	}		used = (natural_t)(vm_info.active_count + vm_info.inactive_count + vm_info.wire_count) << pshift;	free = (natural_t)vm_info.free_count << pshift;		total = (natural_t)(vm_info.active_count + vm_info.inactive_count + vm_info.free_count + vm_info.wire_count) << pshift;	/* Don't know how to get cached or buffers. */	buffers = 0;	cached = 0;	/* shared  0 for now, shared is a PITA */        shared = 0;		gkrellm_mem_assign_data(total, used, free, shared, buffers, cached);	/* Swap is available at same time as mem, so grab values here.	*/	swapin = vm_info.pageins;	swapout = vm_info.pageouts;	swap_used = vm_info.pageouts << pshift;		/* Figure out total swap. This adds up the size of the swapfiles */	if (!first_time_done)	{		dirp = opendir ("/private/var/vm");		if (!dirp)			return;		++first_time_done;	}	swap_total = 0;	while ((dp = readdir (dirp)) != NULL) {		struct stat sb;		char fname [MAXNAMLEN];		if (strncmp (dp->d_name, "swapfile", 8))			continue;		strcpy (fname, "/private/var/vm/");		strcat (fname, dp->d_name);		if (stat (fname, &sb) < 0)			continue;		swap_total += sb.st_size;	}	/*  Save overhead, leave it open. where can we close it? */	rewinddir(dirp);	/*	closedir (dirp); */	}voidgkrellm_sys_swap_read_data(void)	{	gkrellm_swap_assign_data(swap_total, swap_used, swapin, swapout);	}gbooleangkrellm_sys_mem_init(void)	{	return TRUE;	}/* ===================================================================== *//* Battery monitor interface - not implemented */voidgkrellm_sys_battery_read_data(void)	{//	gkrellm_battery_assign_data(0, available, on_line, charging,//					percent, time_left);	}gbooleangkrellm_sys_battery_init(void)	{	return FALSE;	}/* ===================================================================== *//* Sensor monitor interface - not implemented */gbooleangkrellm_sys_sensors_get_temperature(gchar *path, gint id,		gint iodev, gint interface, gfloat *temp)	{	return FALSE;	}gbooleangkrellm_sys_sensors_get_fan(gchar *path, gint id,		gint iodev, gint interface, gfloat *fan)	{	return FALSE;	}gbooleangkrellm_sys_sensors_get_voltage(gchar *path, gint id,		gint iodev, gint interface, gfloat *volt)	{	return FALSE;	}gbooleangkrellm_sys_sensors_init(void)	{	return FALSE;	}

⌨️ 快捷键说明

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