summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorAntoine Jacoutot <ajacoutot@gnome.org>2014-02-03 10:56:02 +0100
committerAntoine Jacoutot <ajacoutot@gnome.org>2014-02-03 10:59:05 +0100
commit4cd3e4fed692dae5b1f238ac11ca03bf044e350e (patch)
tree681effbc51588905b631c69b05857d9b7c5c2fef /sysdeps
parentc99ceeaa65a5482db2b5b3b677a8c4b40acc8eb8 (diff)
downloadlibgtop-4cd3e4fed692dae5b1f238ac11ca03bf044e350e.tar.gz
openbsd: merge patches from ports tree
Bring OpenBSD closer to FreeBSD to help checking what is missing/different. Also we make sure to use and build mountlist and fsusage from the sysdeps/openbsd directory instead of the common one. https://bugzilla.gnome.org/show_bug.cgi?id=723521
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/openbsd/Makefile.am23
-rw-r--r--sysdeps/openbsd/cpu.c4
-rw-r--r--sysdeps/openbsd/fsusage.c80
-rw-r--r--sysdeps/openbsd/glibtop_server.h10
-rw-r--r--sysdeps/openbsd/loadavg.c4
-rw-r--r--sysdeps/openbsd/mem.c15
-rw-r--r--sysdeps/openbsd/mountlist.c168
-rw-r--r--sysdeps/openbsd/nosuid.c8
-rw-r--r--sysdeps/openbsd/open.c64
-rw-r--r--sysdeps/openbsd/procaffinity.c2
-rw-r--r--sysdeps/openbsd/prockernel.c38
-rw-r--r--sysdeps/openbsd/procmap.c18
-rw-r--r--sysdeps/openbsd/proctime.c53
-rw-r--r--sysdeps/openbsd/procwd.c52
-rw-r--r--sysdeps/openbsd/suid_open.c92
-rw-r--r--sysdeps/openbsd/uptime.c6
16 files changed, 376 insertions, 261 deletions
diff --git a/sysdeps/openbsd/Makefile.am b/sysdeps/openbsd/Makefile.am
index cfa84f40..0c9f5278 100644
--- a/sysdeps/openbsd/Makefile.am
+++ b/sysdeps/openbsd/Makefile.am
@@ -2,18 +2,23 @@ INCLUDES = @INCLUDES@
noinst_LTLIBRARIES = libgtop_sysdeps-2.0.la libgtop_sysdeps_suid-2.0.la
-libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c sysinfo.c
+libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c sysinfo.c \
+ cpu.c loadavg.c \
+ uptime.c netlist.c fsusage.c mem.c \
+ mountlist.c procopenfiles.c procwd.c \
+ procaffinity.c glibtop_private.c open.c
libgtop_sysdeps_2_0_la_LDFLAGS = $(LT_VERSION_INFO)
-libgtop_sysdeps_suid_2_0_la_LIBADD = $(KVM_LIBS)
-libgtop_sysdeps_suid_2_0_la_SOURCES = open.c close.c cpu.c mem.c swap.c \
- uptime.c loadavg.c shm_limits.c msg_limits.c \
- sem_limits.c proclist.c procstate.c procuid.c \
- proctime.c procmem.c procsignal.c prockernel.c \
- procsegment.c procargs.c procmap.c netlist.c \
- netload.c ppp.c procopenfiles.c fsusage.c \
- procwd.c procaffinity.c glibtop_private.c
+libgtop_sysdeps_suid_2_0_la_LIBADD = $(KVM_LIBS) $(EXTRA_SYSDEPS_LIBS)
+libgtop_sysdeps_suid_2_0_la_SOURCES = suid_open.c close.c swap.c \
+ proclist.c procstate.c procuid.c \
+ proctime.c procmem.c procsignal.c \
+ prockernel.c procsegment.c procargs.c \
+ procmap.c netload.c ppp.c
+
+# TODO should be made nosuid like FreeBSD
+libgtop_sysdeps_suid_2_0_la_SOURCES += shm_limits.c msg_limits.c sem_limits.c
libgtop_sysdeps_suid_2_0_la_LDFLAGS = $(LT_VERSION_INFO)
diff --git a/sysdeps/openbsd/cpu.c b/sysdeps/openbsd/cpu.c
index 533e04bf..5560a3bb 100644
--- a/sysdeps/openbsd/cpu.c
+++ b/sysdeps/openbsd/cpu.c
@@ -42,7 +42,7 @@ static int mib2 [] = { CTL_KERN, KERN_CPTIME };
/* Init function. */
void
-_glibtop_init_cpu_p (glibtop *server)
+_glibtop_init_cpu_s (glibtop *server)
{
server->sysdeps.cpu = _glibtop_sysdeps_cpu;
}
@@ -50,7 +50,7 @@ _glibtop_init_cpu_p (glibtop *server)
/* Provides information about cpu usage. */
void
-glibtop_get_cpu_p (glibtop *server, glibtop_cpu *buf)
+glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf)
{
gulong cpts [CPUSTATES];
diff --git a/sysdeps/openbsd/fsusage.c b/sysdeps/openbsd/fsusage.c
index 7abafe6e..832d036d 100644
--- a/sysdeps/openbsd/fsusage.c
+++ b/sysdeps/openbsd/fsusage.c
@@ -1,13 +1,4 @@
#include <config.h>
-
-/*
- * statvfs is lacking various members which are present in statfs,
- * like f_(a)syncreads and f_(a)syncwrites. So eventhough we have
- * statvfs, undef it here untill those members are added.
- */
-#undef HAVE_SYS_STATVFS_H
-#undef STAT_STATVFS
-
#include <glibtop.h>
#include <glibtop/error.h>
#include <glibtop/fsusage.h>
@@ -18,44 +9,57 @@
#include <unistd.h>
#include <sys/param.h>
-#if defined (HAVE_SYS_STATVFS_H)
-#include <sys/statvfs.h>
-#else
#include <sys/mount.h>
-#endif
+#include <sys/statvfs.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-void
-_glibtop_openbsd_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);
+
+static void
+_glibtop_get_fsusage_read_write (glibtop *server, glibtop_fsusage *buf, const char *path)
+{
+ int result;
+ struct statfs sfs;
+
+ result = statfs (path, &sfs);
+
+ if (result == -1) {
+ glibtop_warn_io_r (server, "statfs");
+ return;
+ }
+
+ buf->read = sfs.f_syncreads + sfs.f_asyncreads;
+ buf->write = sfs.f_syncwrites + sfs.f_asyncwrites;
+ buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
+}
void
-_glibtop_openbsd_get_fsusage_read_write(glibtop *server,
- glibtop_fsusage *buf,
- const char *path)
+glibtop_get_fsusage_s(glibtop *server, glibtop_fsusage *buf, const char *path)
{
- int result;
-#if defined (STAT_STATVFS)
- struct statvfs sfs;
-#else
- struct statfs sfs;
-#endif
-
-#if defined (STAT_STATVFS)
- result = statvfs (path, &sfs);
-#else
- result = statfs (path, &sfs);
-#endif
-
- if (result == -1) {
+ struct statvfs fsd;
+
+ glibtop_init_r (&server, 0, 0);
+
+ memset (buf, 0, sizeof (glibtop_fsusage));
+
+ if (statvfs (path, &fsd) < 0)
return;
- }
- buf->read = sfs.f_syncreads + sfs.f_asyncreads;
- buf->write = sfs.f_syncwrites + sfs.f_asyncwrites;
- buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
+ 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);
}
+
diff --git a/sysdeps/openbsd/glibtop_server.h b/sysdeps/openbsd/glibtop_server.h
index 3db000e3..f93ffddb 100644
--- a/sysdeps/openbsd/glibtop_server.h
+++ b/sysdeps/openbsd/glibtop_server.h
@@ -24,11 +24,7 @@
G_BEGIN_DECLS
-#define GLIBTOP_SUID_CPU (1 << GLIBTOP_SYSDEPS_CPU)
-#define GLIBTOP_SUID_MEM (1 << GLIBTOP_SYSDEPS_MEM)
#define GLIBTOP_SUID_SWAP (1 << GLIBTOP_SYSDEPS_SWAP)
-#define GLIBTOP_SUID_UPTIME (1 << GLIBTOP_SYSDEPS_UPTIME)
-#define GLIBTOP_SUID_LOADAVG (1 << GLIBTOP_SYSDEPS_LOADAVG)
#define GLIBTOP_SUID_SHM_LIMITS (1 << GLIBTOP_SYSDEPS_SHM_LIMITS)
#define GLIBTOP_SUID_MSG_LIMITS (1 << GLIBTOP_SYSDEPS_MSG_LIMITS)
#define GLIBTOP_SUID_SEM_LIMITS (1 << GLIBTOP_SYSDEPS_SEM_LIMITS)
@@ -43,8 +39,12 @@ G_BEGIN_DECLS
#define GLIBTOP_SUID_PROC_ARGS (1 << GLIBTOP_SYSDEPS_PROC_ARGS)
#define GLIBTOP_SUID_PROC_MAP (1 << GLIBTOP_SYSDEPS_PROC_MAP)
#define GLIBTOP_SUID_NETLOAD (1 << GLIBTOP_SYSDEPS_NETLOAD)
-#define GLIBTOP_SUID_NETLIST 0
#define GLIBTOP_SUID_PPP (1 << GLIBTOP_SYSDEPS_PPP)
+#define GLIBTOP_SUID_CPU 0
+#define GLIBTOP_SUID_MEM 0
+#define GLIBTOP_SUID_UPTIME 0
+#define GLIBTOP_SUID_LOADAVG 0
+#define GLIBTOP_SUID_NETLIST 0
#define GLIBTOP_SUID_PROC_WD 0
#define GLIBTOP_SUID_PROC_AFFINITY 0
diff --git a/sysdeps/openbsd/loadavg.c b/sysdeps/openbsd/loadavg.c
index 6bee9344..c35c14ea 100644
--- a/sysdeps/openbsd/loadavg.c
+++ b/sysdeps/openbsd/loadavg.c
@@ -32,7 +32,7 @@ static const unsigned long _glibtop_sysdeps_loadavg =
/* Init function. */
void
-_glibtop_init_loadavg_p (glibtop *server)
+_glibtop_init_loadavg_s (glibtop *server)
{
server->sysdeps.loadavg = _glibtop_sysdeps_loadavg;
}
@@ -40,7 +40,7 @@ _glibtop_init_loadavg_p (glibtop *server)
/* Provides load averange. */
void
-glibtop_get_loadavg_p (glibtop *server, glibtop_loadavg *buf)
+glibtop_get_loadavg_s (glibtop *server, glibtop_loadavg *buf)
{
double ldavg[3];
int i;
diff --git a/sysdeps/openbsd/mem.c b/sysdeps/openbsd/mem.c
index 2abd3c38..6a49415b 100644
--- a/sysdeps/openbsd/mem.c
+++ b/sysdeps/openbsd/mem.c
@@ -48,12 +48,6 @@ static int pageshift; /* log base 2 of the pagesize */
/* define pagetok in terms of pageshift */
#define pagetok(size) ((size) << pageshift)
-/* nlist structure for kernel access */
-static struct nlist nlst [] = {
- { "_bufpages" },
- { 0 }
-};
-
/* MIB array for sysctl */
static int vmmeter_mib [] = { CTL_VM, VM_METER };
static int uvmexp_mib [] = { CTL_VM, VM_UVMEXP };
@@ -62,15 +56,10 @@ static int bcstats_mib [] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT };
/* Init function. */
void
-_glibtop_init_mem_p (glibtop *server)
+_glibtop_init_mem_s (glibtop *server)
{
register int pagesize;
- if (kvm_nlist (server->machine.kd, nlst) < 0) {
- glibtop_warn_io_r (server, "kvm_nlist (mem)");
- return;
- }
-
/* get the page size and calculate pageshift from it */
pagesize = sysconf(_SC_PAGESIZE);
pageshift = 0;
@@ -86,7 +75,7 @@ _glibtop_init_mem_p (glibtop *server)
}
void
-glibtop_get_mem_p (glibtop *server, glibtop_mem *buf)
+glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
{
struct vmtotal vmt;
struct uvmexp uvmexp;
diff --git a/sysdeps/openbsd/mountlist.c b/sysdeps/openbsd/mountlist.c
new file mode 100644
index 00000000..1e33485f
--- /dev/null
+++ b/sysdeps/openbsd/mountlist.c
@@ -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);
+}
diff --git a/sysdeps/openbsd/nosuid.c b/sysdeps/openbsd/nosuid.c
index b43eaca5..0394540c 100644
--- a/sysdeps/openbsd/nosuid.c
+++ b/sysdeps/openbsd/nosuid.c
@@ -21,16 +21,8 @@
#include <config.h>
#include <glibtop.h>
-#include <glibtop/open.h>
#include <glibtop/close.h>
void
-glibtop_open_s (glibtop *server,
- const char *program_name,
- const unsigned long features,
- const unsigned flags)
-{ }
-
-void
glibtop_close_s (glibtop *server)
{ }
diff --git a/sysdeps/openbsd/open.c b/sysdeps/openbsd/open.c
index 2ced09ae..66f0cdbc 100644
--- a/sysdeps/openbsd/open.c
+++ b/sysdeps/openbsd/open.c
@@ -20,75 +20,17 @@
*/
#include <config.h>
+#include <sys/types.h>
#include <glibtop.h>
-#include <glibtop/error.h>
#include <glibtop/open.h>
-#include <glibtop/init_hooks.h>
-/* !!! THIS FUNCTION RUNS SUID ROOT - CHANGE WITH CAUTION !!! */
+#include <glibtop_private.h>
-void
-glibtop_init_p (glibtop *server, const unsigned long features,
- const unsigned flags)
-{
- const _glibtop_init_func_t *init_fkt;
-
- if (server == NULL)
- glibtop_error_r (NULL, "glibtop_init_p (server == NULL)");
-
- /* Do the initialization, but only if not already initialized. */
-
- if ((server->flags & _GLIBTOP_INIT_STATE_SYSDEPS) == 0) {
- glibtop_open_p (server, "glibtop", features, flags);
-
- for (init_fkt = _glibtop_init_hook_p; *init_fkt; init_fkt++)
- (*init_fkt) (server);
-
- server->flags |= _GLIBTOP_INIT_STATE_SYSDEPS;
- }
-}
void
-glibtop_open_p (glibtop *server, const char *program_name,
+glibtop_open_s (glibtop *server, const char *program_name,
const unsigned long features,
const unsigned flags)
{
- char errbuf[_POSIX2_LINE_MAX];
-#ifdef DEBUG
- fprintf (stderr, "DEBUG (%d): glibtop_open_p ()\n", getpid ());
-#endif
-
- /* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */
-
- server->machine.uid = getuid ();
- server->machine.euid = geteuid ();
- server->machine.gid = getgid ();
- server->machine.egid = getegid ();
-
server->os_version_code = OpenBSD;
-
- /* Setup machine-specific data */
- server->machine.kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf);
-
- if (server->machine.kd == NULL)
- glibtop_error_io_r (server, "kvm_open");
-
- /* Drop priviledges. */
-
- if (setreuid (server->machine.euid, server->machine.uid))
- _exit (1);
-
- if (setregid (server->machine.egid, server->machine.gid))
- _exit (1);
-
- /* !!! END OF SUID ROOT PART !!! */
-
- /* Our effective uid is now those of the user invoking the server,
- * so we do no longer have any priviledges. */
-
- /* NOTE: On FreeBSD, we do not need to be suid root, we just need to
- * be sgid kmem.
- *
- * The server will only use setegid() to get back it's priviledges,
- * so it will fail if it is suid root and not sgid kmem. */
}
diff --git a/sysdeps/openbsd/procaffinity.c b/sysdeps/openbsd/procaffinity.c
index a8957e95..4164cd96 100644
--- a/sysdeps/openbsd/procaffinity.c
+++ b/sysdeps/openbsd/procaffinity.c
@@ -1,5 +1,5 @@
/*
- * procaffinity stub.
+ * TODO (procaffinity stub)
*/
#include <config.h>
diff --git a/sysdeps/openbsd/prockernel.c b/sysdeps/openbsd/prockernel.c
index 9d1a2144..698c5c56 100644
--- a/sysdeps/openbsd/prockernel.c
+++ b/sysdeps/openbsd/prockernel.c
@@ -34,12 +34,13 @@
#include <fcntl.h>
static const unsigned long _glibtop_sysdeps_proc_kernel_pstats =
+(1L << GLIBTOP_PROC_KERNEL_K_FLAGS) +
(1L << GLIBTOP_PROC_KERNEL_MIN_FLT) +
(1L << GLIBTOP_PROC_KERNEL_MAJ_FLT);
static const unsigned long _glibtop_sysdeps_proc_kernel_wchan =
-(1L << GLIBTOP_PROC_KERNEL_NWCHAN) +
-(1L << GLIBTOP_PROC_KERNEL_WCHAN);
+(1L << GLIBTOP_PROC_KERNEL_WCHAN) +
+(1L << GLIBTOP_PROC_KERNEL_NWCHAN);
/* Init function. */
@@ -68,22 +69,39 @@ glibtop_get_proc_kernel_p (glibtop *server,
/* It does not work for the swapper task. */
if (pid == 0) return;
+ glibtop_suid_enter (server);
+
/* Get the process information */
pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid,
sizeof(*pinfo), &count);
if ((pinfo == NULL) || (count != 1)) {
glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid);
+ glibtop_suid_leave (server);
return;
}
- buf->min_flt = pinfo[0].p_uru_minflt;
- buf->maj_flt = pinfo[0].p_uru_majflt;
+ glibtop_suid_leave (server);
+
+#define PROC_WCHAN p_wchan
+#define PROC_WMESG p_wmesg
+
+ buf->nwchan = (unsigned long) pinfo [0].PROC_WCHAN;
+
+ buf->flags |= (1L << GLIBTOP_PROC_KERNEL_NWCHAN);
+
+ if (pinfo [0].PROC_WCHAN && pinfo [0].PROC_WMESG[0] != 0) {
+ g_strlcpy (buf->wchan, pinfo [0].PROC_WMESG,
+ sizeof buf->wchan);
+ buf->flags |= (1L << GLIBTOP_PROC_KERNEL_WCHAN);
+ } else {
+ buf->wchan [0] = 0;
+ }
+
+ buf->k_flags = (unsigned long) pinfo [0].p_flag;
+ buf->min_flt = (unsigned long) pinfo [0].p_uru_minflt;
+ buf->maj_flt = (unsigned long) pinfo [0].p_uru_majflt;
- buf->nwchan = pinfo[0].p_wchan;
- if (pinfo[0].p_wchan && pinfo[0].p_wmesg)
- g_strlcpy(buf->wchan, pinfo[0].p_wmesg,
- sizeof buf->wchan);
+ buf->flags |= _glibtop_sysdeps_proc_kernel_pstats;
- buf->flags |= (_glibtop_sysdeps_proc_kernel_wchan
- | _glibtop_sysdeps_proc_kernel_pstats);
+ return;
}
diff --git a/sysdeps/openbsd/procmap.c b/sysdeps/openbsd/procmap.c
index 7984f3db..9a01d2e9 100644
--- a/sysdeps/openbsd/procmap.c
+++ b/sysdeps/openbsd/procmap.c
@@ -191,8 +191,11 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
if (kvm_read (server->machine.kd,
(unsigned long) pinfo [0].p_vmspace,
- (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace))
- glibtop_error_io_r (server, "kvm_read (vmspace)");
+ (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace)) {
+ glibtop_warn_io_r (server, "kvm_read (vmspace)");
+ glibtop_suid_leave (server);
+ return NULL;
+ }
RB_INIT(&root);
nentries = load_vmmap_entries(server,
@@ -236,6 +239,7 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
&vnode, sizeof (vnode)) != sizeof (vnode)) {
glibtop_warn_io_r (server, "kvm_read (vnode)");
unload_vmmap_entries(RB_ROOT(&root));
+ glibtop_suid_leave (server);
return (glibtop_map_entry*) g_array_free(maps, TRUE);
}
@@ -248,8 +252,12 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
if (kvm_read (server->machine.kd,
(unsigned long) vnode.v_data,
- &inode, sizeof (inode)) != sizeof (inode))
- glibtop_error_io_r (server, "kvm_read (inode)");
+ &inode, sizeof (inode)) != sizeof (inode)) {
+ glibtop_warn_io_r (server, "kvm_read (inode)");
+ unload_vmmap_entries(RB_ROOT(&root));
+ glibtop_suid_leave (server);
+ return (glibtop_map_entry*) g_array_free(maps, TRUE);
+ }
inum = inode.i_number;
dev = inode.i_dev;
@@ -276,6 +284,8 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
mentry->perm |= GLIBTOP_MAP_PERM_EXECUTE;
}
+ glibtop_suid_leave (server);
+
buf->flags = _glibtop_sysdeps_proc_map;
buf->number = maps->len;
diff --git a/sysdeps/openbsd/proctime.c b/sysdeps/openbsd/proctime.c
index 2d1230e6..af8551d9 100644
--- a/sysdeps/openbsd/proctime.c
+++ b/sysdeps/openbsd/proctime.c
@@ -56,59 +56,6 @@ _glibtop_init_proc_time_p (glibtop *server)
_glibtop_sysdeps_proc_time_user;
}
-/* Taken from /usr/src/sys/kern/kern_resource.c */
-
-/*
- * Transform the running time and tick information in proc p into user,
- * system, and interrupt time usage.
- */
-
-static void
-calcru(struct proc *p, struct timeval *up, struct timeval *sp,
- struct timeval *ip)
-{
- quad_t totusec;
- u_quad_t u, st, ut, it, tot;
- long sec, nsec;
- struct timeval tv;
-
- st = p->p_sticks;
- ut = p->p_uticks;
- it = p->p_iticks;
-
- tot = st + ut + it;
- if (tot == 0) {
- st = 1;
- tot = 1;
- }
-
- sec = p->p_rtime.tv_sec;
- nsec = p->p_rtime.tv_nsec;
-
- totusec = (quad_t)sec * 1000000 + nsec/1000;
-
- if (totusec < 0) {
- /* XXX no %qd in kernel. Truncate. */
- fprintf (stderr, "calcru: negative time: %ld usec\n",
- (long)totusec);
- totusec = 0;
- }
-
-
- u = totusec;
- st = (u * st) / tot;
- sp->tv_sec = st / 1000000;
- sp->tv_usec = st % 1000000;
- ut = (u * ut) / tot;
- up->tv_sec = ut / 1000000;
- up->tv_usec = ut % 1000000;
- if (ip != NULL) {
- it = (u * it) / tot;
- ip->tv_sec = it / 1000000;
- ip->tv_usec = it % 1000000;
- }
-}
-
/* Provides detailed information about a process. */
void
diff --git a/sysdeps/openbsd/procwd.c b/sysdeps/openbsd/procwd.c
index fcf386ee..ad084f5f 100644
--- a/sysdeps/openbsd/procwd.c
+++ b/sysdeps/openbsd/procwd.c
@@ -39,58 +39,6 @@ _glibtop_init_proc_wd_s(glibtop *server)
server->sysdeps.proc_wd = _glibtop_sysdeps_proc_wd;
}
-static GPtrArray *
-parse_output(const char *output, glibtop_proc_wd *buf)
-{
- GPtrArray *dirs;
- char **lines;
- gboolean nextwd = FALSE;
- gboolean nextrtd = FALSE;
- gboolean havertd = FALSE;
- guint i;
- guint len;
-
- dirs = g_ptr_array_sized_new(1);
-
- lines = g_strsplit(output, "\n", 0);
- len = g_strv_length(lines);
-
- for (i = 0; i < len && lines[i]; i++) {
- if (strlen(lines[i]) < 2)
- continue;
-
- if (!strcmp(lines[i], "fcwd")) {
- nextwd = TRUE;
- continue;
- }
-
- if (!strcmp(lines[i], "frtd")) {
- nextrtd = TRUE;
- continue;
- }
-
- if (!g_str_has_prefix(lines[i], "n"))
- continue;
-
- if (nextwd) {
- g_ptr_array_add(dirs, g_strdup(lines[i] + 1));
- nextwd = FALSE;
- }
-
- if (nextrtd && !havertd) {
- g_strlcpy(buf->root, lines[i] + 1,
- sizeof(buf->root));
- buf->flags |= (1 << GLIBTOP_PROC_WD_ROOT);
- nextrtd = FALSE;
- havertd = TRUE;
- }
- }
-
- g_strfreev(lines);
-
- return dirs;
-}
-
char**
glibtop_get_proc_wd_s(glibtop *server, glibtop_proc_wd *buf, pid_t pid)
{
diff --git a/sysdeps/openbsd/suid_open.c b/sysdeps/openbsd/suid_open.c
new file mode 100644
index 00000000..137a4268
--- /dev/null
+++ b/sysdeps/openbsd/suid_open.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 1998 Joshua Sled
+ This file is part of LibGTop 1.0.
+
+ Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998.
+
+ 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.h>
+#include <glibtop/error.h>
+#include <glibtop/cpu.h>
+#include <glibtop/open.h>
+#include <glibtop/init_hooks.h>
+
+
+/* !!! THIS FUNCTION RUNS SUID ROOT - CHANGE WITH CAUTION !!! */
+
+void
+glibtop_init_p (glibtop *server, const unsigned long features,
+ const unsigned flags)
+{
+ const _glibtop_init_func_t *init_fkt;
+
+ if (server == NULL)
+ glibtop_error_r (NULL, "glibtop_init_p (server == NULL)");
+
+ /* Do the initialization, but only if not already initialized. */
+
+ if ((server->flags & _GLIBTOP_INIT_STATE_SYSDEPS) == 0) {
+ glibtop_open_p (server, "glibtop", features, flags);
+
+ for (init_fkt = _glibtop_init_hook_p; *init_fkt; init_fkt++)
+ (*init_fkt) (server);
+
+ server->flags |= _GLIBTOP_INIT_STATE_SYSDEPS;
+ }
+}
+
+void
+glibtop_open_p (glibtop *server, const char *program_name,
+ const unsigned long features,
+ const unsigned flags)
+{
+ char errbuf[_POSIX2_LINE_MAX];
+#ifdef DEBUG
+ fprintf (stderr, "DEBUG (%d): glibtop_open_p ()\n", getpid ());
+#endif
+
+ /* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */
+ server->machine.uid = getuid ();
+ server->machine.euid = geteuid ();
+ server->machine.gid = getgid ();
+ server->machine.egid = getegid ();
+ /* Setup machine-specific data */
+ server->machine.kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf);
+
+ if (server->machine.kd == NULL)
+ glibtop_error_io_r (server, "kvm_open");
+
+ /* Drop priviledges. */
+
+ if (setreuid (server->machine.euid, server->machine.uid))
+ _exit (1);
+
+ if (setregid (server->machine.egid, server->machine.gid))
+ _exit (1);
+
+ /* !!! END OF SUID ROOT PART !!! */
+
+ /* Our effective uid is now those of the user invoking the server,
+ * so we do no longer have any priviledges. */
+
+ /* NOTE: On OpenBSD, we do not need to be suid root, we just need to
+ * be sgid kmem.
+ *
+ * The server will only use setegid() to get back it's priviledges,
+ * so it will fail if it is suid root and not sgid kmem. */
+}
diff --git a/sysdeps/openbsd/uptime.c b/sysdeps/openbsd/uptime.c
index 111a2f06..6067fbf1 100644
--- a/sysdeps/openbsd/uptime.c
+++ b/sysdeps/openbsd/uptime.c
@@ -37,7 +37,7 @@ static const unsigned long _required_cpu_flags =
/* Init function. */
void
-_glibtop_init_uptime_p (glibtop *server)
+_glibtop_init_uptime_s (glibtop *server)
{
server->sysdeps.uptime = _glibtop_sysdeps_uptime;
}
@@ -45,7 +45,7 @@ _glibtop_init_uptime_p (glibtop *server)
/* Provides uptime and idle time. */
void
-glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf)
+glibtop_get_uptime_s (glibtop *server, glibtop_uptime *buf)
{
time_t now;
int mib[2];
@@ -63,7 +63,7 @@ glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf)
buf->boot_time = boottime.tv_sec;
}
- glibtop_get_cpu_p (server, &cpu);
+ glibtop_get_cpu_s (server, &cpu);
/* Put something clever in buf->idletime: CP_IDLE. */
buf->idletime = (double) cpu.idle / (double) cpu.frequency;