diff options
author | Carlos Perelló Marín <carlos@gnome.org> | 2003-10-19 16:55:56 +0000 |
---|---|---|
committer | Carlos Perelló Marín <carlos@src.gnome.org> | 2003-10-19 16:55:56 +0000 |
commit | 4c8ae9e25c1940d8876ca3f2330426863cae4737 (patch) | |
tree | c43f97bc0647546b0ed87022db0749c137f24edc /sysdeps/freebsd | |
parent | bae16b467f90df94d80feae41dceb7e816f16c61 (diff) | |
download | libgtop-4c8ae9e25c1940d8876ca3f2330426863cae4737.tar.gz |
Reverted libgtop changes. It's a common module and I should not modify it.
2003-10-19 Carlos Perelló Marín <carlos@gnome.org>
* support/*: Reverted libgtop changes. It's a common module
and I should not modify it.
* Added/removed files. Now the move should be done.
Diffstat (limited to 'sysdeps/freebsd')
34 files changed, 4031 insertions, 0 deletions
diff --git a/sysdeps/freebsd/.cvsignore b/sysdeps/freebsd/.cvsignore new file mode 100644 index 00000000..09980ae6 --- /dev/null +++ b/sysdeps/freebsd/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +*.la diff --git a/sysdeps/freebsd/AUTHORS b/sysdeps/freebsd/AUTHORS new file mode 100644 index 00000000..9da8aceb --- /dev/null +++ b/sysdeps/freebsd/AUTHORS @@ -0,0 +1,2 @@ +Martin Baulig (martin@home-of-linux.org) +Josh Sled (jsled@scam.XCF.Berkeley.EDU) diff --git a/sysdeps/freebsd/ChangeLog b/sysdeps/freebsd/ChangeLog new file mode 100644 index 00000000..72a89fa7 --- /dev/null +++ b/sysdeps/freebsd/ChangeLog @@ -0,0 +1,188 @@ +2001-10-17 Abel Cheung <maddog@linux.org.hk> + + * Makefile.am: move header to $(includedir)/libgtop-1.0/glibtop. + +2001-02-27 Martin Baulig <baulig@suse.de> + + * netload.c: Comment out the `subnet' field on BSDI; this should + make it compile. Bug #13345. + + * shm_limits.c, msg_limits.c, sem_limits.c: Applied a patch + from Rolf Grossmann (grossman@securitas.net) for FreeBSD 4.2. + Fixes #51334. + +2001-02-14 Martin Baulig <baulig@suse.de> + + * proctime.c (glibtop_get_proc_time_p): Make things work on + OpenBSD 2.6; this is basically the same than on NetBSD. + +2000-02-13 Martin Baulig <martin@home-of-linux.org> + + * *.c: kvm_nlist () returns -1 on error, but a positive return value + does not necessarily mean failure. Fixes #3302 which was reported by + Matthias Scheler some time ago. + +1999-10-16 Martin Baulig <martin@home-of-linux.org> + + Applied all patches from the FreeBSD 3.3 ports collection. + + * swap.c: Only #include <rlist.h> for __FreeBSD_version < 400005. + + * prockernel.c: Make it compile on FreeBSD / alpha. + + * procsignal.c: Some fixes for FreeBSD-current. + +1999-10-16 Martin Baulig <martin@home-of-linux.org> + + * procstate.c (glibtop_get_proc_state_p): Don't use the + `GLIBTOP_PROCESS_*' constants for process states for + LibGTop 1.0.x. + +1999-07-29 Martin Baulig <martin@home-of-linux.org> + + * proctime.c (glibtop_get_proc_time_p): Fix bug reported by + Takis Psarogiannakopoulos: `start_time' are seconds since the + epoch as it is stated in the manual. + +Tue Jun 15 16:04:10 1999 Timur Bakeyev <mc@bat.ru> + + * procuid.c: A fix to a ommitted case, when nor NetBSD, nor + LibGTop >= 1.1.0. This should be investigated closely to cover + more cases.... + +1999-05-26 Martin Baulig <martin@home-of-linux.org> + + More NetBSD 1.4 fixes. + + * mem.c, procmap.c, procmem.c: Make this work with the new UVM code. + + [FIXME: This following most likely works on all BSD systems, but + this needs to be tested; I made it conditional to NetBSD 1.4 at + the moment. Please extend the conditionals to any other systems + where this works ...] + + * procstate.c: Added `ruid' and `rgid' for LibGTop >= 1.1.0. + * procuid.c: Added `ngroups' and `groups' for LibGTop >= 1.1.0. + +1999-05-25 Martin Baulig <martin@home-of-linux.org> + + * ppp.c: Make this work on NetBSD. + +Thu Apr 8 23:47:29 1999 Timur Bakeyev <timur@gnu.org> + + * cpu.c, mem.c, netload.c, procargs.c, procstate.c, proctime.c, + sem_limits.c, shm_limits.c, swap.c: Added initial port for BSD/OS + (aka BSDI) 2.x and 3.x. 4.x should also(?) work. + + Still, this port require more close look and extended check. + +1999-03-19 Martin Baulig <martin@home-of-linux.org> + + Added basic support for BSDI. It compiles without problems on + BSDI 2.1 and 3.1, but it is *untested* - I'm neither root on + the machine nor have I access to /dev/kmem, so I don't know + whether it will work. + + You need to give configure the `--enable-hacker-mode' parameter + to use the code. + + If someone can verify whether it actually works, please let me + know. + +1999-03-18 Martin Baulig <martin@home-of-linux.org> + + * ppp.c: Don't use `sppp.pp_phase' if we don't HAVE_I4B_ACCT. + This is an ugly hack until someone tells me which versions have + this field and which not. + +1999-02-25 Martin Baulig <martin@home-of-linux.org> + + * prockernel.c, proctime.c: Applied patch Stanislav Grozev for + OpenBSD: only include <osreldate.h> for FreeBSD. + +1999-02-24 Martin Baulig <martin@home-of-linux.org> + + * swap.c: Applied another patch from Jeremy Lea to + make it work with FreeBSD-current. + +1999-02-21 Martin Baulig <martin@home-of-linux.org> + + * procmap.c, procmem.c: Applied patch from Jeremy Lea. + + * prockernel.c, proctime.c: Applied patch from the FreeBSD 2.2.8 + ports collection. + + * procsignal.c: Applied patch from the NetBSD-current ports + collection. + +1998-12-06 Martin Baulig <martin@home-of-linux.org> + + * Make it work with OpenBSD 2.4. + +1998-12-05 Martin Baulig <martin@home-of-linux.org> + + * Make it work with NetBSD 1.3.2. + +1998-11-17 Martin Baulig <martin@home-of-linux.org> + + * Make it work with FreeBSD 3.0. + +1998-11-11 Martin Baulig <martin@home-of-linux.org> + + * *.c: It does not work to get information about the swapper task + on FreeBSD 2.2.6, so we simple return if pid == 0. + +1998-10-31 Martin Baulig <martin@home-of-linux.org> + + * *.c: Use glibtop_warn_io_r () instead of glibtop_error_io_r (). + + * proctime.c, prockernel.c, procargs.c: Don't call kvm_uread () if + the /proc filesystem is not mounted. + +1998-10-26 Martin Baulig <martin@home-of-linux.org> + + * netload.c: New file to get network load. + +1998-10-26 Martin Baulig <martin@home-of-linux.org> + + * procargs.c: New file to get command line arguments. + +1998-10-25 Martin Baulig <martin@home-of-linux.org> + + * ppp.c: New file to get PPP/ISDN statistics. Currently this only + get ISDN statistics if you have the I4B package. + + To get the number of bytes transferred in/out you need to read the + file `misc/i4b_acct.txt' in the LibGTop source directory to see + how to enable this. + +1998-10-03 Martin Baulig <martin@home-of-linux.org> + + * procstate.c (glibtop_get_procstate_s): Use correct values for + the `state' field. + + * proclist.c (glibtop_get_proclist_p): Honor the GLIBTOP_EXCLUDE_IDLE + and GLIBTOP_EXCLUDE_SYSTEM flags of the `which' parameter. + +1998-08-24 Martin Baulig <martin@home-of-linux.org> + + * *.c (glibtop_init_p): Using correct `(1 << GLIBTOP_SYSDPES_*)'. + * cpu.c, mem.c: Removed `const' from sysctl () constants to keep + compiler happy. + + * procmem.c: Added missing call to `glibtop_init_p'. + + * prockernel.c: Casting `nwchan' to `unsigned long' since this + normally has the same size than a pointer. Well, is there a + FreeBSD for 64bit architectures ? + +1998-08-08 Martin Baulig <martin@home-of-linux.org> + + * swap.c: Added swap usage based upton the source code + of `pinfo'. + +1998-08-07 Martin Baulig <martin@home-of-linux.org> + + * *: Imported FreeBSD port of libgtop from Josh Sled. + + * ChangeLog: New file. diff --git a/sysdeps/freebsd/Makefile.am b/sysdeps/freebsd/Makefile.am new file mode 100644 index 00000000..b955e6ff --- /dev/null +++ b/sysdeps/freebsd/Makefile.am @@ -0,0 +1,23 @@ +LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@ + +INCLUDES = @INCLUDES@ + +lib_LTLIBRARIES = libgtop_sysdeps-2.0.la libgtop_sysdeps_suid-2.0.la + +libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c + +libgtop_sysdeps_2_0_la_LDFLAGS = $(LT_VERSION_INFO) + +libgtop_sysdeps_suid_2_0_la_SOURCES = open.c close.c siglist.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 netload.c \ + ppp.c + +libgtop_sysdeps_suid_2_0_la_LDFLAGS = $(LT_VERSION_INFO) + +libgtopinclude_HEADERS = glibtop_server.h glibtop_machine.h \ + glibtop_suid.h + +libgtopincludedir = $(includedir)/libgtop-2.0 diff --git a/sysdeps/freebsd/NOTES b/sysdeps/freebsd/NOTES new file mode 100644 index 00000000..82bbbc4b --- /dev/null +++ b/sysdeps/freebsd/NOTES @@ -0,0 +1,10 @@ +sysctl (3) +/usr/include/sys/vmmeter.h : VM stats +kvm (3) + +CPU stats: /usr/include/sys/dkstat.h +cp_time_offset = kvm_nlist(...)["_cp_time"].n_value; + +"systemwide main memory usage structure" +sysctl(...) + diff --git a/sysdeps/freebsd/close.c b/sysdeps/freebsd/close.c new file mode 100644 index 00000000..b887a914 --- /dev/null +++ b/sysdeps/freebsd/close.c @@ -0,0 +1,31 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/close.h> + +/* Closes pipe to gtop server. */ + +void +glibtop_close_p (glibtop *server) +{ } diff --git a/sysdeps/freebsd/cpu.c b/sysdeps/freebsd/cpu.c new file mode 100644 index 00000000..5fdce7ad --- /dev/null +++ b/sysdeps/freebsd/cpu.c @@ -0,0 +1,117 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/cpu.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_cpu = +(1L << GLIBTOP_CPU_TOTAL) + (1L << GLIBTOP_CPU_USER) + +(1L << GLIBTOP_CPU_NICE) + (1L << GLIBTOP_CPU_SYS) + +(1L << GLIBTOP_CPU_IDLE) + (1L << GLIBTOP_CPU_FREQUENCY); + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { +#ifdef __bsdi__ + { "_cpustats" }, +#else + { "_cp_time" }, +#endif + { 0 } +}; + +/* MIB array for sysctl */ +static int mib_length=2; +static int mib [] = { CTL_KERN, KERN_CLOCKRATE }; + +/* Init function. */ + +void +glibtop_init_cpu_p (glibtop *server) +{ + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (cpu)"); + return; + } + + /* Set this only if kvm_nlist () succeeded. */ + server->sysdeps.cpu = _glibtop_sysdeps_cpu; +} + +/* Provides information about cpu usage. */ + +void +glibtop_get_cpu_p (glibtop *server, glibtop_cpu *buf) +{ + long cpts [CPUSTATES]; + /* sysctl vars*/ + struct clockinfo ci; + size_t length; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_CPU), 0); + + memset (buf, 0, sizeof (glibtop_cpu)); + + /* If this fails, the nlist may not be valid. */ + if (server->sysdeps.cpu == 0) + return; + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &cpts, sizeof (cpts)) != sizeof (cpts)) { + glibtop_warn_io_r (server, "kvm_read (cp_time)"); + return; + } + + /* Get the clockrate data */ + length = sizeof (struct clockinfo); + if (sysctl (mib, mib_length, &ci, &length, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl"); + return; + } + + /* set user time */ + buf->user = cpts [CP_USER]; + /* set nice time */ + buf->nice = cpts [CP_NICE]; + /* set sys time */ + buf->sys = cpts [CP_SYS]; + /* set idle time */ + buf->idle = cpts [CP_IDLE]; + + /* set frequency */ + /* + FIXME -- is hz, tick, profhz or stathz wanted? + buf->frequency = sysctl("kern.clockrate", ...); + + struct clockinfo + */ + buf->frequency = ci.hz; + /* set total */ + buf->total = cpts [CP_USER] + cpts [CP_NICE] + + cpts [CP_SYS] + cpts [CP_IDLE]; + + /* Set the flags last. */ + buf->flags = _glibtop_sysdeps_cpu; +} diff --git a/sysdeps/freebsd/glibtop_machine.h b/sysdeps/freebsd/glibtop_machine.h new file mode 100644 index 00000000..192c3b7f --- /dev/null +++ b/sysdeps/freebsd/glibtop_machine.h @@ -0,0 +1,59 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 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. +*/ + +#ifndef __GLIBTOP_MACHINE_H__ +#define __GLIBTOP_MACHINE_H__ + +#include <sys/param.h> +#include <nlist.h> +#include <kvm.h> +#include <sys/dkstat.h> +#include <time.h> +#include <sys/user.h> +#include <sys/types.h> +#include <sys/sysctl.h> + +#include <fcntl.h> + +#ifdef __FreeBSD__ +#include <osreldate.h> +#endif + +BEGIN_LIBGTOP_DECLS + +typedef struct _glibtop_machine glibtop_machine; + +struct _glibtop_machine +{ + uid_t uid, euid; + gid_t gid, egid; + + /* The kernel descriptor, used by kvm_* calls. We keep and re-use + * it rather than re-getting it for almost all function + * invocations. */ + kvm_t *kd; +}; + +END_LIBGTOP_DECLS + +#endif /* __GLIBTOP_MACHINE_H__ */ diff --git a/sysdeps/freebsd/glibtop_server.h b/sysdeps/freebsd/glibtop_server.h new file mode 100644 index 00000000..ccf3d29d --- /dev/null +++ b/sysdeps/freebsd/glibtop_server.h @@ -0,0 +1,52 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 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. +*/ + +#ifndef __GLIBTOP_SERVER_H__ +#define __GLIBTOP_SERVER_H__ + +BEGIN_LIBGTOP_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) +#define GLIBTOP_SUID_PROCLIST (1 << GLIBTOP_SYSDEPS_PROCLIST) +#define GLIBTOP_SUID_PROC_STATE (1 << GLIBTOP_SYSDEPS_PROC_STATE) +#define GLIBTOP_SUID_PROC_UID (1 << GLIBTOP_SYSDEPS_PROC_UID) +#define GLIBTOP_SUID_PROC_MEM (1 << GLIBTOP_SYSDEPS_PROC_MEM) +#define GLIBTOP_SUID_PROC_TIME (1 << GLIBTOP_SYSDEPS_PROC_TIME) +#define GLIBTOP_SUID_PROC_SIGNAL (1 << GLIBTOP_SYSDEPS_PROC_SIGNAL) +#define GLIBTOP_SUID_PROC_KERNEL (1 << GLIBTOP_SYSDEPS_PROC_KERNEL) +#define GLIBTOP_SUID_PROC_SEGMENT (1 << GLIBTOP_SYSDEPS_PROC_SEGMENT) +#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_PPP (1 << GLIBTOP_SYSDEPS_PPP) + +END_LIBGTOP_DECLS + +#endif diff --git a/sysdeps/freebsd/glibtop_suid.h b/sysdeps/freebsd/glibtop_suid.h new file mode 100644 index 00000000..18ad4b76 --- /dev/null +++ b/sysdeps/freebsd/glibtop_suid.h @@ -0,0 +1,58 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 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. +*/ + +#ifndef __GLIBTOP_SUID_H__ +#define __GLIBTOP_SUID_H__ + +BEGIN_LIBGTOP_DECLS + +#if _IN_LIBGTOP +#include <sys/param.h> +#endif + +#define KI_PROC(ki) (&(ki))->kp_proc) +#define KI_EPROC(ki) (&(ki))->kp_eproc) + +#define FORCEUREAD 1 +#define UREADOK(ki) (FORCEUREAD || (KI_PROC(ki)->p_flag & P_INMEM)) + +static inline void glibtop_suid_enter (glibtop *server) { + setregid (server->machine.gid, server->machine.egid); +}; + +static inline void glibtop_suid_leave (glibtop *server) { + if (setregid (server->machine.egid, server->machine.gid)) + _exit (1); +}; + +void +glibtop_init_p (glibtop *server, const unsigned long features, + const unsigned flags); +void +glibtop_open_p (glibtop *server, const char *program_name, + const unsigned long features, + const unsigned flags); + +END_LIBGTOP_DECLS + +#endif diff --git a/sysdeps/freebsd/init.c b/sysdeps/freebsd/init.c new file mode 100644 index 00000000..11d89342 --- /dev/null +++ b/sysdeps/freebsd/init.c @@ -0,0 +1,45 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/open.h> + +static glibtop _glibtop_global_server; +glibtop *glibtop_global_server = NULL; + +glibtop * +glibtop_init_r (glibtop **server, + const unsigned long features, + const unsigned flags) +{ + if (*server != NULL) + return *server; + + if (glibtop_global_server == NULL) { + glibtop_global_server = &_glibtop_global_server; + glibtop_open (glibtop_global_server, "glibtop", + features, flags); + } + + return *server = glibtop_global_server; +} diff --git a/sysdeps/freebsd/loadavg.c b/sysdeps/freebsd/loadavg.c new file mode 100644 index 00000000..b0530e8a --- /dev/null +++ b/sysdeps/freebsd/loadavg.c @@ -0,0 +1,60 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/loadavg.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_loadavg = +(1L << GLIBTOP_LOADAVG_LOADAVG); + +/* Init function. */ + +void +glibtop_init_loadavg_p (glibtop *server) +{ + server->sysdeps.loadavg = _glibtop_sysdeps_loadavg; +} + +/* Provides load averange. */ + +void +glibtop_get_loadavg_p (glibtop *server, glibtop_loadavg *buf) +{ + double ldavg[3]; + int i; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_LOADAVG), 0); + + memset (buf, 0, sizeof (glibtop_loadavg)); + + getloadavg (ldavg, 3); + + /* fill in the struct */ + buf->flags = _glibtop_sysdeps_loadavg; + for (i = 0; i < 3; i++) { + buf->loadavg [i] = ldavg [i]; + } /* end for */ +} diff --git a/sysdeps/freebsd/mem.c b/sysdeps/freebsd/mem.c new file mode 100644 index 00000000..1b96fe7f --- /dev/null +++ b/sysdeps/freebsd/mem.c @@ -0,0 +1,222 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/mem.h> + +#include <glibtop_suid.h> + +#include <sys/sysctl.h> +#include <sys/vmmeter.h> +#include <vm/vm_param.h> + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +#include <uvm/uvm_extern.h> +#endif + +static const unsigned long _glibtop_sysdeps_mem = +(1L << GLIBTOP_MEM_TOTAL) + (1L << GLIBTOP_MEM_USED) + +(1L << GLIBTOP_MEM_FREE) + +(1L << GLIBTOP_MEM_SHARED) + +(1L << GLIBTOP_MEM_BUFFER) + +#ifdef __FreeBSD__ +(1L << GLIBTOP_MEM_CACHED) + +#endif +(1L << GLIBTOP_MEM_USER) + (1L << GLIBTOP_MEM_LOCKED); + +#ifndef LOG1024 +#define LOG1024 10 +#endif + +/* these are for getting the memory statistics */ +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 [] = { +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + { "_bufpages" }, + { 0 } +#else +#if defined(__bsdi__) + { "_bufcachemem" }, +#elif defined(__FreeBSD__) + { "_bufspace" }, +#else + { "_bufpages" }, +#endif + { "_cnt" }, + { 0 } +#endif +}; + +/* MIB array for sysctl */ +static int mib_length=2; +#ifdef __bsdi__ +static int mib [] = { CTL_VM, VM_TOTAL }; +#else +static int mib [] = { CTL_VM, VM_METER }; +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +static int mib_uvmexp [] = { CTL_VM, VM_UVMEXP }; +#endif + +/* Init function. */ + +void +glibtop_init_mem_p (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 with "getpagesize" and calculate pageshift + * from it */ + pagesize = getpagesize (); + pageshift = 0; + while (pagesize > 1) { + pageshift++; + pagesize >>= 1; + } + + /* we only need the amount of log(2)1024 for our conversion */ + pageshift -= LOG1024; + + server->sysdeps.mem = _glibtop_sysdeps_mem; +} + +void +glibtop_get_mem_p (glibtop *server, glibtop_mem *buf) +{ + struct vmtotal vmt; + size_t length_vmt; +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + struct uvmexp uvmexp; + size_t length_uvmexp; +#else + struct vmmeter vmm; +#endif + u_int v_used_count; + u_int v_total_count; + u_int v_free_count; + int bufspace; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_MEM), 0); + + memset (buf, 0, sizeof (glibtop_mem)); + + if (server->sysdeps.mem == 0) + return; + + /* [FIXME: On FreeBSD 2.2.6, sysctl () returns an incorrect + * value for `vmt.vm'. We use some code from Unix top + * here.] */ + + /* Get the data from sysctl */ + length_vmt = sizeof (vmt); + if (sysctl (mib, 2, &vmt, &length_vmt, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (vmt)"); + return; + } + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + length_uvmexp = sizeof (uvmexp); + if (sysctl (mib_uvmexp, 2, &uvmexp, &length_uvmexp, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (uvmexp)"); + return; + } +#else + /* Get the data from kvm_* */ + if (kvm_read (server->machine.kd, nlst[1].n_value, + &vmm, sizeof (vmm)) != sizeof (vmm)) { + glibtop_warn_io_r (server, "kvm_read (cnt)"); + return; + } +#endif + + if (kvm_read (server->machine.kd, nlst[0].n_value, + &bufspace, sizeof (bufspace)) != sizeof (bufspace)) { + glibtop_warn_io_r (server, "kvm_read (bufspace)"); + return; + } + + /* convert memory stats to Kbytes */ + +#if defined(__FreeBSD__) + v_total_count = vmm.v_page_count; +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + v_total_count = uvmexp.reserve_kernel + + uvmexp.reserve_pagedaemon + + uvmexp.free + uvmexp.wired + uvmexp.active + + uvmexp.inactive; +#else + v_total_count = vmm.v_kernel_pages + + vmm.v_free_count + vmm.v_wire_count + + vmm.v_active_count + vmm.v_inactive_count; +#endif +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + v_used_count = uvmexp.active + uvmexp.inactive; + v_free_count = uvmexp.free; +#else + v_used_count = vmm.v_active_count + vmm.v_inactive_count; + v_free_count = vmm.v_free_count; +#endif + + buf->total = (u_int64_t) pagetok (v_total_count) << LOG1024; + buf->used = (u_int64_t) pagetok (v_used_count) << LOG1024; + buf->free = (u_int64_t) pagetok (v_free_count) << LOG1024; + +#ifdef __FreeBSD__ + buf->cached = (u_int64_t) pagetok (vmm.v_cache_count) << LOG1024; +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + buf->locked = (u_int64_t) pagetok (uvmexp.wired) << LOG1024; +#else + buf->locked = (u_int64_t) pagetok (vmm.v_wire_count) << LOG1024; +#endif + + buf->shared = (u_int64_t) pagetok (vmt.t_rmshr) << LOG1024; + +#if __FreeBSD__ + buf->buffer = (u_int64_t) bufspace; +#else + buf->buffer = (u_int64_t) pagetok (bufspace) << LOG1024; +#endif + + /* user */ + buf->user = buf->total - buf->free - buf->shared - buf->buffer; + + /* Set the values to return */ + buf->flags = _glibtop_sysdeps_mem; +} diff --git a/sysdeps/freebsd/msg_limits.c b/sysdeps/freebsd/msg_limits.c new file mode 100644 index 00000000..e4752bf3 --- /dev/null +++ b/sysdeps/freebsd/msg_limits.c @@ -0,0 +1,115 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, August 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/msg_limits.h> + +#include <glibtop_suid.h> + +#if (defined __bsdi__) && (_BSDI_VERSION < 199700) +/* Older versions of BSDI don't seem to have this. */ + +void +glibtop_init_msg_limits_p (glibtop *server) +{ } + +void +glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_MSG_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_msg_limits)); +} + +#else + +/* #define KERNEL to get declaration of `struct msginfo'. */ + +#if (defined(__FreeBSD__) && (__FreeBSD_version < 410000)) || (defined __bsdi__) +#define KERNEL 1 +#else +#define _KERNEL 1 +#endif + +#include <sys/ipc.h> +#include <sys/msg.h> + +static const unsigned long _glibtop_sysdeps_msg_limits = +(1L << GLIBTOP_IPC_MSGMAX) + (1L << GLIBTOP_IPC_MSGMNI) + +(1L << GLIBTOP_IPC_MSGMNB) + (1L << GLIBTOP_IPC_MSGTQL) + +(1L << GLIBTOP_IPC_MSGSSZ); + +/* The values in this structure never change at runtime, so we only + * read it once during initialization. We have to use the name `_msginfo' + * since `msginfo' is already declared external in <sys/msg.h>. */ +static struct msginfo _msginfo; + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_msginfo" }, + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_msg_limits_p (glibtop *server) +{ + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (msg_limits)"); + return; + } + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &_msginfo, sizeof (_msginfo)) != sizeof (_msginfo)) { + glibtop_warn_io_r (server, "kvm_read (msginfo)"); + return; + } + + server->sysdeps.msg_limits = _glibtop_sysdeps_msg_limits; +} + +/* Provides information about sysv ipc limits. */ + +void +glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_MSG_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_msg_limits)); + + if (server->sysdeps.msg_limits == 0) + return; + + buf->msgmax = _msginfo.msgmax; + buf->msgmni = _msginfo.msgmni; + buf->msgmnb = _msginfo.msgmnb; + buf->msgtql = _msginfo.msgtql; + buf->msgssz = _msginfo.msgtql; + + buf->flags = _glibtop_sysdeps_msg_limits; +} + +#endif /* either a newer BSDI or no BSDI at all. */ + diff --git a/sysdeps/freebsd/netload.c b/sysdeps/freebsd/netload.c new file mode 100644 index 00000000..4062dfe2 --- /dev/null +++ b/sysdeps/freebsd/netload.c @@ -0,0 +1,219 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, October 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/netload.h> + +#include <glibtop_suid.h> + +#include <net/if.h> +#include <net/if_dl.h> +#include <net/if_types.h> + +#ifdef HAVE_NET_IF_VAR_H +#include <net/if_var.h> +#endif + +#include <netinet/in.h> +#include <netinet/in_var.h> + +static const unsigned long _glibtop_sysdeps_netload = +(1L << GLIBTOP_NETLOAD_IF_FLAGS) + +(1L << GLIBTOP_NETLOAD_MTU) + +#if !defined(__bsdi__) +(1L << GLIBTOP_NETLOAD_SUBNET) + +#endif +(1L << GLIBTOP_NETLOAD_ADDRESS) + +(1L << GLIBTOP_NETLOAD_PACKETS_IN) + +(1L << GLIBTOP_NETLOAD_PACKETS_OUT) + +(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) + +(1L << GLIBTOP_NETLOAD_BYTES_IN) + +(1L << GLIBTOP_NETLOAD_BYTES_OUT) + +(1L << GLIBTOP_NETLOAD_BYTES_TOTAL) + +(1L << GLIBTOP_NETLOAD_ERRORS_IN) + +(1L << GLIBTOP_NETLOAD_ERRORS_OUT) + +(1L << GLIBTOP_NETLOAD_ERRORS_TOTAL) + +(1L << GLIBTOP_NETLOAD_COLLISIONS); + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_ifnet" }, + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_netload_p (glibtop *server) +{ + server->sysdeps.netload = _glibtop_sysdeps_netload; + + if (kvm_nlist (server->machine.kd, nlst) < 0) + glibtop_error_io_r (server, "kvm_nlist"); +} + +/* Provides Network statistics. */ + +void +glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, + const char *interface) +{ + struct ifnet ifnet; + u_long ifnetaddr, ifnetfound, ifaddraddr; + struct sockaddr *sa; + char tname [16]; + + union { + struct ifaddr ifa; + struct in_ifaddr in; + } ifaddr; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_NETLOAD), 0); + + memset (buf, 0, sizeof (glibtop_netload)); + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &ifnetaddr, sizeof (ifnetaddr)) != sizeof (ifnetaddr)) + glibtop_error_io_r (server, "kvm_read (ifnet)"); + + ifaddraddr = 0; + while (ifnetaddr || ifaddraddr) { + struct sockaddr_in *sin; + register char *cp; + + if (ifaddraddr == 0) { + ifnetfound = ifnetaddr; + + if (kvm_read (server->machine.kd, ifnetaddr, &ifnet, + sizeof (ifnet)) != sizeof (ifnet)) + glibtop_error_io_r (server, "kvm_read (ifnetaddr)"); + +#if defined(__FreeBSD__) || defined(__bsdi__) + if (kvm_read (server->machine.kd, (u_long) ifnet.if_name, + tname, 16) != 16) + glibtop_error_io_r (server, "kvm_read (if_name)"); +#else + strncpy (tname, ifnet.if_xname, 16); + tname [15] = 0; +#endif + +#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) + ifaddraddr = (u_long) ifnet.if_addrhead.tqh_first; +#elif defined(__FreeBSD__) || defined(__bsdi__) + ifaddraddr = (u_long) ifnet.if_addrlist; +#else + ifaddraddr = (u_long) ifnet.if_addrlist.tqh_first; +#endif + } + + if (ifaddraddr) { + if ((kvm_read (server->machine.kd, ifaddraddr, &ifaddr, + sizeof (ifaddr)) != sizeof (ifaddr))) + glibtop_error_io_r (server, "kvm_read (ifaddraddr)"); + +#define CP(x) ((char *)(x)) + cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + + CP(&ifaddr); sa = (struct sockaddr *)cp; + + if (!strcmp (interface, tname) && (sa->sa_family == AF_INET)) { + sin = (struct sockaddr_in *)sa; + + if (ifnet.if_flags & IFF_UP) + buf->if_flags |= GLIBTOP_IF_FLAGS_UP; + if (ifnet.if_flags & IFF_BROADCAST) + buf->if_flags |= GLIBTOP_IF_FLAGS_BROADCAST; + if (ifnet.if_flags & IFF_DEBUG) + buf->if_flags |= GLIBTOP_IF_FLAGS_DEBUG; + if (ifnet.if_flags & IFF_LOOPBACK) + buf->if_flags |= GLIBTOP_IF_FLAGS_LOOPBACK; + if (ifnet.if_flags & IFF_POINTOPOINT) + buf->if_flags |= GLIBTOP_IF_FLAGS_POINTOPOINT; + if (ifnet.if_flags & IFF_RUNNING) + buf->if_flags |= GLIBTOP_IF_FLAGS_RUNNING; + if (ifnet.if_flags & IFF_NOARP) + buf->if_flags |= GLIBTOP_IF_FLAGS_NOARP; + if (ifnet.if_flags & IFF_PROMISC) + buf->if_flags |= GLIBTOP_IF_FLAGS_PROMISC; + if (ifnet.if_flags & IFF_ALLMULTI) + buf->if_flags |= GLIBTOP_IF_FLAGS_ALLMULTI; + if (ifnet.if_flags & IFF_OACTIVE) + buf->if_flags |= GLIBTOP_IF_FLAGS_OACTIVE; + if (ifnet.if_flags & IFF_SIMPLEX) + buf->if_flags |= GLIBTOP_IF_FLAGS_SIMPLEX; + if (ifnet.if_flags & IFF_LINK0) + buf->if_flags |= GLIBTOP_IF_FLAGS_LINK0; + if (ifnet.if_flags & IFF_LINK1) + buf->if_flags |= GLIBTOP_IF_FLAGS_LINK1; + if (ifnet.if_flags & IFF_LINK2) + buf->if_flags |= GLIBTOP_IF_FLAGS_LINK2; +#ifdef __FreeBSD__ + if (ifnet.if_flags & IFF_ALTPHYS) + buf->if_flags |= GLIBTOP_IF_FLAGS_ALTPHYS; +#endif + if (ifnet.if_flags & IFF_MULTICAST) + buf->if_flags |= GLIBTOP_IF_FLAGS_MULTICAST; + +#if !defined(__bsdi__) + /* Commenting out to "fix" #13345. */ + buf->subnet = htonl (ifaddr.in.ia_subnet); +#endif + buf->address = sin->sin_addr.s_addr; + + buf->mtu = ifnet.if_mtu; + + buf->packets_in = ifnet.if_ipackets; + buf->packets_out = ifnet.if_opackets; + buf->packets_total = buf->packets_in + buf->packets_out; + + buf->bytes_in = ifnet.if_ibytes; + buf->bytes_out = ifnet.if_obytes; + buf->bytes_total = buf->bytes_in + buf->bytes_out; + + buf->errors_in = ifnet.if_ierrors; + buf->errors_out = ifnet.if_oerrors; + buf->errors_total = buf->errors_in + buf->errors_out; + + buf->collisions = ifnet.if_collisions; + buf->flags = _glibtop_sysdeps_netload; + return; + } + +#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) + ifaddraddr = (u_long)ifaddr.ifa.ifa_link.tqe_next; +#elif defined(__FreeBSD__) || defined(__bsdi__) + ifaddraddr = (u_long)ifaddr.ifa.ifa_next; +#else + ifaddraddr = (u_long)ifaddr.ifa.ifa_list.tqe_next; +#endif + } + +#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) + ifnetaddr = (u_long) ifnet.if_link.tqe_next; +#elif defined(__FreeBSD__) || defined(__bsdi__) + ifnetaddr = (u_long) ifnet.if_next; +#else + ifnetaddr = (u_long) ifnet.if_list.tqe_next; +#endif + } +} diff --git a/sysdeps/freebsd/nosuid.c b/sysdeps/freebsd/nosuid.c new file mode 100644 index 00000000..15edf79a --- /dev/null +++ b/sysdeps/freebsd/nosuid.c @@ -0,0 +1,37 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 <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/freebsd/open.c b/sysdeps/freebsd/open.c new file mode 100644 index 00000000..ea95d16f --- /dev/null +++ b/sysdeps/freebsd/open.c @@ -0,0 +1,95 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/open.h> +#include <glibtop/xmalloc.h> + +/* !!! THIS FUNCTION RUNS SUID ROOT - CHANGE WITH CAUTION !!! */ + +void +glibtop_init_p (glibtop *server, const unsigned long features, + const unsigned flags) +{ + 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) +{ +#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 (); + +#ifdef __FreeBSD__ + server->os_version_code = __FreeBSD_version; +#endif + + /* Setup machine-specific data */ + server->machine.kd = kvm_open (NULL, NULL, NULL, O_RDONLY, "kvm_open"); + + 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/freebsd/ppp.c b/sysdeps/freebsd/ppp.c new file mode 100644 index 00000000..41ab1b36 --- /dev/null +++ b/sysdeps/freebsd/ppp.c @@ -0,0 +1,144 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, October 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/ppp.h> + +#include <glibtop_suid.h> + +#ifdef HAVE_I4B + +#include <net/if.h> +#include <net/if_types.h> + +#ifdef HAVE_NET_IF_VAR_H +#include <net/if_var.h> +#endif + +#include <net/netisr.h> +#include <net/route.h> + +#if defined(__FreeBSD__) || defined(__NetBSD__) +#include <net/if_sppp.h> +#else +#include <i4b/sppp/if_sppp.h> +#endif + +/* Read `misc/i4b_acct.txt' for details ... */ +#ifdef HAVE_I4B_ACCT +#include <machine/i4b_acct.h> +#endif + +static const unsigned long _glibtop_sysdeps_ppp = +(1L << GLIBTOP_PPP_STATE); + +#ifdef HAVE_I4B_ACCT +static const unsigned long _glibtop_sysdeps_ppp_acct = +(1L << GLIBTOP_PPP_BYTES_IN) + (1L << GLIBTOP_PPP_BYTES_OUT); +#endif + +#endif /* HAVE_I4B */ + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { +#ifdef HAVE_I4B + { "_i4bisppp_softc" }, +#endif + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_ppp_p (glibtop *server) +{ +#ifdef HAVE_I4B +#ifdef HAVE_I4B_ACCT + server->sysdeps.ppp = _glibtop_sysdeps_ppp | + _glibtop_sysdeps_ppp_acct; +#else + server->sysdeps.ppp = _glibtop_sysdeps_ppp; +#endif +#endif /* HAVE_I4B */ + + if (kvm_nlist (server->machine.kd, nlst) < 0) + glibtop_error_io_r (server, "kvm_nlist"); +} + +/* Provides information about ppp usage. */ + +void +glibtop_get_ppp_p (glibtop *server, glibtop_ppp *buf, unsigned short device) +{ +#ifdef HAVE_I4B +#ifdef HAVE_I4B_ACCT + struct i4bisppp_softc data; +#else + struct sppp data; +#endif + int phase; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PPP), 0); + + memset (buf, 0, sizeof (glibtop_ppp)); + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &data, sizeof (data)) != sizeof (data)) + glibtop_error_io_r (server, "kvm_read (i4bisppp_softc)"); + +#ifdef HAVE_I4B_ACCT + phase = data.sc_if_un.scu_sp.pp_phase; +#else + /* FIXME: Which FreeBSD version have this field and + * which not. */ +#if 0 + phase = data.pp_phase; +#endif +#endif + + switch (phase) { +#ifdef HAVE_I4B_ACCT + case PHASE_DEAD: + case PHASE_TERMINATE: + buf->state = GLIBTOP_PPP_STATE_HANGUP; + break; + case PHASE_ESTABLISH: + case PHASE_NETWORK: + buf->state = GLIBTOP_PPP_STATE_ONLINE; + break; +#endif + default: + buf->state = GLIBTOP_PPP_STATE_UNKNOWN; + break; + } + + buf->flags = _glibtop_sysdeps_ppp; + +#ifdef HAVE_I4B_ACCT + buf->bytes_in = data.sc_inb; + buf->bytes_out = data.sc_outb; + buf->flags |= _glibtop_sysdeps_ppp_acct; +#endif +#endif /* HAVE_I4B */ +} diff --git a/sysdeps/freebsd/procargs.c b/sysdeps/freebsd/procargs.c new file mode 100644 index 00000000..83b6a78b --- /dev/null +++ b/sysdeps/freebsd/procargs.c @@ -0,0 +1,111 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/xmalloc.h> +#include <glibtop/procargs.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/proc.h> + +static const unsigned long _glibtop_sysdeps_proc_args = +(1L << GLIBTOP_PROC_ARGS_SIZE); + +/* Init function. */ + +void +glibtop_init_proc_args_p (glibtop *server) +{ + server->sysdeps.proc_args = _glibtop_sysdeps_proc_args; +} + +/* Provides detailed information about a process. */ + +char * +glibtop_get_proc_args_p (glibtop *server, glibtop_proc_args *buf, + pid_t pid, unsigned max_len) +{ + struct kinfo_proc *pinfo; + char *retval, **args, **ptr; + unsigned size = 0, pos = 0; + int count; + +#ifndef __bsdi__ + char filename [BUFSIZ]; + struct stat statb; +#endif + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_ARGS), 0); + + memset (buf, 0, sizeof (glibtop_proc_args)); + + /* swapper, init, pagedaemon, vmdaemon, update - this doen't work. */ + if (pid < 5) return NULL; + +#ifndef __bsdi__ + sprintf (filename, "/proc/%d/mem", pid); + if (stat (filename, &statb)) return NULL; +#endif + + glibtop_suid_enter (server); + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count < 1)) { + glibtop_suid_leave (server); + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return NULL; + } + + args = kvm_getargv (server->machine.kd, pinfo, max_len); + if (args == NULL) { + glibtop_suid_leave (server); + glibtop_warn_io_r (server, "kvm_getargv (%d)", pid); + return NULL; + } + + glibtop_suid_leave (server); + + for (ptr = args; *ptr; ptr++) + size += strlen (*ptr)+1; + + size += 2; + retval = glibtop_malloc_r (server, size); + memset (retval, 0, size); + + for (ptr = args; *ptr; ptr++) { + int len = strlen (*ptr)+1; + memcpy (retval+pos, *ptr, len); + pos += len; + } + + buf->size = pos ? pos-1 : 0; + + buf->flags = _glibtop_sysdeps_proc_args; + + return retval; +} diff --git a/sysdeps/freebsd/procdata.c b/sysdeps/freebsd/procdata.c new file mode 100644 index 00000000..65ec6822 --- /dev/null +++ b/sysdeps/freebsd/procdata.c @@ -0,0 +1,180 @@ +/* $Id$ */ + +/* 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/procdata.h> + +#include <sys/stat.h> + +#define LINUX_VERSION(x,y,z) (0x10000*(x) + 0x100*(y) + z) + +#define BIT_SHIFT(x) (1L << (x % 64)) + +static const unsigned long _glibtop_sysdeps_procdata_0 = +BIT_SHIFT(GLIBTOP_PROCDATA_CMD) + +BIT_SHIFT(GLIBTOP_PROCDATA_STATE) + +BIT_SHIFT(GLIBTOP_PROCDATA_UID) + +BIT_SHIFT(GLIBTOP_PROCDATA_PID) + +BIT_SHIFT(GLIBTOP_PROCDATA_PPID) + +BIT_SHIFT(GLIBTOP_PROCDATA_PGRP) + +BIT_SHIFT(GLIBTOP_PROCDATA_SESSION) + +BIT_SHIFT(GLIBTOP_PROCDATA_TTY) + +BIT_SHIFT(GLIBTOP_PROCDATA_TPGID) + +BIT_SHIFT(GLIBTOP_PROCDATA_PRIORITY) + +BIT_SHIFT(GLIBTOP_PROCDATA_NICE) + +BIT_SHIFT(GLIBTOP_PROCDATA_SIGNAL) + +BIT_SHIFT(GLIBTOP_PROCDATA_BLOCKED) + +BIT_SHIFT(GLIBTOP_PROCDATA_SIGIGNORE) + +BIT_SHIFT(GLIBTOP_PROCDATA_SIGCATCH) + +BIT_SHIFT(GLIBTOP_PROCDATA_START_TIME) + +BIT_SHIFT(GLIBTOP_PROCDATA_UTIME) + +BIT_SHIFT(GLIBTOP_PROCDATA_STIME) + +BIT_SHIFT(GLIBTOP_PROCDATA_CUTIME) + +BIT_SHIFT(GLIBTOP_PROCDATA_CSTIME) + +BIT_SHIFT(GLIBTOP_PROCDATA_SIZE) + +BIT_SHIFT(GLIBTOP_PROCDATA_RESIDENT) + +BIT_SHIFT(GLIBTOP_PROCDATA_SHARE) + +BIT_SHIFT(GLIBTOP_PROCDATA_TRS) + +BIT_SHIFT(GLIBTOP_PROCDATA_LRS) + +BIT_SHIFT(GLIBTOP_PROCDATA_DRS) + +BIT_SHIFT(GLIBTOP_PROCDATA_DT) + +BIT_SHIFT(GLIBTOP_PROCDATA_VSIZE) + +BIT_SHIFT(GLIBTOP_PROCDATA_RSS) + +BIT_SHIFT(GLIBTOP_PROCDATA_RSS_RLIM) + +BIT_SHIFT(GLIBTOP_PROCDATA_TIMEOUT) + +BIT_SHIFT(GLIBTOP_PROCDATA_IT_REAL_VALUE); + +static const unsigned long _glibtop_sysdeps_procdata_1 = +BIT_SHIFT(GLIBTOP_PROCDATA_K_FLAGS) + +BIT_SHIFT(GLIBTOP_PROCDATA_MIN_FLT) + +BIT_SHIFT(GLIBTOP_PROCDATA_MAJ_FLT) + +BIT_SHIFT(GLIBTOP_PROCDATA_CMIN_FLT) + +BIT_SHIFT(GLIBTOP_PROCDATA_CMAJ_FLT) + +BIT_SHIFT(GLIBTOP_PROCDATA_START_CODE) + +BIT_SHIFT(GLIBTOP_PROCDATA_END_CODE) + +BIT_SHIFT(GLIBTOP_PROCDATA_START_STACK) + +BIT_SHIFT(GLIBTOP_PROCDATA_KSTK_ESP) + +BIT_SHIFT(GLIBTOP_PROCDATA_KSTK_EIP) + +BIT_SHIFT(GLIBTOP_PROCDATA_WCHAN); + +/* Provides detailed information about a process. */ + +void +glibtop_get_procdata_s (glibtop *server, glibtop_procdata *buf, pid_t pid) +{ + char input [BUFSIZ], *tmp; + struct stat statb; + int nread; + FILE *f; + + glibtop_init_r (&server, 0, 0); + + memset (buf, 0, sizeof (glibtop_procdata)); + + if (pid == 0) { + /* Client is only interested in the flags. */ + buf->flags [0] = _glibtop_sysdeps_procdata_0; + buf->flags [1] = _glibtop_sysdeps_procdata_1; + return; + } + + + sprintf (input, "/proc/%d/stat", pid); + + if (stat (input, &statb)) return; + + buf->uid = statb.st_uid; + + f = fopen (input, "r"); + if (!f) return; + + nread = fread (input, 1, BUFSIZ, f); + + if (nread < 0) { + fclose (f); + return; + } + + input [nread] = 0; + + /* This is from guile-utils/gtop/proc/readproc.c */ + + /* split into "PID (cmd" and "<rest>" */ + tmp = strrchr (input, ')'); + *tmp = '\0'; /* replace trailing ')' with NUL */ + /* parse these two strings separately, skipping the leading "(". */ + memset (buf->cmd, 0, sizeof (buf->cmd)); + sscanf (input, "%d (%39c", &buf->pid, buf->cmd); + sscanf(tmp + 2, /* skip space after ')' too */ + "%c %d %d %d %d %d %lu %lu %lu %lu %lu " + "%ld %ld %ld %ld %d %d %lu %lu %ld %lu " + "%lu %lu %lu %lu %lu %lu %lu %d %d %d %d %lu", + &buf->state, &buf->ppid, &buf->pgrp, &buf->session, + &buf->tty, &buf->tpgid, &buf->k_flags, &buf->min_flt, + &buf->cmin_flt, &buf->maj_flt, &buf->cmaj_flt, + &buf->utime, &buf->stime, &buf->cutime, &buf->cstime, + &buf->priority, &buf->nice, &buf->timeout, + &buf->it_real_value, &buf->start_time, &buf->vsize, + &buf->rss, &buf->rss_rlim, &buf->start_code, + &buf->end_code, &buf->start_stack, &buf->kstk_esp, + &buf->kstk_eip, &buf->signal, &buf->blocked, + &buf->sigignore, &buf->sigcatch, &buf->wchan); + + if (buf->tty == 0) + /* the old notty val, update elsewhere bef. moving to 0 */ + buf->tty = -1; + + if (server->os_version_code < LINUX_VERSION(1,3,39)) { + /* map old meanings to new */ + buf->priority = 2*15 - buf->priority; + buf->nice = 15 - buf->nice; + } + if (server->os_version_code < LINUX_VERSION(1,1,30) && buf->tty != -1) + /* when tty wasn't full devno */ + buf->tty = 4*0x100 + buf->tty; + + fclose (f); + + sprintf (input, "/proc/%d/statm", pid); + + f = fopen (input, "r"); + if (!f) return; + + nread = fread (input, 1, BUFSIZ, f); + + if (nread < 0) { + fclose (f); + return; + } + + input [nread] = 0; + + sscanf (input, "%ld %ld %ld %ld %ld %ld %ld", + &buf->size, &buf->resident, &buf->share, + &buf->trs, &buf->lrs, &buf->drs, &buf->dt); + + fclose (f); + + buf->flags [0] = _glibtop_sysdeps_procdata_0; + buf->flags [1] = _glibtop_sysdeps_procdata_1; +} diff --git a/sysdeps/freebsd/prockernel.c b/sysdeps/freebsd/prockernel.c new file mode 100644 index 00000000..0dd97ab4 --- /dev/null +++ b/sysdeps/freebsd/prockernel.c @@ -0,0 +1,184 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/prockernel.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/proc.h> +#if (!defined __OpenBSD__) && (!defined __bsdi__) +#include <sys/user.h> +#endif +#if !defined(__bsdi__) && !(defined(__FreeBSD__) && defined(__alpha__)) +#include <machine/pcb.h> +#endif +#if defined(__FreeBSD__) && !defined(__alpha__) +#include <machine/tss.h> +#endif + +#include <unistd.h> +#include <fcntl.h> + +#ifdef __FreeBSD__ +#include <osreldate.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_kernel_pstats = +(1L << GLIBTOP_PROC_KERNEL_MIN_FLT) + +(1L << GLIBTOP_PROC_KERNEL_MAJ_FLT) + +(1L << GLIBTOP_PROC_KERNEL_CMIN_FLT) + +(1L << GLIBTOP_PROC_KERNEL_CMAJ_FLT); + +static const unsigned long _glibtop_sysdeps_proc_kernel_pcb = +(1L << GLIBTOP_PROC_KERNEL_KSTK_EIP) + +(1L << GLIBTOP_PROC_KERNEL_KSTK_ESP); + +static const unsigned long _glibtop_sysdeps_proc_kernel_wchan = +(1L << GLIBTOP_PROC_KERNEL_NWCHAN) + +(1L << GLIBTOP_PROC_KERNEL_WCHAN); + +/* Init function. */ + +void +glibtop_init_proc_kernel_p (glibtop *server) +{ + server->sysdeps.proc_kernel = _glibtop_sysdeps_proc_kernel_pstats | + _glibtop_sysdeps_proc_kernel_pcb | + _glibtop_sysdeps_proc_kernel_wchan; +} + +void +glibtop_get_proc_kernel_p (glibtop *server, + glibtop_proc_kernel *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + struct user *u_addr = (struct user *)USRSTACK; + struct pstats pstats; + struct pcb pcb; + int count; + + char filename [BUFSIZ]; + struct stat statb; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_KERNEL), 0); + + memset (buf, 0, sizeof (glibtop_proc_kernel)); + + if (server->sysdeps.proc_time == 0) + return; + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) + glibtop_error_io_r (server, "kvm_getprocs (%d)", pid); + + buf->nwchan = (unsigned long) pinfo [0].kp_proc.p_wchan &~ KERNBASE; + buf->flags |= (1L << GLIBTOP_PROC_KERNEL_NWCHAN); + + if (pinfo [0].kp_proc.p_wchan && pinfo [0].kp_proc.p_wmesg) { + strncpy (buf->wchan, pinfo [0].kp_eproc.e_wmesg, + sizeof (buf->wchan) - 1); + buf->wchan [sizeof (buf->wchan) - 1] = 0; + buf->flags |= (1L << GLIBTOP_PROC_KERNEL_WCHAN); + } else { + buf->wchan [0] = 0; + } + + /* Taken from `saveuser ()' in `/usr/src/bin/ps/ps.c'. */ + + /* [FIXME]: /usr/include/sys/user.h tells me that the user area + * may or may not be at the same kernel address in all + * processes, but I don't see any way to get that address. + * Since `ps' simply uses its own address, I think it's + * safe to do this here, too. */ + + /* NOTE: You need to mount the /proc filesystem to make + * `kvm_uread' work. */ + + sprintf (filename, "/proc/%d/mem", (int) pid); + if (stat (filename, &statb)) return; + + glibtop_suid_enter (server); + + if ((pinfo [0].kp_proc.p_flag & P_INMEM) && + kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, + (unsigned long) &u_addr->u_stats, + (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) + { + /* + * The u-area might be swapped out, and we can't get + * at it because we have a crashdump and no swap. + * If it's here fill in these fields, otherwise, just + * leave them 0. + */ + + buf->min_flt = (u_int64_t) pstats.p_ru.ru_minflt; + buf->maj_flt = (u_int64_t) pstats.p_ru.ru_majflt; + buf->cmin_flt = (u_int64_t) pstats.p_cru.ru_minflt; + buf->cmaj_flt = (u_int64_t) pstats.p_cru.ru_majflt; + + buf->flags |= _glibtop_sysdeps_proc_kernel_pstats; + } + + if ((pinfo [0].kp_proc.p_flag & P_INMEM) && + kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, + (unsigned long) &u_addr->u_pcb, + (char *) &pcb, sizeof (pcb)) == sizeof (pcb)) + { +#ifdef __FreeBSD__ +#ifndef __alpha__ +#if (__FreeBSD_version >= 300003) + buf->kstk_esp = (u_int64_t) pcb.pcb_esp; + buf->kstk_eip = (u_int64_t) pcb.pcb_eip; +#else + buf->kstk_esp = (u_int64_t) pcb.pcb_ksp; + buf->kstk_eip = (u_int64_t) pcb.pcb_pc; +#endif +#else + /*xxx FreeBSD/Alpha? */ +#endif +#else + buf->kstk_esp = (u_int64_t) pcb.pcb_tss.tss_esp0; +#ifdef __bsdi__ + buf->kstk_eip = (u_int64_t) pcb.pcb_tss.tss_eip; +#else + buf->kstk_eip = (u_int64_t) pcb.pcb_tss.__tss_eip; +#endif + + buf->flags |= _glibtop_sysdeps_proc_kernel_pcb; +#endif + } + + /* Taken from `wchan ()' in `/usr/src/bin/ps/print.c'. */ + + glibtop_suid_leave (server); +} diff --git a/sysdeps/freebsd/proclist.c b/sysdeps/freebsd/proclist.c new file mode 100644 index 00000000..20353ec5 --- /dev/null +++ b/sysdeps/freebsd/proclist.c @@ -0,0 +1,103 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/xmalloc.h> +#include <glibtop/proclist.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_proclist = +(1L << GLIBTOP_PROCLIST_TOTAL) + (1L << GLIBTOP_PROCLIST_NUMBER) + +(1L << GLIBTOP_PROCLIST_SIZE); + +/* Fetch list of currently running processes. + * The interface of this function is a little bit different from the others: + * buf->flags is only set if the call succeeded, in this case pids_chain, + * a list of the pids of all currently running processes is returned, + * buf->number is the number of elements of this list and buf->size is + * the size of one single element (sizeof (unsigned)). The total size is + * stored in buf->total. + * + * The calling function has to free the memory to which a pointer is returned. + * + * IMPORTANT NOTE: + * On error, this function MUST return NULL and set buf->flags to zero ! + * On success, it returnes a pointer to a list of buf->number elements + * each buf->size big. The total size is stored in buf->total. + * The calling function has to free the memory to which a pointer is returned. + * + * On error, NULL is returned and buf->flags is zero. */ + +/* Init function. */ + +void +glibtop_init_proclist_p (glibtop *server) +{ + server->sysdeps.proclist = _glibtop_sysdeps_proclist; +} + +unsigned * +glibtop_get_proclist_p (glibtop *server, glibtop_proclist *buf, + int64_t real_which, int64_t arg) +{ + struct kinfo_proc *pinfo; + unsigned *pids = NULL; + int which, count; + int i,j; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROCLIST), 0); + + memset (buf, 0, sizeof (glibtop_proclist)); + + which = (int)(real_which & GLIBTOP_KERN_PROC_MASK); + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, which, arg, &count); + if ((pinfo == NULL) || (count < 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (proclist)"); + return NULL; + } + count--; + + /* Allocate count objects in the pids_chain array + * Same as malloc is pids is NULL, which it is. */ + pids = glibtop_realloc_r (server, pids, count * sizeof (unsigned)); + /* Copy the pids over to this chain */ + for (i=j=0; i < count; i++) { + if ((real_which & GLIBTOP_EXCLUDE_IDLE) && + (pinfo[i].kp_proc.p_stat != SRUN)) + continue; + else if ((real_which & GLIBTOP_EXCLUDE_SYSTEM) && + (pinfo[i].kp_eproc.e_pcred.p_ruid == 0)) + continue; + pids [j++] = (unsigned) pinfo[i].kp_proc.p_pid; + } /* end for */ + /* Set the fields in buf */ + buf->number = j; + buf->size = sizeof (unsigned); + buf->total = j * sizeof (unsigned); + buf->flags = _glibtop_sysdeps_proclist; + return pids; +} diff --git a/sysdeps/freebsd/procmap.c b/sysdeps/freebsd/procmap.c new file mode 100644 index 00000000..f29445b5 --- /dev/null +++ b/sysdeps/freebsd/procmap.c @@ -0,0 +1,266 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/xmalloc.h> +#include <glibtop/procmap.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/resource.h> +#include <vm/vm_object.h> +#include <vm/vm_prot.h> +#include <vm/vm_map.h> + +#include <sys/vnode.h> +#include <sys/mount.h> +#include <ufs/ufs/quota.h> +#include <ufs/ufs/inode.h> + +#include <sys/ucred.h> +#if (!defined __OpenBSD__) && (!defined __bsdi__) +#include <sys/user.h> +#endif +#include <sys/sysctl.h> +#include <vm/vm.h> + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +/* Fixme ... */ +#undef _KERNEL +#define _UVM_UVM_AMAP_I_H_ 1 +#define _UVM_UVM_MAP_I_H_ 1 +#include <uvm/uvm.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_map = +(1L << GLIBTOP_PROC_MAP_TOTAL) + (1L << GLIBTOP_PROC_MAP_NUMBER) + +(1L << GLIBTOP_PROC_MAP_SIZE); + +static const unsigned long _glibtop_sysdeps_map_entry = +(1L << GLIBTOP_MAP_ENTRY_START) + (1L << GLIBTOP_MAP_ENTRY_END) + +(1L << GLIBTOP_MAP_ENTRY_OFFSET) + (1L << GLIBTOP_MAP_ENTRY_PERM) + +(1L << GLIBTOP_MAP_ENTRY_INODE) + (1L << GLIBTOP_MAP_ENTRY_DEVICE); + +/* Init function. */ + +void +glibtop_init_proc_map_p (glibtop *server) +{ + server->sysdeps.proc_map = _glibtop_sysdeps_proc_map; +} + +/* Provides detailed information about a process. */ + +glibtop_map_entry * +glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + struct vm_map_entry entry, *first; + struct vmspace vmspace; +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + struct vnode vnode; + struct inode inode; +#else + struct vm_object object; +#endif + glibtop_map_entry *maps; +#if defined __FreeBSD__ + struct vnode vnode; + struct inode inode; + struct mount mount; +#endif + int count, i = 0; + int update = 0; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_MAP), 0); + + memset (buf, 0, sizeof (glibtop_proc_map)); + + /* It does not work for the swapper task. */ + if (pid == 0) return NULL; + + glibtop_suid_enter (server); + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count < 1)) + glibtop_error_io_r (server, "kvm_getprocs (%d)", pid); + + /* Now we get the memory maps. */ + + if (kvm_read (server->machine.kd, + (unsigned long) pinfo [0].kp_proc.p_vmspace, + (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace)) + glibtop_error_io_r (server, "kvm_read (vmspace)"); + + first = vmspace.vm_map.header.next; + + if (kvm_read (server->machine.kd, + (unsigned long) vmspace.vm_map.header.next, + (char *) &entry, sizeof (entry)) != sizeof (entry)) + glibtop_error_io_r (server, "kvm_read (entry)"); + + /* Allocate space. */ + + buf->number = vmspace.vm_map.nentries; + buf->size = sizeof (glibtop_map_entry); + + buf->total = buf->number * buf->size; + + maps = glibtop_malloc_r (server, buf->total); + + memset (maps, 0, buf->total); + + buf->flags = _glibtop_sysdeps_proc_map; + + /* Walk through the `vm_map_entry' list ... */ + + /* I tested this a few times with `mmap'; as soon as you write + * to the mmap'ed area, the object type changes from OBJT_VNODE + * to OBJT_DEFAULT so if seems this really works. */ + + do { + if (update) { + if (kvm_read (server->machine.kd, + (unsigned long) entry.next, + &entry, sizeof (entry)) != sizeof (entry)) + glibtop_error_io_r (server, "kvm_read (entry)"); + } else { + update = 1; + } + +#ifdef __FreeBSD__ +#if __FreeBSD__ >= 4 + if (entry.eflags & (MAP_ENTRY_IS_SUB_MAP)) + continue; +#else + if (entry.eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) + continue; +#endif +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (UVM_ET_ISSUBMAP (&entry)) + continue; +#else + if (entry.is_a_map || entry.is_sub_map) + continue; +#endif +#endif + + maps [i].flags = _glibtop_sysdeps_map_entry; + + maps [i].start = entry.start; + maps [i].end = entry.end; + maps [i].offset = entry.offset; + + maps [i].perm = 0; + + if (entry.protection & VM_PROT_READ) + maps [i].perm |= GLIBTOP_MAP_PERM_READ; + if (entry.protection & VM_PROT_WRITE) + maps [i].perm |= GLIBTOP_MAP_PERM_WRITE; + if (entry.protection & VM_PROT_EXECUTE) + maps [i].perm |= GLIBTOP_MAP_PERM_EXECUTE; + + i++; + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (!entry.object.uvm_obj) + continue; + + /* We're only interested in vnodes */ + + if (kvm_read (server->machine.kd, + (unsigned long) entry.object.uvm_obj, + &vnode, sizeof (vnode)) != sizeof (vnode)) { + glibtop_warn_io_r (server, "kvm_read (vnode)"); + return NULL; + } +#else + if (!entry.object.vm_object) + continue; + + /* We're only interested in `vm_object's */ + + if (kvm_read (server->machine.kd, + (unsigned long) entry.object.vm_object, + &object, sizeof (object)) != sizeof (object)) + glibtop_error_io_r (server, "kvm_read (object)"); +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (!vnode.v_uvm.u_flags & UVM_VNODE_VALID) + continue; + + if ((vnode.v_type != VREG) || (vnode.v_tag != VT_UFS) || + !vnode.v_data) continue; + + if (kvm_read (server->machine.kd, + (unsigned long) vnode.v_data, + &inode, sizeof (inode)) != sizeof (inode)) + glibtop_error_io_r (server, "kvm_read (inode)"); + + maps [i-1].inode = inode.i_number; + maps [i-1].device = inode.i_dev; +#endif + + +#ifdef __FreeBSD__ + /* If the object is of type vnode, add its size */ + + if (object.type != OBJT_VNODE) + continue; + + if (!object.handle) + continue; + + if (kvm_read (server->machine.kd, + (unsigned long) object.handle, + &vnode, sizeof (vnode)) != sizeof (vnode)) + glibtop_error_io_r (server, "kvm_read (vnode)"); + + if ((vnode.v_type != VREG) || (vnode.v_tag != VT_UFS) || + !vnode.v_data) continue; + + if (kvm_read (server->machine.kd, + (unsigned long) vnode.v_data, + &inode, sizeof (inode)) != sizeof (inode)) + glibtop_error_io_r (server, "kvm_read (inode)"); + + if (kvm_read (server->machine.kd, + (unsigned long) vnode.v_mount, + &mount, sizeof (mount)) != sizeof (mount)) + glibtop_error_io_r (server, "kvm_read (mount)"); + + maps [i-1].inode = inode.i_number; + maps [i-1].device = inode.i_dev; +#endif + } while (entry.next != first); + + return maps; +} diff --git a/sysdeps/freebsd/procmem.c b/sysdeps/freebsd/procmem.c new file mode 100644 index 00000000..05f66001 --- /dev/null +++ b/sysdeps/freebsd/procmem.c @@ -0,0 +1,259 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procmem.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/resource.h> +#include <vm/vm_object.h> +#include <vm/vm_map.h> + +#include <sys/vnode.h> +#include <ufs/ufs/quota.h> +#include <ufs/ufs/inode.h> + +#include <sys/ucred.h> +#if (!defined __OpenBSD__) && (!defined __bsdi__) +#include <sys/user.h> +#endif +#include <sys/sysctl.h> +#include <vm/vm.h> + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +/* Fixme ... */ +#undef _KERNEL +#define _UVM_UVM_AMAP_I_H_ 1 +#define _UVM_UVM_MAP_I_H_ 1 +#include <uvm/uvm.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_mem = +(1L << GLIBTOP_PROC_MEM_SIZE) + +(1L << GLIBTOP_PROC_MEM_VSIZE) + +(1L << GLIBTOP_PROC_MEM_RESIDENT) + +(1L << GLIBTOP_PROC_MEM_RSS) + +(1L << GLIBTOP_PROC_MEM_RSS_RLIM); + +static const unsigned long _glibtop_sysdeps_proc_mem_share = +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +(1L << GLIBTOP_PROC_MEM_SHARE); +#elif defined(__FreeBSD__) +(1L << GLIBTOP_PROC_MEM_SHARE); +#else +0; +#endif + +#ifndef LOG1024 +#define LOG1024 10 +#endif + +/* these are for getting the memory statistics */ +static int pageshift; /* log base 2 of the pagesize */ + +/* define pagetok in terms of pageshift */ +#define pagetok(size) ((size) << pageshift) + +/* Init function. */ + +void +glibtop_init_proc_mem_p (glibtop *server) +{ + register int pagesize; + + /* get the page size with "getpagesize" and calculate pageshift + * from it */ + pagesize = getpagesize (); + pageshift = 0; + while (pagesize > 1) { + pageshift++; + pagesize >>= 1; + } + + /* we only need the amount of log(2)1024 for our conversion */ + pageshift -= LOG1024; + + server->sysdeps.proc_mem = _glibtop_sysdeps_proc_mem | + _glibtop_sysdeps_proc_mem_share; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + struct vm_map_entry entry, *first; + struct vmspace *vms, vmspace; +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + struct vnode vnode; + struct inode inode; +#else + struct vm_object object; +#endif + struct plimit plimit; + int count; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_MEM), 0); + + memset (buf, 0, sizeof (glibtop_proc_mem)); + + if (server->sysdeps.proc_mem == 0) + return; + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count < 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } + + if (kvm_read (server->machine.kd, + (unsigned long) pinfo [0].kp_proc.p_limit, + (char *) &plimit, sizeof (plimit)) != sizeof (plimit)) { + glibtop_warn_io_r (server, "kvm_read (plimit)"); + return; + } + + buf->rss_rlim = (u_int64_t) + (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur); + + vms = &pinfo [0].kp_eproc.e_vm; + + buf->vsize = buf->size = (u_int64_t) pagetok + (vms->vm_tsize + vms->vm_dsize + vms->vm_ssize) << LOG1024; + + buf->resident = buf->rss = (u_int64_t) pagetok + (vms->vm_rssize) << LOG1024; + + /* Now we get the shared memory. */ + + if (kvm_read (server->machine.kd, + (unsigned long) pinfo [0].kp_proc.p_vmspace, + (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace)) { + glibtop_warn_io_r (server, "kvm_read (vmspace)"); + return; + } + + first = vmspace.vm_map.header.next; + + if (kvm_read (server->machine.kd, + (unsigned long) vmspace.vm_map.header.next, + (char *) &entry, sizeof (entry)) != sizeof (entry)) { + glibtop_warn_io_r (server, "kvm_read (entry)"); + return; + } + + /* Walk through the `vm_map_entry' list ... */ + + /* I tested this a few times with `mmap'; as soon as you write + * to the mmap'ed area, the object type changes from OBJT_VNODE + * to OBJT_DEFAULT so if seems this really works. */ + + while (entry.next != first) { + if (kvm_read (server->machine.kd, + (unsigned long) entry.next, + &entry, sizeof (entry)) != sizeof (entry)) { + glibtop_warn_io_r (server, "kvm_read (entry)"); + return; + } + +#ifdef __FreeBSD__ +#if __FreeBSD__ >= 4 + if (entry.eflags & (MAP_ENTRY_IS_SUB_MAP)) + continue; +#else + if (entry.eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) + continue; +#endif +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (UVM_ET_ISSUBMAP (&entry)) + continue; +#else + if (entry.is_a_map || entry.is_sub_map) + continue; +#endif +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (!entry.object.uvm_obj) + continue; + + /* We're only interested in vnodes */ + + if (kvm_read (server->machine.kd, + (unsigned long) entry.object.uvm_obj, + &vnode, sizeof (vnode)) != sizeof (vnode)) { + glibtop_warn_io_r (server, "kvm_read (vnode)"); + return; + } +#else + if (!entry.object.vm_object) + continue; + + /* We're only interested in `vm_object's */ + + if (kvm_read (server->machine.kd, + (unsigned long) entry.object.vm_object, + &object, sizeof (object)) != sizeof (object)) { + glibtop_warn_io_r (server, "kvm_read (object)"); + return; + } +#endif + /* If the object is of type vnode, add its size */ + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + if (!vnode.v_uvm.u_flags & UVM_VNODE_VALID) + continue; + + if ((vnode.v_type != VREG) || (vnode.v_tag != VT_UFS) || + !vnode.v_data) continue; + + /* Reference count must be at least two. */ + if (vnode.v_uvm.u_obj.uo_refs <= 1) + continue; + + buf->share += pagetok (vnode.v_uvm.u_obj.uo_npages) << LOG1024; +#endif + +#ifdef __FreeBSD__ + if (object.type != OBJT_VNODE) + continue; + + buf->share += object.un_pager.vnp.vnp_size; +#endif + } + + buf->flags = _glibtop_sysdeps_proc_mem | + _glibtop_sysdeps_proc_mem_share; +} diff --git a/sysdeps/freebsd/procsegment.c b/sysdeps/freebsd/procsegment.c new file mode 100644 index 00000000..915472ef --- /dev/null +++ b/sysdeps/freebsd/procsegment.c @@ -0,0 +1,82 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procsegment.h> + +#include <glibtop_suid.h> + +#include <kvm.h> +#include <sys/param.h> +#include <sys/sysctl.h> + +static const unsigned long _glibtop_sysdeps_proc_segment = 0; + +/* Init function. */ + +void +glibtop_init_proc_segment_p (glibtop *server) +{ + server->sysdeps.proc_segment = _glibtop_sysdeps_proc_segment; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_segment_p (glibtop *server, + glibtop_proc_segment *buf, + pid_t pid) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_SEGMENT), 0); + + memset (buf, 0, sizeof (glibtop_proc_segment)); + +#if 0 + /* Get the process info from the kernel */ + kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, count); + if (*count != 1) { + return; /* the zeroed-out buffer indicating no data */ + } + + /* trs: text resident set size + pinfo[0]->kp_eproc.e_xrssize; + */ + /* buf->trs = pinfo[0]->kp_eproc.e_xrssize; */ + /* lrs: shared-lib resident set size + ? */ + /* drs: data resident set size + pinfo[0]->kp_eproc.e_vm.vm_map.vm_dsize; + */ + /* dt: dirty pages + */ + /* start_code: address of beginning of code segment + + */ + /* end_code: address of end of code segment + */ + /* start_stack: address of the bottom of stack segment + */ +#endif +} + diff --git a/sysdeps/freebsd/procsignal.c b/sysdeps/freebsd/procsignal.c new file mode 100644 index 00000000..6ee36cab --- /dev/null +++ b/sysdeps/freebsd/procsignal.c @@ -0,0 +1,107 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procsignal.h> + +#include <glibtop_suid.h> + +#ifdef __FreeBSD__ +#include <osreldate.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_signal = +(1L << GLIBTOP_PROC_SIGNAL_SIGNAL) + +(1L << GLIBTOP_PROC_SIGNAL_BLOCKED) + +(1L << GLIBTOP_PROC_SIGNAL_SIGIGNORE) + +(1L << GLIBTOP_PROC_SIGNAL_SIGCATCH); + +/* Init function. */ + +void +glibtop_init_proc_signal_p (glibtop *server) +{ + server->sysdeps.proc_signal = _glibtop_sysdeps_proc_signal; +} + +void +glibtop_get_proc_signal_p (glibtop *server, + glibtop_proc_signal *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + int count = 0; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_SIGNAL), 0); + + memset (buf, 0, sizeof (glibtop_proc_signal)); + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } + + /* signal: mask of pending signals. + * pinfo [0].kp_proc.p_siglist + */ +#if (defined(__NetBSD__) && (NSIG > 32)) || (__FreeBSD_version >= 400011) + buf->signal [0] = pinfo [0].kp_proc.p_siglist.__bits[0]; +#else + buf->signal [0] = pinfo [0].kp_proc.p_siglist; +#endif + + /* blocked: mask of blocked signals. + * pinfo [0].kp_proc.p_sigmask + */ +#if (defined(__NetBSD__) && (NSIG > 32)) || (__FreeBSD_version >= 400011) + buf->blocked [0] = pinfo [0].kp_proc.p_sigmask.__bits[0]; +#else + buf->blocked [0] = pinfo [0].kp_proc.p_sigmask; +#endif + + /* sigignore: mask of ignored signals. + * pinfo [0].kp_proc.p_sigignore + */ +#if (defined(__NetBSD__) && (NSIG > 32)) || (__FreeBSD_version >= 400011) + buf->sigignore [0] = pinfo [0].kp_proc.p_sigignore.__bits[0]; +#else + buf->sigignore [0] = pinfo [0].kp_proc.p_sigignore; +#endif + + /* sigcatch: mask of caught signals. + * pinfo [0].kp_proc.p_sigcatch + */ +#if (defined(__NetBSD__) && (NSIG > 32)) || (__FreeBSD_version >= 400011) + buf->sigcatch [0] = pinfo [0].kp_proc.p_sigcatch.__bits[0]; +#else + buf->sigcatch [0] = pinfo [0].kp_proc.p_sigcatch; +#endif + + buf->flags = _glibtop_sysdeps_proc_signal; +} diff --git a/sysdeps/freebsd/procstate.c b/sysdeps/freebsd/procstate.c new file mode 100644 index 00000000..2357b393 --- /dev/null +++ b/sysdeps/freebsd/procstate.c @@ -0,0 +1,137 @@ +/* $Id$ */ + +/* 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procstate.h> + +#include <glibtop_suid.h> + +#if !defined(__OpenBSD__) +//&& (!defined __bsdi__) +#include <sys/user.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_state = +(1L << GLIBTOP_PROC_STATE_CMD) + (1L << GLIBTOP_PROC_STATE_UID) + +(1L << GLIBTOP_PROC_STATE_GID); + +static const unsigned long _glibtop_sysdeps_proc_state_new = +#if LIBGTOP_VERSION_CODE >= 1001000 +(1L << GLIBTOP_PROC_STATE_RUID) + (1L << GLIBTOP_PROC_STATE_RGID); +#else +0; +#endif + +/* Init function. */ + +void +glibtop_init_proc_state_p (glibtop *server) +{ + server->sysdeps.proc_state = _glibtop_sysdeps_proc_state | + _glibtop_sysdeps_proc_state_new; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_state_p (glibtop *server, + glibtop_proc_state *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + int count = 0; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_STATE), 0); + + memset (buf, 0, sizeof (glibtop_proc_state)); + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } + + strncpy (buf->cmd, pinfo [0].kp_proc.p_comm, sizeof (buf->cmd)-1); + buf->cmd [sizeof (buf->cmd)-1] = 0; + + buf->uid = pinfo [0].kp_eproc.e_pcred.p_svuid; + buf->gid = pinfo [0].kp_eproc.e_pcred.p_svgid; + +#if LIBGTOP_VERSION_CODE >= 1001000 + buf->ruid = pinfo [0].kp_eproc.e_pcred.p_ruid; + buf->rgid = pinfo [0].kp_eproc.e_pcred.p_rgid; +#endif + + /* Set the flags for the data we're about to return*/ + buf->flags = _glibtop_sysdeps_proc_state | + _glibtop_sysdeps_proc_state_new; + +#if LIBGTOP_VERSION_CODE >= 1001000 + switch (pinfo [0].kp_proc.p_stat) { + case SIDL: + buf->state = 0; + break; + case SRUN: + buf->state = GLIBTOP_PROCESS_RUNNING; + break; + case SSLEEP: + buf->state = GLIBTOP_PROCESS_INTERRUPTIBLE; + break; + case SSTOP: + buf->state = GLIBTOP_PROCESS_STOPPED; + break; + case SZOMB: + buf->state = GLIBTOP_PROCESS_ZOMBIE; + break; + default: + return; + } +#else + switch (pinfo [0].kp_proc.p_stat) { + case SIDL: + buf->state = 'S'; + break; + case SRUN: + buf->state = 'R'; + break; + case SSLEEP: + buf->state = 'S'; + break; + case SSTOP: + buf->state = 'T'; + break; + case SZOMB: + buf->state = 'Z'; + break; + default: + return; + } +#endif + + buf->flags |= (1L << GLIBTOP_PROC_STATE_STATE); +} diff --git a/sysdeps/freebsd/proctime.c b/sysdeps/freebsd/proctime.c new file mode 100644 index 00000000..0c71c593 --- /dev/null +++ b/sysdeps/freebsd/proctime.c @@ -0,0 +1,229 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/proctime.h> + +#include <glibtop_suid.h> + +#ifdef __FreeBSD__ +#include <osreldate.h> +#endif + +static const unsigned long _glibtop_sysdeps_proc_time = +(1L << GLIBTOP_PROC_TIME_RTIME) + (1L << GLIBTOP_PROC_TIME_FREQUENCY); + +static const unsigned long _glibtop_sysdeps_proc_time_user = +(1L << GLIBTOP_PROC_TIME_UTIME) + (1L << GLIBTOP_PROC_TIME_STIME) + +(1L << GLIBTOP_PROC_TIME_CUTIME) + (1L << GLIBTOP_PROC_TIME_CSTIME) + +(1L << GLIBTOP_PROC_TIME_START_TIME); + +#define tv2sec(tv) (((u_int64_t) tv.tv_sec * 1000000) + (u_int64_t) tv.tv_usec) + +/* Init function. */ + +void +glibtop_init_proc_time_p (glibtop *server) +{ + server->sysdeps.proc_time = _glibtop_sysdeps_proc_time | + _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(p, up, sp, ip) + struct proc *p; + struct timeval *up; + struct timeval *sp; + struct timeval *ip; +{ + quad_t totusec; + u_quad_t u, st, ut, it, tot; +#if (__FreeBSD_version < 300003) + long sec, usec; +#endif + 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; + } + +#if (defined __FreeBSD__) && (__FreeBSD_version >= 300003) + + /* This was changed from a `struct timeval' into a `u_int64_t' + * on FreeBSD 3.0 and renamed p_rtime -> p_runtime. + */ + + totusec = (u_quad_t) p->p_runtime; +#else + sec = p->p_rtime.tv_sec; + usec = p->p_rtime.tv_usec; + + totusec = (quad_t)sec * 1000000 + usec; +#endif + + 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 +glibtop_get_proc_time_p (glibtop *server, glibtop_proc_time *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; +#if (defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) || (defined(OpenBSD) && (OpenBSD >= 199912)) + register struct rusage *rup; +#else + struct user *u_addr = (struct user *)USRSTACK; +#endif + struct pstats pstats; + int count; + + char filename [BUFSIZ]; + struct stat statb; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_TIME), 0); + + memset (buf, 0, sizeof (glibtop_proc_time)); + + /* It does not work for the swapper task. */ + if (pid == 0) return; + +#if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) + if (server->sysdeps.proc_time == 0) + return; + +#ifndef __bsdi__ + sprintf (filename, "/proc/%d/mem", (int) pid); + if (stat (filename, &statb)) return; +#endif +#endif + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) + glibtop_error_io_r (server, "kvm_getprocs (%d)", pid); + +#if (defined __FreeBSD__) && (__FreeBSD_version >= 300003) + buf->rtime = pinfo [0].kp_proc.p_runtime; +#else + buf->rtime = tv2sec (pinfo [0].kp_proc.p_rtime); +#endif + + buf->frequency = 1000000; + buf->flags = _glibtop_sysdeps_proc_time; + +#if (defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) || (defined(OpenBSD) && (OpenBSD >= 199912)) + glibtop_suid_enter (server); + + if (kvm_read (server->machine.kd, + (unsigned long) pinfo [0].kp_proc.p_stats, + &pstats, sizeof (pstats)) != sizeof (pstats)) { + glibtop_warn_io_r (server, "kvm_read (pstats)"); + return; + } + + glibtop_suid_leave (server); + + rup = &pstats.p_ru; + calcru(&(pinfo [0]).kp_proc, + &rup->ru_utime, &rup->ru_stime, NULL); + + buf->utime = tv2sec (pstats.p_ru.ru_utime); + buf->stime = tv2sec (pstats.p_ru.ru_stime); + + buf->cutime = tv2sec (pstats.p_cru.ru_utime); + buf->cstime = tv2sec (pstats.p_cru.ru_stime); + + buf->start_time = (u_int64_t) pstats.p_start.tv_sec; + + buf->flags |= _glibtop_sysdeps_proc_time_user; +#else + glibtop_suid_enter (server); + + if ((pinfo [0].kp_proc.p_flag & P_INMEM) && + kvm_uread (server->machine.kd, &(pinfo [0]).kp_proc, + (unsigned long) &u_addr->u_stats, + (char *) &pstats, sizeof (pstats)) == sizeof (pstats)) + { + /* This is taken form the kernel source code of + * FreeBSD 2.2.6. */ + + /* Well, we just do the same getrusage () does ... */ + + register struct rusage *rup; + + glibtop_suid_leave (server); + + rup = &pstats.p_ru; + calcru(&(pinfo [0]).kp_proc, + &rup->ru_utime, &rup->ru_stime, NULL); + + buf->utime = tv2sec (pstats.p_ru.ru_utime); + buf->stime = tv2sec (pstats.p_ru.ru_stime); + + buf->cutime = tv2sec (pstats.p_cru.ru_utime); + buf->cstime = tv2sec (pstats.p_cru.ru_stime); + + buf->start_time = tv2sec (pstats.p_start); + + buf->flags = _glibtop_sysdeps_proc_time_user; + } + + glibtop_suid_leave (server); +#endif +} + diff --git a/sysdeps/freebsd/procuid.c b/sysdeps/freebsd/procuid.c new file mode 100644 index 00000000..03c4598a --- /dev/null +++ b/sysdeps/freebsd/procuid.c @@ -0,0 +1,128 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/procuid.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_proc_uid = +(1L << GLIBTOP_PROC_UID_UID) + (1L << GLIBTOP_PROC_UID_EUID) + +(1L << GLIBTOP_PROC_UID_EGID) + (1L << GLIBTOP_PROC_UID_PID) + +(1L << GLIBTOP_PROC_UID_PPID) + (1L << GLIBTOP_PROC_UID_PGRP) + +(1L << GLIBTOP_PROC_UID_TPGID) + (1L << GLIBTOP_PROC_UID_PRIORITY) + +(1L << GLIBTOP_PROC_UID_NICE); + +static const unsigned long _glibtop_sysdeps_proc_uid_groups = +#if LIBGTOP_VERSION_CODE >= 1001000 +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +(1L << GLIBTOP_PROC_UID_NGROUPS) + (1L << GLIBTOP_PROC_UID_GROUPS); +#else +0L; +#endif +#else /* LIBGTOP_VERSION_CODE < 1001000 */ +0L; +#endif + +/* Init function. */ + +void +glibtop_init_proc_uid_p (glibtop *server) +{ + server->sysdeps.proc_uid = _glibtop_sysdeps_proc_uid | + _glibtop_sysdeps_proc_uid_groups; +} + +/* Provides detailed information about a process. */ + +void +glibtop_get_proc_uid_p (glibtop *server, glibtop_proc_uid *buf, + pid_t pid) +{ + struct kinfo_proc *pinfo; + int count = 0; + +#if LIBGTOP_VERSION_CODE >= 1001000 +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + struct ucred ucred; + void *ucred_ptr; +#endif +#endif + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_UID), 0); + + memset (buf, 0, sizeof (glibtop_proc_uid)); + + /* It does not work for the swapper task. */ + if (pid == 0) return; + + /* Get the process information */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count != 1)) { + glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid); + return; + } + + buf->uid = pinfo [0].kp_eproc.e_pcred.p_ruid; + buf->euid = pinfo [0].kp_eproc.e_pcred.p_svuid; + buf->gid = pinfo [0].kp_eproc.e_pcred.p_rgid; + buf->egid = pinfo [0].kp_eproc.e_pcred.p_svgid; + + buf->ppid = pinfo [0].kp_eproc.e_ppid; + buf->pgrp = pinfo [0].kp_eproc.e_pgid; + buf->tpgid = pinfo [0].kp_eproc.e_tpgid; + + buf->nice = pinfo [0].kp_proc.p_nice; + buf->priority = pinfo [0].kp_proc.p_priority; + + /* Set the flags for the data we're about to return*/ + buf->flags = _glibtop_sysdeps_proc_uid; + + /* Use LibGTop conditionals here so we can more easily merge this + * code into the LIBGTOP_STABLE_1_0 branch. */ +#if LIBGTOP_VERSION_CODE >= 1001000 + /* This probably also works with other versions, but not yet + * tested. Please remove the conditional if this is true. */ +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + ucred_ptr = (void *) pinfo [0].kp_eproc.e_pcred.pc_ucred; + + if (ucred_ptr) { + if (kvm_read (server->machine.kd, (unsigned long) ucred_ptr, + &ucred, sizeof (ucred)) != sizeof (ucred)) { + glibtop_warn_io_r (server, "kvm_read (ucred)"); + } else { + int count = (ucred.cr_ngroups < GLIBTOP_MAX_GROUPS) ? + ucred.cr_ngroups : GLIBTOP_MAX_GROUPS; + int i; + + for (i = 0; i < count; i++) + buf->groups [i] = ucred.cr_groups [i]; + buf->ngroups = count; + + buf->flags |= _glibtop_sysdeps_proc_uid_groups; + } + } +#endif +#endif +} diff --git a/sysdeps/freebsd/sem_limits.c b/sysdeps/freebsd/sem_limits.c new file mode 100644 index 00000000..c9a177de --- /dev/null +++ b/sysdeps/freebsd/sem_limits.c @@ -0,0 +1,120 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, August 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/sem_limits.h> + +#include <glibtop_suid.h> + +#if defined(__bsdi__) && (_BSDI_VERSION < 199700) +/* Older versions of BSDI don't seem to have this. */ + +void +glibtop_init_sem_limits_p (glibtop *server) +{ } + +void +glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SEM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_sem_limits)); +} + +#else + +/* #define KERNEL to get declaration of `struct seminfo'. */ + +#if (defined(__FreeBSD__) && (__FreeBSD_version < 410000)) || defined(__bsdi__) +#define KERNEL 1 +#else +#define _KERNEL 1 +#endif + +#include <sys/ipc.h> +#include <sys/sem.h> + +static unsigned long _glibtop_sysdeps_sem_limits = +(1L << GLIBTOP_IPC_SEMMAP) + (1L << GLIBTOP_IPC_SEMMNI) + +(1L << GLIBTOP_IPC_SEMMNS) + (1L << GLIBTOP_IPC_SEMMNU) + +(1L << GLIBTOP_IPC_SEMMSL) + (1L << GLIBTOP_IPC_SEMOPM) + +(1L << GLIBTOP_IPC_SEMUME) + (1L << GLIBTOP_IPC_SEMUSZ) + +(1L << GLIBTOP_IPC_SEMVMX) + (1L << GLIBTOP_IPC_SEMAEM); + +/* The values in this structure never change at runtime, so we only + * read it once during initialization. We have to use the name `_seminfo' + * since `seminfo' is already declared external in <sys/sem.h>. */ +static struct seminfo _seminfo; + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_seminfo" }, + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_sem_limits_p (glibtop *server) +{ + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (sem_limits)"); + return; + } + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &_seminfo, sizeof (_seminfo)) != sizeof (_seminfo)) { + glibtop_warn_io_r (server, "kvm_read (seminfo)"); + return; + } + + server->sysdeps.sem_limits = _glibtop_sysdeps_sem_limits; +} + +/* Provides information about sysv sem limits. */ + +void +glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SEM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_sem_limits)); + + if (server->sysdeps.sem_limits == 0) + return; + + buf->semmap = _seminfo.semmap; + buf->semmni = _seminfo.semmni; + buf->semmns = _seminfo.semmns; + buf->semmnu = _seminfo.semmnu; + buf->semmsl = _seminfo.semmsl; + buf->semopm = _seminfo.semopm; + buf->semvmx = _seminfo.semvmx; + buf->semaem = _seminfo.semaem; + + buf->flags = _glibtop_sysdeps_sem_limits; +} + +#endif /* either a newer BSDI or no BSDI at all. */ + diff --git a/sysdeps/freebsd/shm_limits.c b/sysdeps/freebsd/shm_limits.c new file mode 100644 index 00000000..5abe88e8 --- /dev/null +++ b/sysdeps/freebsd/shm_limits.c @@ -0,0 +1,115 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, August 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/shm_limits.h> + +#include <glibtop_suid.h> + +#if defined(__bsdi__) && (_BSDI_VERSION < 199700) +/* Older versions of BSDI don't seem to have this. */ + +void +glibtop_init_shm_limits_p (glibtop *server) +{ } + +void +glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SHM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_shm_limits)); +} + +#else + +/* #define KERNEL to get declaration of `struct shminfo'. */ + +#if (defined(__FreeBSD__) && (__FreeBSD_version < 410000)) || defined(__bsdi__) +#define KERNEL 1 +#else +#define _KERNEL 1 +#endif + +#include <sys/ipc.h> +#include <sys/shm.h> + +static unsigned long _glibtop_sysdeps_shm_limits = +(1L << GLIBTOP_IPC_SHMMAX) + (1L << GLIBTOP_IPC_SHMMIN) + +(1L << GLIBTOP_IPC_SHMMNI) + (1L << GLIBTOP_IPC_SHMSEG) + +(1L << GLIBTOP_IPC_SHMALL); + +/* The values in this structure never change at runtime, so we only + * read it once during initialization. We have to use the name `_shminfo' + * since `shminfo' is already declared external in <sys/shm.h>. */ +static struct shminfo _shminfo; + +/* nlist structure for kernel access */ +static struct nlist nlst [] = { + { "_shminfo" }, + { 0 } +}; + +/* Init function. */ + +void +glibtop_init_shm_limits_p (glibtop *server) +{ + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (shm_limits)"); + return; + } + + if (kvm_read (server->machine.kd, nlst [0].n_value, + &_shminfo, sizeof (_shminfo)) != sizeof (_shminfo)) { + glibtop_warn_io_r (server, "kvm_read (shminfo)"); + return; + } + + server->sysdeps.shm_limits = _glibtop_sysdeps_shm_limits; +} + +/* Provides information about sysv ipc limits. */ + +void +glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf) +{ + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SHM_LIMITS), 0); + + memset (buf, 0, sizeof (glibtop_shm_limits)); + + if (server->sysdeps.shm_limits == 0) + return; + + buf->shmmax = _shminfo.shmmax; + buf->shmmin = _shminfo.shmmin; + buf->shmmni = _shminfo.shmmni; + buf->shmseg = _shminfo.shmseg; + buf->shmall = _shminfo.shmall; + + buf->flags = _glibtop_sysdeps_shm_limits; +} + +#endif /* either a newer BSDI or no BSDI at all. */ + diff --git a/sysdeps/freebsd/siglist.c b/sysdeps/freebsd/siglist.c new file mode 100644 index 00000000..94abfdc6 --- /dev/null +++ b/sysdeps/freebsd/siglist.c @@ -0,0 +1,28 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 <glibtop.h> +#include <glibtop/signal.h> + +const glibtop_signame glibtop_sys_siglist [] = +{ { 0, NULL, NULL } }; diff --git a/sysdeps/freebsd/swap.c b/sysdeps/freebsd/swap.c new file mode 100644 index 00000000..d9669fa6 --- /dev/null +++ b/sysdeps/freebsd/swap.c @@ -0,0 +1,426 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/swap.h> + +#include <glibtop/xmalloc.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_swap = +(1L << GLIBTOP_SWAP_TOTAL) + (1L << GLIBTOP_SWAP_USED) + +(1L << GLIBTOP_SWAP_FREE) + (1L << GLIBTOP_SWAP_PAGEIN) + +(1L << GLIBTOP_SWAP_PAGEOUT); + +#if defined(__FreeBSD__) || defined(__bsdi__) + +#include <sys/conf.h> +#ifdef __bsdi__ +#include <vm/swap_pager.h> +#else +#if __FreeBSD_version < 400005 +#include <sys/rlist.h> +#endif +#endif +#include <sys/vmmeter.h> + +/* nlist structure for kernel access */ + +#if defined(__bsdi__) +static struct nlist nlst [] = { + { "_swapstats" }, /* general swap info */ + { 0 } +}; +#elif __FreeBSD__ < 4 +static struct nlist nlst [] = { +#define VM_SWAPLIST 0 + { "_swaplist" },/* list of free swap areas */ +#define VM_SWDEVT 1 + { "_swdevt" }, /* list of swap devices and sizes */ +#define VM_NSWAP 2 + { "_nswap" }, /* size of largest swap device */ +#define VM_NSWDEV 3 + { "_nswdev" }, /* number of swap devices */ +#define VM_DMMAX 4 + { "_dmmax" }, /* maximum size of a swap block */ + { 0 } +}; +#endif + +#elif defined(__NetBSD__) + +#if (__NetBSD_Version__ >= 104000000) +#include <uvm/uvm_extern.h> +#include <sys/swap.h> +#else +#include <vm/vm_swap.h> +#endif + +#endif + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) +static int mib_uvmexp [] = { CTL_VM, VM_UVMEXP }; +#else +/* nlist structure for kernel access */ +static struct nlist nlst2 [] = { + { "_cnt" }, + { 0 } +}; +#endif + +/* Init function. */ + +void +glibtop_init_swap_p (glibtop *server) +{ +#if defined(__FreeBSD__) || defined(__bsdi__) +#if __FreeBSD__ < 4 || defined(__bsdi__) + if (kvm_nlist (server->machine.kd, nlst) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (swap)"); + return; + } +#else + struct kvm_swap dummy; + + if (kvm_getswapinfo (server->machine.kd, &dummy, 1, 0) != 0) { + glibtop_warn_io_r (server, "kvm_swap (swap)"); + return; + } +#endif +#endif + +#if !(defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)) + if (kvm_nlist (server->machine.kd, nlst2) < 0) { + glibtop_warn_io_r (server, "kvm_nlist (cnt)"); + return; + } +#endif + + server->sysdeps.swap = _glibtop_sysdeps_swap; +} + +/* Provides information about swap usage. */ + +/* + * This function is based on a program called swapinfo written + * by Kevin Lahey <kml@rokkaku.atl.ga.us>. + */ + +void +glibtop_get_swap_p (glibtop *server, glibtop_swap *buf) +{ +#if defined(__FreeBSD__) + +# if __FreeBSD__ < 4 + char *header; + int hlen, nswdev, dmmax; + int div, nfree, npfree; + struct swdevt *sw; + long blocksize, *perdev; + struct rlist head; + struct rlisthdr swaplist; + struct rlist *swapptr; + size_t sw_size; + u_long ptr; +# else + int nswdev; + struct kvm_swap kvmsw[16]; +# endif + +#elif defined(__bsdi__) + struct swapstats swap; +#elif defined(__NetBSD__) + struct swapent *swaplist; +#endif + + int nswap, i; + int avail = 0, inuse = 0; + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + struct uvmexp uvmexp; + size_t length_uvmexp; +#else + /* To get `pagein' and `pageout'. */ + struct vmmeter vmm; +#endif + static int swappgsin = -1; + static int swappgsout = -1; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_SWAP), 0); + + memset (buf, 0, sizeof (glibtop_swap)); + + if (server->sysdeps.swap == 0) + return; + +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + length_uvmexp = sizeof (uvmexp); + if (sysctl (mib_uvmexp, 2, &uvmexp, &length_uvmexp, NULL, 0)) { + glibtop_warn_io_r (server, "sysctl (uvmexp)"); + return; + } +#else + /* This is used to get the `pagein' and `pageout' members. */ + + if (kvm_read (server->machine.kd, nlst2[0].n_value, + &vmm, sizeof (vmm)) != sizeof (vmm)) { + glibtop_warn_io_r (server, "kvm_read (cnt)"); + return; + } +#endif + + if (swappgsin < 0) { + buf->pagein = 0; + buf->pageout = 0; + } else { +#ifdef __FreeBSD__ + buf->pagein = vmm.v_swappgsin - swappgsin; + buf->pageout = vmm.v_swappgsout - swappgsout; +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + buf->pagein = uvmexp.swapins - swappgsin; + buf->pageout = uvmexp.swapouts - swappgsout; +#else + buf->pagein = vmm.v_swpin - swappgsin; + buf->pageout = vmm.v_swpout - swappgsout; +#endif +#endif + } + +#ifdef __FreeBSD__ + swappgsin = vmm.v_swappgsin; + swappgsout = vmm.v_swappgsout; +#else +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) + swappgsin = uvmexp.swapins; + swappgsout = uvmexp.swapouts; +#else + swappgsin = vmm.v_swpin; + swappgsout = vmm.v_swpout; +#endif +#endif + +#if defined(__FreeBSD__) + +#if __FreeBSD__ < 4 + + /* Size of largest swap device. */ + + if (kvm_read (server->machine.kd, nlst[VM_NSWAP].n_value, + &nswap, sizeof (nswap)) != sizeof (nswap)) { + glibtop_warn_io_r (server, "kvm_read (nswap)"); + return; + } + + /* Number of swap devices. */ + + if (kvm_read (server->machine.kd, nlst[VM_NSWDEV].n_value, + &nswdev, sizeof (nswdev)) != sizeof (nswdev)) { + glibtop_warn_io_r (server, "kvm_read (nswdev)"); + return; + } + + /* Maximum size of a swap block. */ + + if (kvm_read (server->machine.kd, nlst[VM_DMMAX].n_value, + &dmmax, sizeof (dmmax)) != sizeof (dmmax)) { + glibtop_warn_io_r (server, "kvm_read (dmmax)"); + return; + } + + /* List of free swap areas. */ + + if (kvm_read (server->machine.kd, nlst[VM_SWAPLIST].n_value, + &swaplist, sizeof (swaplist)) != sizeof (swaplist)) { + glibtop_warn_io_r (server, "kvm_read (swaplist)"); + return; + } + + /* Kernel offset of list of swap devices and sizes. */ + + if (kvm_read (server->machine.kd, nlst[VM_SWDEVT].n_value, + &ptr, sizeof (ptr)) != sizeof (ptr)) { + glibtop_warn_io_r (server, "kvm_read (swdevt)"); + return; + } + + /* List of swap devices and sizes. */ + + sw_size = nswdev * sizeof (*sw); + sw = glibtop_malloc_r (server, sw_size); + + if (kvm_read (server->machine.kd, ptr, sw, sw_size) != (ssize_t)sw_size) { + glibtop_warn_io_r (server, "kvm_read (*swdevt)"); + return; + } + + perdev = glibtop_malloc (nswdev * sizeof (*perdev)); + + /* Count up swap space. */ + + nfree = 0; + memset (perdev, 0, nswdev * sizeof(*perdev)); + + swapptr = swaplist.rlh_list; + + while (swapptr) { + int top, bottom, next_block; + + if (kvm_read (server->machine.kd, (int) swapptr, &head, + sizeof (struct rlist)) != sizeof (struct rlist)) { + glibtop_warn_io_r (server, "kvm_read (swapptr)"); + return; + } + + top = head.rl_end; + bottom = head.rl_start; + + nfree += top - bottom + 1; + + /* + * Swap space is split up among the configured disks. + * + * For interleaved swap devices, the first dmmax blocks + * of swap space some from the first disk, the next dmmax + * blocks from the next, and so on up to nswap blocks. + * + * The list of free space joins adjacent free blocks, + * ignoring device boundries. If we want to keep track + * of this information per device, we'll just have to + * extract it ourselves. + */ + while (top / dmmax != bottom / dmmax) { + next_block = ((bottom + dmmax) / dmmax); + perdev[(bottom / dmmax) % nswdev] += + next_block * dmmax - bottom; + bottom = next_block * dmmax; + } + perdev[(bottom / dmmax) % nswdev] += + top - bottom + 1; + + swapptr = head.rl_next; + } + + header = getbsize (&hlen, &blocksize); + + div = blocksize / 512; + avail = npfree = 0; + for (i = 0; i < nswdev; i++) { + int xsize, xfree; + + /* + * Don't report statistics for partitions which have not + * yet been activated via swapon(8). + */ + if (!(sw[i].sw_flags & SW_FREED)) + continue; + + /* The first dmmax is never allocated to avoid trashing of + * disklabels + */ + xsize = sw[i].sw_nblks - dmmax; + xfree = perdev[i]; + inuse = xsize - xfree; + npfree++; + avail += xsize; + } + + /* + * If only one partition has been set up via swapon(8), we don't + * need to bother with totals. + */ + inuse = avail - nfree; + + glibtop_free_r (server, sw); + glibtop_free_r (server, perdev); + + buf->flags = _glibtop_sysdeps_swap; + + buf->used = inuse; + buf->free = avail; + + buf->total = inuse + avail; + +#else + + nswdev = kvm_getswapinfo(server->machine.kd, kvmsw, 16, 0); + + buf->flags = _glibtop_sysdeps_swap; + + buf->used = kvmsw[nswdev].ksw_used; + buf->total = kvmsw[nswdev].ksw_total; + + buf->free = buf->total - buf->used; + +#endif + +#elif defined(__bsdi__) + + /* General info about swap devices. */ + + if (kvm_read (server->machine.kd, nlst[0].n_value, + &swap, sizeof (swap)) != sizeof (swap)) { + glibtop_warn_io_r (server, "kvm_read (swap)"); + return; + } + + buf->flags = _glibtop_sysdeps_swap; + + buf->used = swap.swap_total - swap.swap_free; + buf->free = swap.swap_free; + + buf->total = swap.swap_total; + +#elif defined(__NetBSD__) + + nswap = swapctl (SWAP_NSWAP, NULL, 0); + if (nswap < 0) { + glibtop_warn_io_r (server, "swapctl (SWAP_NSWAP)"); + return; + } + + swaplist = glibtop_calloc_r (server, nswap, sizeof (struct swapent)); + + if (swapctl (SWAP_STATS, swaplist, nswap) != nswap) { + glibtop_warn_io_r (server, "swapctl (SWAP_STATS)"); + glibtop_free_r (server, swaplist); + return; + } + + for (i = 0; i < nswap; i++) { + avail += swaplist[i].se_nblks; + inuse += swaplist[i].se_inuse; + } + + glibtop_free_r (server, swaplist); + + buf->flags = _glibtop_sysdeps_swap; + + buf->used = inuse; + buf->free = avail; + + buf->total = inuse + avail; +#endif +} diff --git a/sysdeps/freebsd/uptime.c b/sysdeps/freebsd/uptime.c new file mode 100644 index 00000000..250a72d1 --- /dev/null +++ b/sysdeps/freebsd/uptime.c @@ -0,0 +1,73 @@ +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 <glibtop.h> +#include <glibtop/error.h> +#include <glibtop/uptime.h> + +#include <glibtop/cpu.h> + +#include <glibtop_suid.h> + +static const unsigned long _glibtop_sysdeps_uptime = +(1L << GLIBTOP_UPTIME_UPTIME) + (1L << GLIBTOP_UPTIME_IDLETIME); + +static const unsigned long _required_cpu_flags = +(1L << GLIBTOP_CPU_TOTAL) + (1L << GLIBTOP_CPU_IDLE) + +(1L << GLIBTOP_CPU_FREQUENCY); + +/* Init function. */ + +void +glibtop_init_uptime_p (glibtop *server) +{ + server->sysdeps.uptime = _glibtop_sysdeps_uptime; +} + +/* Provides uptime and idle time. */ + +void +glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf) +{ + glibtop_cpu cpu; + + glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_UPTIME), 0); + + memset (buf, 0, sizeof (glibtop_uptime)); + + /* We simply calculate it from the CPU usage. */ + + glibtop_get_cpu_p (server, &cpu); + + /* Make sure all required fields are present. */ + + if ((cpu.flags & _required_cpu_flags) != _required_cpu_flags) + return; + + /* Calculate values. */ + + buf->uptime = (double) cpu.total / (double) cpu.frequency; + buf->idletime = (double) cpu.idle / (double) cpu.frequency; + + buf->flags = _glibtop_sysdeps_uptime; +} |