[Xfce4-commits] <xfce4-taskmanager:master> Add FreeBSD implementation

Mike Massonnet noreply at xfce.org
Fri May 21 13:28:01 CEST 2010


Updating branch refs/heads/master
         to 175b4cb54121f860eaca1770fc1530faa814f230 (commit)
       from b5ba8235af5ba1291568fe416a685765f82a503e (commit)

commit 175b4cb54121f860eaca1770fc1530faa814f230
Author: Mike Massonnet <mmassonnet at xfce.org>
Date:   Fri May 21 12:56:28 2010 +0200

    Add FreeBSD implementation
    
    Original code (task list) is from Oliver Lehmann and was licensed under
    FreeBSD (BSD 2-clause.)

 configure.ac.in            |    6 +-
 src/Makefile.am            |    3 +
 src/task-manager-freebsd.c |  239 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 246 insertions(+), 2 deletions(-)

diff --git a/configure.ac.in b/configure.ac.in
index 8e9e4ac..1196538 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -1,8 +1,8 @@
 dnl
 dnl xfce4-taskmanager - A small taskmanager based on the Xfce 4 libraries.
 dnl
-dnl 2005-2007 Johannes Zellner <webmaster at nebulon.de>
 dnl 2010 Mike Massonnet <mmassonnet at xfce.org>
+dnl 2005-2007 Johannes Zellner <webmaster at nebulon.de>
 
 dnl ***************************
 dnl *** Version information ***
@@ -69,7 +69,8 @@ dnl ******* Check for OS family *******
 dnl ***********************************
 case "$target_os" in
 	freebsd*)
-		AC_MSG_ERROR([Support for FreeBSD is missing])
+		ac_os_implementation="freebsd"
+		AC_CHECK_LIB([kvm], [kvm_openfiles])
 	;;
 	dragonfly*|netbsd*|openbsd*|darwin*)
 		ac_os_implementation="bsd"
@@ -91,6 +92,7 @@ esac
 AC_MSG_CHECKING([for OS implementation])
 AC_MSG_RESULT([$ac_os_implementation])
 
+AM_CONDITIONAL([OS_FREEBSD], [test x"$ac_os_implementation" = x"freebsd"])
 AM_CONDITIONAL([OS_BSD], [test x"$ac_os_implementation" = x"bsd"])
 AM_CONDITIONAL([OS_SOLARIS], [test x"$ac_os_implementation" = x"solaris"])
 AM_CONDITIONAL([OS_LINUX], [test x"$ac_os_implementation" = x"linux"])
diff --git a/src/Makefile.am b/src/Makefile.am
index b21ba1d..40a386e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,6 +24,9 @@ xfce4_taskmanager_SOURCES =						\
 	settings.c			settings.h			\
 	$(NULL)
 
+if OS_FREEBSD
+xfce4_taskmanager_SOURCES += task-manager-freebsd.c
+endif
 if OS_BSD
 xfce4_taskmanager_SOURCES += task-manager-bsd.c
 endif
diff --git a/src/task-manager-freebsd.c b/src/task-manager-freebsd.c
new file mode 100644
index 0000000..2f69fc8
--- /dev/null
+++ b/src/task-manager-freebsd.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2010  Mike Massonnet <mmassonnet at xfce.org>
+ * Copyright (c) 2006  Oliver Lehmann <oliver at FreeBSD.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <kvm.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <pwd.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "task-manager.h"
+
+gboolean
+get_memory_usage (guint64 *memory_total, guint64 *memory_free, guint64 *memory_cache, guint64 *memory_buffers, guint64 *swap_total, guint64 *swap_free)
+{
+	/* Get memory usage */
+	{
+		gulong total = 0, free = 0, inactive = 0;
+		size_t size;
+
+		size = sizeof (gulong);
+		sysctlbyname ("vm.stats.vm.v_page_count", &total, &size, NULL, 0);
+		size = sizeof (gulong);
+		sysctlbyname ("vm.stats.vm.v_free_count", &free, &size, NULL, 0);
+		size = sizeof (gulong);
+		sysctlbyname ("vm.stats.vm.v_inactive_count", &inactive, &size, NULL, 0);
+
+		*memory_total = total * getpagesize ();
+		*memory_free = free * getpagesize ();
+		*memory_cache = inactive * getpagesize ();
+		*memory_buffers = 0;
+	}
+
+	/* Get swap usage */
+	{
+		kvm_t *kd;
+		struct kvm_swap kswap;
+
+		if ((kd = kvm_openfiles (_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, NULL)) == NULL)
+			return FALSE;
+
+		kvm_getswapinfo (kd, &kswap, 1, 0);
+		*swap_total = kswap.ksw_total * getpagesize ();
+		*swap_free = (kswap.ksw_total - kswap.ksw_used) * getpagesize ();
+
+		kvm_close (kd);
+	}
+
+	return TRUE;
+}
+
+gboolean
+get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system)
+{
+	/* Get CPU count */
+	{
+		size_t len = sizeof (*cpu_count);
+		sysctlbyname ("hw.ncpu", cpu_count, &len, NULL, 0);
+	}
+
+	/* Get CPU usage */
+	{
+		static gulong cp_user = 0, cp_system = 0, cp_total = 0;
+		static gulong cp_user_old = 0, cp_system_old = 0, cp_total_old = 0;
+
+		gulong cpu_state[CPUSTATES] = { 0 };
+		size_t len = sizeof (cpu_state);
+		sysctlbyname ("kern.cp_time", &cpu_state, &len, NULL, 0);
+
+		cp_user_old = cp_user;
+		cp_system_old = cp_system;
+		cp_total_old = cp_total;
+		cp_user = cpu_state[CP_USER] + cpu_state[CP_NICE];
+		cp_system = cpu_state[CP_SYS] + cpu_state[CP_INTR];
+		cp_total = cpu_state[CP_IDLE] + cp_user + cp_system;
+
+		*cpu_user = (cp_user > cp_user_old) ? (cp_user - cp_user_old) * 100 / (gdouble)(cp_total - cp_total_old) : 0;
+		*cpu_system = (cp_system > cp_system_old) ? (cp_system - cp_system_old) * 100 / (gdouble)(cp_total - cp_total_old) : 0;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+get_task_details (kvm_t *kd, struct kinfo_proc *kp, Task *task)
+{
+	struct passwd *pw;
+	char **argv;
+	int i;
+
+	task->pid = kp->ki_pid;
+	task->ppid = kp->ki_ppid;
+	task->cpu_user = 100 * ((double)kp->ki_pctcpu / FSCALE);
+	task->cpu_system = 0;
+	task->vsz = kp->ki_size;
+	task->rss = kp->ki_rssize * getpagesize ();
+	pw = getpwuid (kp->ki_uid);
+	task->uid = kp->ki_uid;
+	g_strlcpy (task->uid_name, (pw != NULL) ? pw->pw_name : "nobody", sizeof (task->uid_name));
+	task->prio = (gushort)kp->ki_nice;
+	g_strlcpy (task->name, kp->ki_comm, 256);
+
+	task->cmdline[0] = '\0';
+	if ((argv = kvm_getargv (kd, kp, 1024)) != NULL)
+	{
+		for (i = 0; argv[i] != NULL; i++)
+		{
+			g_strlcat (task->cmdline, argv[i], 1024);
+			g_strlcat (task->cmdline, " ", 1024);
+		}
+	}
+	else
+	{
+		g_strlcpy (task->cmdline, kp->ki_comm, 1024);
+	}
+
+	i = 0;
+	switch (kp->ki_stat)
+	{
+		case SSTOP:
+		task->state[i] = 'T';
+		break;
+
+		case SSLEEP:
+		if (kp->ki_tdflags & TDF_SINTR)
+			task->state[i] = kp->ki_slptime >= MAXSLP ? 'I' : 'S';
+		else
+			task->state[i] = 'D';
+		break;
+
+		case SRUN:
+		case SIDL:
+		task->state[i] = 'R';
+		break;
+
+		case SWAIT:
+		task->state[i] = 'W';
+		break;
+
+		case SLOCK:
+		task->state[i] = 'L';
+		break;
+
+		case SZOMB:
+		task->state[i] = 'Z';
+		break;
+
+		default:
+		task->state[i] = '?';
+	}
+	i++;
+	if (!(kp->ki_sflag & PS_INMEM))
+		task->state[i++] = 'W';
+	if (kp->ki_nice < NZERO)
+		task->state[i++] = '<';
+	else if (kp->ki_nice > NZERO)
+		task->state[i++] = 'N';
+	if (kp->ki_flag & P_TRACED)
+		task->state[i++] = 'X';
+	if (kp->ki_flag & P_WEXIT && kp->ki_stat != SZOMB)
+		task->state[i++] = 'E';
+	if (kp->ki_flag & P_PPWAIT)
+		task->state[i++] = 'V';
+	if ((kp->ki_flag & P_SYSTEM) || kp->ki_lock > 0)
+		task->state[i++] = 'L';
+	if (kp->ki_kiflag & KI_SLEADER)
+		task->state[i++] = 's';
+	if ((kp->ki_flag & P_CONTROLT) && kp->ki_pgid == kp->ki_tpgid)
+		task->state[i++] = '+';
+	if (kp->ki_flag & P_JAILED)
+		task->state[i++] = 'J';
+	task->state[i] = '\0';
+
+	return TRUE;
+}
+
+gboolean
+get_task_list (GArray *task_list)
+{
+	kvm_t *kd;
+	struct kinfo_proc *kp;
+	int cnt, i;
+	Task task;
+
+	if ((kd = kvm_openfiles (_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, NULL)) == NULL)
+		return FALSE;
+
+	if ((kp = kvm_getprocs (kd, KERN_PROC_PROC, 0, &cnt)) == NULL)
+	{
+		kvm_close (kd);
+		return FALSE;
+	}
+
+	for (i = 0; i < cnt; kp++, i++)
+	{
+		get_task_details (kd, kp, &task);
+		g_array_append_val (task_list, task);
+	}
+
+	kvm_close (kd);
+
+	return TRUE;
+}
+
+gboolean
+pid_is_sleeping (guint pid)
+{
+	kvm_t *kd;
+	struct kinfo_proc *kp;
+	gint cnt;
+	gboolean ret;
+
+	if ((kd = kvm_openfiles (_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, NULL)) == NULL)
+		return FALSE;
+
+	if ((kp = kvm_getprocs (kd, KERN_PROC_PID, pid, &cnt)) == NULL)
+	{
+		kvm_close (kd);
+		return FALSE;
+	}
+
+	ret = (kp->ki_stat == SSTOP);
+	kvm_close (kd);
+
+	return ret;
+}



More information about the Xfce4-commits mailing list