libgtop r2767 - in trunk: . sysdeps/freebsd



Author: bdejean
Date: Mon Aug 18 16:11:07 2008
New Revision: 2767
URL: http://svn.gnome.org/viewvc/libgtop?rev=2767&view=rev

Log:
Improved freebsd port.
Patch by Joe Marcus Clarke <marcus freebsd org>.
Closes #548184.


Added:
   trunk/sysdeps/freebsd/mountlist.c
   trunk/sysdeps/freebsd/procaffinity.c
Modified:
   trunk/libgtop-sysdeps.m4
   trunk/sysdeps/freebsd/Makefile.am
   trunk/sysdeps/freebsd/fsusage.c
   trunk/sysdeps/freebsd/glibtop_server.h
   trunk/sysdeps/freebsd/procmap.c
   trunk/sysdeps/freebsd/procopenfiles.c
   trunk/sysdeps/freebsd/procwd.c
   trunk/sysdeps/freebsd/shm_limits.c

Modified: trunk/libgtop-sysdeps.m4
==============================================================================
--- trunk/libgtop-sysdeps.m4	(original)
+++ trunk/libgtop-sysdeps.m4	Mon Aug 18 16:11:07 2008
@@ -79,6 +79,8 @@
 	  libgtop_sysdeps_dir=freebsd
 	  libgtop_use_machine_h=yes
 	  libgtop_need_server=yes
+	  libgtop_sysdeps_private_mountlist=yes
+	  libgtop_sysdeps_private_fsusage=yes
 	  libgtop_postinstall='chgrp kmem $(bindir)/libgtop_server2 && chmod 2755 $(bindir)/libgtop_server2'
 	  ;;
 	solaris*)

Modified: trunk/sysdeps/freebsd/Makefile.am
==============================================================================
--- trunk/sysdeps/freebsd/Makefile.am	(original)
+++ trunk/sysdeps/freebsd/Makefile.am	Mon Aug 18 16:11:07 2008
@@ -6,8 +6,8 @@
 libgtop_sysdeps_2_0_la_SOURCES	= nosuid.c siglist.c sysinfo.c shm_limits.c \
 				  cpu.c msg_limits.c sem_limits.c loadavg.c \
 				  uptime.c netlist.c fsusage.c mem.c \
-				  procopenfiles.c procwd.c \
-				  glibtop_private.c
+				  mountlist.c procopenfiles.c procwd.c \
+				  procaffinity.c glibtop_private.c
 
 libgtop_sysdeps_2_0_la_LDFLAGS	= $(LT_VERSION_INFO)
 

Modified: trunk/sysdeps/freebsd/fsusage.c
==============================================================================
--- trunk/sysdeps/freebsd/fsusage.c	(original)
+++ trunk/sysdeps/freebsd/fsusage.c	Mon Aug 18 16:11:07 2008
@@ -10,6 +10,7 @@
 #include <unistd.h>
 #include <sys/param.h>
 #include <sys/mount.h>
+#include <sys/statvfs.h>
 #if __FreeBSD_version >= 600000 || defined(__FreeBSD_kernel__)
 #include <libgeom.h>
 #include <sys/resource.h>
@@ -21,15 +22,13 @@
 #include <string.h>
 #include <stdlib.h>
 
-void
-_glibtop_freebsd_get_fsusage_read_write(glibtop *server,
-                                        glibtop_fsusage *buf,
-                                        const char *path);
+static const unsigned long _glibtop_sysdeps_fsusage =
+(1L << GLIBTOP_FSUSAGE_BLOCKS) + (1L << GLIBTOP_FSUSAGE_BFREE)
++ (1L << GLIBTOP_FSUSAGE_BAVAIL) + (1L << GLIBTOP_FSUSAGE_FILES)
++ (1L << GLIBTOP_FSUSAGE_FFREE) + (1L << GLIBTOP_FSUSAGE_BLOCK_SIZE);
 
-void
-_glibtop_freebsd_get_fsusage_read_write(glibtop *server,
-                                        glibtop_fsusage *buf,
-                                        const char *path)
+static void
+_glibtop_get_fsusage_read_write (glibtop *server, glibtop_fsusage *buf, const char *path)
 {
         int result;
         struct statfs sfs;
@@ -135,3 +134,28 @@
 #endif
         buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
 }
+
+void
+glibtop_get_fsusage_s(glibtop *server, glibtop_fsusage *buf, const char *path)
+{
+	struct statvfs fsd;
+
+	glibtop_init_r (&server, 0, 0);
+
+	memset (buf, 0, sizeof (glibtop_fsusage));
+
+	if (statvfs (path, &fsd) < 0)
+		return;
+
+	buf->block_size = fsd.f_frsize;
+	buf->blocks = fsd.f_blocks;
+	buf->bfree  = fsd.f_bfree;
+	buf->bavail = (fsd.f_bavail > fsd.f_bfree) ? 0 : fsd.f_bavail;
+	buf->files  = fsd.f_files;
+	buf->ffree  = fsd.f_ffree;
+
+	buf->flags = _glibtop_sysdeps_fsusage;
+
+	_glibtop_get_fsusage_read_write(server, buf, path);
+}
+

Modified: trunk/sysdeps/freebsd/glibtop_server.h
==============================================================================
--- trunk/sysdeps/freebsd/glibtop_server.h	(original)
+++ trunk/sysdeps/freebsd/glibtop_server.h	Mon Aug 18 16:11:07 2008
@@ -46,6 +46,7 @@
 #define GLIBTOP_SUID_SEM_LIMITS		0
 #define GLIBTOP_SUID_NETLIST		0
 #define GLIBTOP_SUID_PROC_WD		0
+#define GLIBTOP_SUID_PROC_AFFINITY	0
 
 G_END_DECLS
 

Added: trunk/sysdeps/freebsd/mountlist.c
==============================================================================
--- (empty file)
+++ trunk/sysdeps/freebsd/mountlist.c	Mon Aug 18 16:11:07 2008
@@ -0,0 +1,168 @@
+/* mountlist.c -- return a list of mounted filesystems
+   Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+   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, 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <config.h>
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+
+#include <string.h>
+
+#include <glibtop.h>
+#include <glibtop/mountlist.h>
+
+/* A mount table entry. */
+struct mount_entry
+{
+  char *me_devname;             /* Device node pathname, including "/dev/". */
+  char *me_mountdir;            /* Mount point directory pathname. */
+  char *me_type;                /* "nfs", "4.2", etc. */
+  dev_t me_dev;                 /* Device number of me_mountdir. */
+  struct mount_entry *me_next;
+};
+
+static struct mount_entry *read_filesystem_list (void);
+
+/* Return a list of the currently mounted filesystems, or NULL on error.
+   Add each entry to the tail of the list so that they stay in order.
+*/
+
+static struct mount_entry *
+read_filesystem_list (void)
+{
+  struct mount_entry *mount_list;
+  struct mount_entry *me;
+  struct mount_entry *mtail;
+
+  /* Start the list off with a dummy entry. */
+  me = g_new (struct mount_entry, 1);
+  me->me_next = NULL;
+  mount_list = mtail = me;
+  {
+    struct statfs *fsp;
+    int entries;
+
+    entries = getmntinfo (&fsp, MNT_NOWAIT);
+    if (entries < 0)
+      return NULL;
+    while (entries-- > 0)
+      {
+	me = (struct mount_entry *) g_malloc (sizeof (struct mount_entry));
+	me->me_devname = g_strdup (fsp->f_mntfromname);
+	me->me_mountdir = g_strdup (fsp->f_mntonname);
+	me->me_type = g_strdup (fsp->f_fstypename);
+	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */
+	me->me_next = NULL;
+
+	/* Add to the linked list. */
+	mtail->me_next = me;
+	mtail = me;
+	fsp++;
+      }
+  }
+
+  /* Free the dummy head. */
+  me = mount_list;
+  mount_list = mount_list->me_next;
+  g_free (me);
+  return mount_list;
+}
+
+static gboolean ignore_mount_entry(const struct mount_entry *me)
+{
+	/* keep sorted */
+	static const char ignored[][17] = {
+		"autofs",
+		"devfs",
+		"fusectl",
+		"linprocfs",
+		"linsysfs",
+		"mfs",
+		"none",
+		"nfs",
+		"nullfs",
+		"nwfs",
+		"portalfs",
+		"proc",
+		"procfs",
+		"smbfs",
+		"tmpfs",
+		"unionfs",
+		"unknown"
+	};
+
+	typedef int (*Comparator)(const void*, const void*);
+
+	return bsearch(me->me_type,
+		       ignored, G_N_ELEMENTS(ignored), sizeof ignored[0],
+		       (Comparator) strcmp) != NULL;
+}
+
+
+glibtop_mountentry *
+glibtop_get_mountlist_s (glibtop *server, glibtop_mountlist *buf, int all_fs)
+{
+	struct mount_entry *entries, *cur, *next;
+
+	GArray *mount_array = g_array_new(FALSE, FALSE,
+					  sizeof(glibtop_mountentry));
+
+	glibtop_init_r (&server, 0, 0);
+
+	memset (buf, 0, sizeof (glibtop_mountlist));
+
+	/* Read filesystem list. */
+
+	if((entries = read_filesystem_list ()) == NULL)
+		return NULL;
+
+	for (cur = &entries[0]; cur != NULL; cur = next) {
+
+		if(all_fs || !ignore_mount_entry(cur)) {
+			/* add a new glibtop_mountentry */
+			glibtop_mountentry e;
+
+			g_strlcpy(e.devname,  cur->me_devname,  sizeof e.devname);
+			g_strlcpy(e.mountdir, cur->me_mountdir, sizeof e.mountdir);
+			g_strlcpy(e.type,     cur->me_type,     sizeof e.type);
+			e.dev = cur->me_dev;
+
+			g_array_append_val(mount_array, e);
+		}
+
+		/* free current mount_entry and move to the next */
+		next = cur->me_next;
+		g_free(cur->me_devname);
+		g_free(cur->me_mountdir);
+		g_free(cur->me_type);
+		g_free(cur);
+	}
+
+	buf->size   = sizeof (glibtop_mountentry);
+	buf->number = mount_array->len;
+	buf->total  = buf->number * buf->size;
+
+	buf->flags  = (1 << GLIBTOP_MOUNTLIST_SIZE)
+	  | (1 << GLIBTOP_MOUNTLIST_NUMBER)
+	  | (1 << GLIBTOP_MOUNTLIST_TOTAL);
+
+	return (glibtop_mountentry*) g_array_free(mount_array, FALSE);
+}

Added: trunk/sysdeps/freebsd/procaffinity.c
==============================================================================
--- (empty file)
+++ trunk/sysdeps/freebsd/procaffinity.c	Mon Aug 18 16:11:07 2008
@@ -0,0 +1,84 @@
+/* Copyright (C) 2007 Joe Marcus Clarke <marcus FreeBSD org>
+   This file is part of LibGTop 2.
+
+   LibGTop 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.
+
+   LibGTop 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.
+
+   You should have received a copy of the GNU General Public License
+   along with LibGTop; see the file COPYING. If not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+#include <glibtop/procaffinity.h>
+#include <glibtop/error.h>
+
+#include <glibtop_private.h>
+
+#include <sys/param.h>
+#if __FreeBSD_version > 800024
+#include <sys/cpuset.h>
+#endif
+
+void
+_glibtop_init_proc_affinity_s(glibtop *server)
+{
+  server->sysdeps.proc_affinity =
+    (1 << GLIBTOP_PROC_AFFINITY_NUMBER) |
+    (1 << GLIBTOP_PROC_AFFINITY_ALL);
+
+}
+
+
+guint16 *
+glibtop_get_proc_affinity_s(glibtop *server, glibtop_proc_affinity *buf, pid_t pid)
+{
+#if __FreeBSD_version > 800024
+  id_t id;
+  cpulevel_t level;
+  cpuwhich_t which;
+  cpuset_t mask;
+  size_t i;
+  GArray* cpus;
+
+  memset(buf, 0, sizeof *buf);
+
+  which = CPU_WHICH_PID;
+  level = CPU_LEVEL_WHICH;
+  id = pid;
+
+  if (cpuset_getaffinity(level, which, id, sizeof(mask), &mask) != 0) {
+    glibtop_error_r(server, "cpuset_getaffinity failed");
+    return NULL;
+  }
+
+  cpus = g_array_new(FALSE, FALSE, sizeof(guint16));
+
+  for (i = 0; i < MIN(CPU_SETSIZE, (size_t)(server->ncpu + 1)); i++) {
+    if (CPU_ISSET(i, &mask)) {
+      guint16 n = i;
+      g_array_append_val(cpus, n);
+    }
+  }
+
+  buf->number = cpus->len;
+  buf->all = (cpus->len == (size_t)(server->ncpu + 1));
+  buf->flags = (1 << GLIBTOP_PROC_AFFINITY_NUMBER)
+    | (1 << GLIBTOP_PROC_AFFINITY_ALL);
+
+  return (guint16*) g_array_free(cpus, FALSE);
+#else
+  memset(buf, 0, sizeof *buf);
+
+  return NULL;
+#endif
+}
+

Modified: trunk/sysdeps/freebsd/procmap.c
==============================================================================
--- trunk/sysdeps/freebsd/procmap.c	(original)
+++ trunk/sysdeps/freebsd/procmap.c	Mon Aug 18 16:11:07 2008
@@ -41,7 +41,17 @@
 #define _KERNEL
 #include <sys/pipe.h>
 #include <sys/conf.h>
+#undef _KERNEL
+#if __FreeBSD_version >= 800038
+#define _WANT_FILE
 #include <sys/file.h>
+#undef _WANT_FILE
+#else
+#define _KERNEL
+#include <sys/file.h>
+#undef _KERNEL
+#endif
+#define _KERNEL
 #include <sys/mount.h>
 #include <ufs/ufs/quota.h>
 #include <ufs/ufs/inode.h>
@@ -103,8 +113,14 @@
 
         if (kvm_read (server->machine.kd, (gulong) inode.i_dev, (char *) &si,
 	              sizeof (si)) != sizeof (si) ||
+#if __FreeBSD_version >= 800039
+            kvm_read (server->machine.kd, (gulong)  cdev2priv(&si), (char *) &priv,
+		      sizeof (priv))
+#else
             kvm_read (server->machine.kd, (gulong) si.si_priv, (char *) &priv,
-		      sizeof (priv)) != sizeof (priv))
+		      sizeof (priv))
+#endif
+	    != sizeof (priv))
         {
                 glibtop_warn_io_r (server, "kvm_read (si)");
                 return;

Modified: trunk/sysdeps/freebsd/procopenfiles.c
==============================================================================
--- trunk/sysdeps/freebsd/procopenfiles.c	(original)
+++ trunk/sysdeps/freebsd/procopenfiles.c	Mon Aug 18 16:11:07 2008
@@ -28,6 +28,13 @@
 #include <glibtop/error.h>
 #include <glibtop/procopenfiles.h>
 #include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/un.h>
+#include <sys/user.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include <string.h>
 #include <stdlib.h>
 
@@ -46,6 +53,63 @@
 	server->sysdeps.proc_open_files = _glibtop_sysdeps_proc_open_files;
 }
 
+#if __FreeBSD_version > 800018 || (__FreeBSD_version < 800000 && __FreeBSD_version >= 700104)
+static char *
+addr_to_string(struct sockaddr_storage *ss)
+{
+	char *buffer = NULL;
+	char buffer2[INET6_ADDRSTRLEN];
+	struct sockaddr_in6 *sin6;
+	struct sockaddr_in *sin;
+	struct sockaddr_un *sun;
+
+	switch (ss->ss_family) {
+		case AF_LOCAL:
+			sun = (struct sockaddr_un *)ss;
+			if (strlen(sun->sun_path) == 0)
+				buffer = g_strdup("-");
+			else
+				buffer = g_strdup(sun->sun_path);
+			break;
+		case AF_INET:
+			sin = (struct sockaddr_in *)ss;
+			buffer = g_strdup(inet_ntoa(sin->sin_addr));
+			break;
+		case AF_INET6:
+			sin6 = (struct sockaddr_in6 *)ss;
+			if (inet_ntop(AF_INET6, &sin6->sin6_addr, buffer2,
+			    sizeof(buffer2)) != NULL)
+				buffer = g_strdup(buffer2);
+			else
+				buffer = g_strdup("-");
+			break;
+	}
+
+	return buffer;
+}
+
+static int
+addr_to_port(struct sockaddr_storage *ss)
+{
+	int port = 0;
+	struct sockaddr_in6 *sin6;
+	struct sockaddr_in *sin;
+
+	switch (ss->ss_family) {
+		case AF_INET:
+			sin = (struct sockaddr_in *)ss;
+			port = ntohs(sin->sin_port);
+			break;
+		case AF_INET6:
+			sin6 = (struct sockaddr_in6 *)ss;
+			port = ntohs(sin6->sin6_port);
+			break;
+	}
+
+	return port;
+}
+#else
+
 static GArray *
 parse_output(const char *output) {
 	GArray *entries;
@@ -143,6 +207,39 @@
 			entry.info.sock.dest_port = atoi(remote_host[1]);
 
 			g_strfreev(remote_host);
+		} else if (!strcmp(ftype, "IPv6")) {
+			char **hosts;
+			char **remote_host;
+
+			if (!strstr(fname, "->")) {
+				remote_host = g_strsplit(fname, ":", 0);
+			} else {
+				hosts = g_strsplit(fname, "->", 0);
+				if (g_strv_length(hosts) < 2) {
+					g_strfreev(hosts);
+					continue;
+				}
+
+				remote_host = g_strsplit(hosts[1], "]", 0);
+				g_strfreev(hosts);
+			}
+
+			if (g_strv_length(remote_host) < 2) {
+				g_strfreev(remote_host);
+				continue;
+			}
+
+			entry.type = GLIBTOP_FILE_TYPE_INET6SOCKET;
+			if (!strcmp(remote_host[0], "*"))
+				g_strlcpy(entry.info.sock.dest_host, "0.0.0.0",
+					  sizeof(entry.info.sock.dest_host));
+			else
+				g_strlcpy(entry.info.sock.dest_host,
+					  remote_host[0] + 1,
+					  sizeof(entry.info.sock.dest_host));
+			entry.info.sock.dest_port = atoi(remote_host[1] + 1);
+
+			g_strfreev(remote_host);
 		} else
 			continue;
 
@@ -159,21 +256,108 @@
 
 	return entries;
 }
+#endif
 
 glibtop_open_files_entry *
 glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf,	pid_t pid)
 {
+#if __FreeBSD_version > 800018 || (__FreeBSD_version < 800000 && __FreeBSD_version >= 700104)
+	struct kinfo_file *freep, *kif;
+	int name[4];
+	size_t len;
+	size_t i;
+#else
 	char *output;
+#endif
 	GArray *entries;
 
 	memset(buf, 0, sizeof (glibtop_proc_open_files));
 
+#if __FreeBSD_version > 800018 || (__FreeBSD_version < 800000 && __FreeBSD_version >= 700104)
+	name[0] = CTL_KERN;
+	name[1] = KERN_PROC;
+	name[2] = KERN_PROC_FILEDESC;
+	name[3] = pid;
+
+	if (sysctl(name, 4, NULL, &len, NULL, 0) < 0)
+		return NULL;
+
+	freep = kif = g_malloc(len);
+	if (sysctl(name, 4, kif, &len, NULL, 0) < 0) {
+		g_free(freep);
+		return NULL;
+	}
+
+	entries = g_array_new(FALSE, FALSE, sizeof(glibtop_open_files_entry));
+
+	for (i = 0; i < len / sizeof(*kif); i++, kif++) {
+		glibtop_open_files_entry entry = {0};
+
+		if (kif->kf_fd < 0)
+			continue;
+
+		if (kif->kf_type == KF_TYPE_SOCKET) {
+			if (kif->kf_sock_domain == AF_LOCAL) {
+				struct sockaddr_un *sun;
+
+				entry.type = GLIBTOP_FILE_TYPE_LOCALSOCKET;
+				sun = (struct sockaddr_un *)&kif->kf_sa_local;
+
+				if (sun->sun_path[0]) {
+					char *addrstr;
+
+					addrstr = addr_to_string(&kif->kf_sa_local);
+					g_strlcpy(entry.info.localsock.name,
+						  addrstr,
+						  sizeof(entry.info.localsock.name));
+					g_free(addrstr);
+				} else {
+					char *addrstr;
+
+					addrstr = addr_to_string(&kif->kf_sa_peer);
+					g_strlcpy(entry.info.localsock.name,
+						  addrstr,
+						  sizeof(entry.info.localsock.name));
+					g_free(addrstr);
+				}
+			} else if (kif->kf_sock_domain == AF_INET ||
+				   kif->kf_sock_domain == AF_INET6) {
+				char *addrstr;
+
+				if (kif->kf_sock_domain == AF_INET)
+					entry.type = GLIBTOP_FILE_TYPE_INETSOCKET;
+				else
+					entry.type = GLIBTOP_FILE_TYPE_INET6SOCKET;
+				addrstr = addr_to_string(&kif->kf_sa_peer);
+				g_strlcpy(entry.info.sock.dest_host,
+					  addrstr,
+					  sizeof(entry.info.sock.dest_host));
+				g_free(addrstr);
+				entry.info.sock.dest_port = addr_to_port(&kif->kf_sa_peer);
+			}
+		} else if (kif->kf_type == KF_TYPE_PIPE) {
+			entry.type = GLIBTOP_FILE_TYPE_PIPE;
+		} else if (kif->kf_type == KF_TYPE_VNODE) {
+			entry.type = GLIBTOP_FILE_TYPE_FILE;
+			g_strlcpy(entry.info.file.name, kif->kf_path,
+				  sizeof(entry.info.file.name));
+		} else
+			continue;
+
+		entry.fd = kif->kf_fd;
+
+		g_array_append_val(entries, entry);
+	}
+	g_free(freep);
+#else
+
 	output = execute_lsof(pid);
 	if (output == NULL) return NULL;
 
 	entries = parse_output(output);
 
 	g_free(output);
+#endif
 
 	buf->flags = _glibtop_sysdeps_proc_open_files;
 	buf->number = entries->len;

Modified: trunk/sysdeps/freebsd/procwd.c
==============================================================================
--- trunk/sysdeps/freebsd/procwd.c	(original)
+++ trunk/sysdeps/freebsd/procwd.c	Mon Aug 18 16:11:07 2008
@@ -24,7 +24,9 @@
 #include <glibtop_private.h>
 
 #include <sys/types.h>
+#include <sys/sysctl.h>
 #include <sys/param.h>
+#include <sys/user.h>
 #include <string.h>
 
 static const unsigned long _glibtop_sysdeps_proc_wd =
@@ -38,6 +40,7 @@
 	server->sysdeps.proc_wd = _glibtop_sysdeps_proc_wd;
 }
 
+#if (__FreeBSD_version >= 800000 && __FreeBSD_version < 800019) || _FreeBSD_version < 700104
 static GPtrArray *
 parse_output(const char *output, glibtop_proc_wd *buf)
 {
@@ -89,12 +92,21 @@
 
 	return dirs;
 }
+#endif
 
 char**
 glibtop_get_proc_wd_s(glibtop *server, glibtop_proc_wd *buf, pid_t pid)
 {
 	char path[MAXPATHLEN];
+#if __FreeBSD_version > 800018 || (__FreeBSD_version < 800000 && __FreeBSD_version >= 700104)
+	struct kinfo_file *freep, *kif;
+	GPtrArray *dirs;
+	size_t len;
+	int i;
+	int name[4];
+#else
 	char *output;
+#endif
 
 	memset (buf, 0, sizeof (glibtop_proc_wd));
 
@@ -102,6 +114,43 @@
 	if (safe_readlink(path, buf->exe, sizeof(buf->exe)))
 		buf->flags |= (1 << GLIBTOP_PROC_WD_EXE);
 
+#if __FreeBSD_version > 800018 || (__FreeBSD_version < 800000 && __FreeBSD_version >= 700104)
+	name[0] = CTL_KERN;
+	name[1] = KERN_PROC;
+	name[2] = KERN_PROC_FILEDESC;
+	name[3] = pid;
+
+	if (sysctl(name, 4, NULL, &len, NULL, 0) < 0)
+		return NULL;
+	freep = kif = g_malloc(len);
+	if (sysctl(name, 4, kif, &len, NULL, 0) < 0) {
+		g_free(freep);
+		return NULL;
+	}
+
+	dirs = g_ptr_array_sized_new(1);
+
+	for (i = 0; i < len / sizeof(*kif); i++, kif++) {
+		switch (kif->kf_fd) {
+			case KF_FD_TYPE_ROOT:
+				g_strlcpy(buf->root, kif->kf_path,
+					   sizeof(buf->root));
+				buf->flags |= (1 << GLIBTOP_PROC_WD_ROOT);
+				break;
+			case KF_FD_TYPE_CWD:
+				g_ptr_array_add(dirs, g_strdup (kif->kf_path));
+				break;
+		}
+	}
+	g_free(freep);
+
+	buf->number = dirs->len;
+	buf->flags |= (1 << GLIBTOP_PROC_WD_NUMBER);
+
+	g_ptr_array_add(dirs, NULL);
+
+	return (char **)g_ptr_array_free(dirs, FALSE);
+#else
 	output = execute_lsof(pid);
 	if (output != NULL) {
 		GPtrArray *dirs;
@@ -116,6 +165,7 @@
 
 		return (char **)g_ptr_array_free(dirs, FALSE);
 	}
+#endif
 
 	return NULL;
 }

Modified: trunk/sysdeps/freebsd/shm_limits.c
==============================================================================
--- trunk/sysdeps/freebsd/shm_limits.c	(original)
+++ trunk/sysdeps/freebsd/shm_limits.c	Mon Aug 18 16:11:07 2008
@@ -25,6 +25,7 @@
 #include <glibtop/shm_limits.h>
 
 #include <sys/types.h>
+#include <sys/param.h>
 #include <sys/sysctl.h>
 
 static unsigned long _glibtop_sysdeps_shm_limits =
@@ -46,7 +47,11 @@
 glibtop_get_shm_limits_s (glibtop *server, glibtop_shm_limits *buf)
 {
 	size_t len;
+#if __FreeBSD_version < 700002
 	int shmmax, shmmin, shmmni, shmseg, shmall;
+#else
+	unsigned long shmmax, shmmin, shmmni, shmseg, shmall;
+#endif
 
 	glibtop_init_s (&server, GLIBTOP_SYSDEPS_SHM_LIMITS, 0);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]