diff options
author | Antoine Jacoutot <ajacoutot@gnome.org> | 2014-02-03 10:56:02 +0100 |
---|---|---|
committer | Antoine Jacoutot <ajacoutot@gnome.org> | 2014-02-03 10:59:05 +0100 |
commit | 4cd3e4fed692dae5b1f238ac11ca03bf044e350e (patch) | |
tree | 681effbc51588905b631c69b05857d9b7c5c2fef /sysdeps | |
parent | c99ceeaa65a5482db2b5b3b677a8c4b40acc8eb8 (diff) | |
download | libgtop-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.am | 23 | ||||
-rw-r--r-- | sysdeps/openbsd/cpu.c | 4 | ||||
-rw-r--r-- | sysdeps/openbsd/fsusage.c | 80 | ||||
-rw-r--r-- | sysdeps/openbsd/glibtop_server.h | 10 | ||||
-rw-r--r-- | sysdeps/openbsd/loadavg.c | 4 | ||||
-rw-r--r-- | sysdeps/openbsd/mem.c | 15 | ||||
-rw-r--r-- | sysdeps/openbsd/mountlist.c | 168 | ||||
-rw-r--r-- | sysdeps/openbsd/nosuid.c | 8 | ||||
-rw-r--r-- | sysdeps/openbsd/open.c | 64 | ||||
-rw-r--r-- | sysdeps/openbsd/procaffinity.c | 2 | ||||
-rw-r--r-- | sysdeps/openbsd/prockernel.c | 38 | ||||
-rw-r--r-- | sysdeps/openbsd/procmap.c | 18 | ||||
-rw-r--r-- | sysdeps/openbsd/proctime.c | 53 | ||||
-rw-r--r-- | sysdeps/openbsd/procwd.c | 52 | ||||
-rw-r--r-- | sysdeps/openbsd/suid_open.c | 92 | ||||
-rw-r--r-- | sysdeps/openbsd/uptime.c | 6 |
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; |