[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