**** Merged from LIBGTOP_1_1_2_PATCHES ****

This commit is contained in:
Martin Baulig
2001-02-14 23:07:41 +00:00
parent 2698263164
commit 0bd5a6c082
29 changed files with 1182 additions and 231 deletions

View File

@@ -4,3 +4,4 @@ Makefile
Makefile.in Makefile.in
libgtop_sysdeps.la libgtop_sysdeps.la
*.lo *.lo
libgtop_sysdeps_suid.la

2
sysdeps/solaris/AUTHORS Normal file
View File

@@ -0,0 +1,2 @@
Drazen Kacar (dave@srce.hr)
Martin Baulig (martin@home-of-linux.org)

View File

@@ -1,3 +1,131 @@
1999-10-17 Martin Baulig <martin@home-of-linux.org>
* Makefile.am (libgtop_sysdeps_la_LIBADD): Added `@DL_LIB@'.
1999-09-28 Drazen Kacar <dave@srce.hr>
* proclist.c (glibtop_get_proclist_s): Bugfix. It wasn't
excluding system, non-tty or idle processes if that was
requested.
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.
1999-07-16 Drazen Kacar <dave@srce.hr>
* proclist.c: Bug fix. All Solaris versions have RUID and
RGID in /proc.
1999-06-07 Drazen Kacar <dave@srce.hr>
* glibtop_machine.h, open.c, procargs.c, proclist.c, procmap.c:
Solaris 2.5 & 2.5.1 portability fixes, based on patches
from Steve Murphy <murf@e-tools.com>.
1999-05-30 Drazen Kacar <dave@srce.hr>
* procargs.c: Fixed bug in calculation of process argument list.
1999-05-27 Drazen Kacar <dave@srce.hr>
* glibtop_machine.h, open.c, procmap.c: Get the file name
from inode number.
1999-05-17 Drazen Kacar <dave@srce.hr>
* procargs.c: Implemented what Solaris has to offer cheaply.
It sucks, but digging in process address space would be
too slow.
1999-05-11 Drazen Kacar <dave@srce.hr>
* proctime.c: Return 0 usage times for scheaduler (PID 0).
1999-05-10 Drazen Kacar <dave@srce.hr>
* proclist.c: Added process selection mechanism. It's not
included in Solaris 2.5 build, since we first have to decide
what will be dispatched to daemon.
1999-05-10 Drazen Kacar <dave@srce.hr>
There be some useful documentation now. Syncing...
* mem.c: Output values in bytes, as the documentation requires.
It was a bit odd when gtop reported 256K of total memory.
1999-05-09 Drazen Kacar <dave@srce.hr>
* glibtop_machine.h, procdata.c, proclist.c, procmap.c, procmem.c,
procsignal.c, procstate.c, procuid.c, open.c, mem.c: Initial
Solaris 2.5 port. It's far from being complete and hasn't been
tested properly. We'll need setuid root daemon, which is
currently not implemented. #ifdef symbols to check are
HAVE_PROCFS_H and KSTAT_DATA_UINT32. These will be defined on
Solaris 2.6 and later, but not on earlier releases.
1999-05-08 Drazen Kacar <dave@srce.hr>
* safeio.c, safeio.h: Added s_open(), s_close() etc. with EINTR
wrappers.
* procdata.c, procmap.c, proclist.c: Use them.
1999-05-08 Drazen Kacar <dave@srce.hr>
* procmem.c: Use bytes as units for memory consumption.
1999-05-08 Drazen Kacar <dave@srce.hr>
* procuid.c: Fixed nice value.
1999-05-08 Martin Baulig <martin@home-of-linux.org>
Use the setgid server for IPC Limits.
* shm_limits.c, msg_limits.c, sem_limits.c: Moved them into the
setgid server since they need to access kvm data.
* open_suid.c, close_suid.c: New file. We do the initialization and cleanup
for the setgid server here.
* glibtop_suid.h: New file. We include this in the setgid files.
* open.c: Moved kvm opening code into open_suid.c.
1999-05-07 Drazen Kacar <dave@srce.hr>
* glibtop_machine.h, open.c, mem.c, procmem.c: machine.pagesize
is now number of bits we need for shifting, ie. 2^pagesize
will give pagesize in Kb.
1999-05-07 Drazen Kacar <dave@srce.hr>
* procmem.c: Implemented size, vsize, resident and rss.
1999-05-06 Drazen Kacar <dave@srce.hr>
* siglist.c: Fixed, valid for Solaris 2.6 & 7.
1999-05-06 Drazen Kacar <dave@srce.hr>
* glibtop_private.h, procuid.c, procdata.c: List of supplementary
groups was not correct. Fixed.
1999-05-04 Drazen Kacar <dave@srce.hr>
* glibtop_machine.h: Changed boot time to unsigned long long.
* open.c: Added proper type checking for boot value. There's
no point in saving a few nanoseconds in init function. And
one day it will become 64-bit value.
In glibtop_get_kstats(): Don't reread vminfo_snaptime when
reinitializing kstats.
1999-05-03 Drazen Kacar <dave@srce.hr> 1999-05-03 Drazen Kacar <dave@srce.hr>
* glibtop_private.h: Fixed typoo. * glibtop_private.h: Fixed typoo.

View File

@@ -2,17 +2,25 @@ LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
INCLUDES = @INCLUDES@ INCLUDES = @INCLUDES@
lib_LTLIBRARIES = libgtop_sysdeps.la lib_LTLIBRARIES = libgtop_sysdeps.la libgtop_sysdeps_suid.la
libgtop_sysdeps_la_SOURCES = open.c close.c siglist.c cpu.c mem.c swap.c \ libgtop_sysdeps_la_SOURCES = open.c close.c siglist.c cpu.c mem.c \
uptime.c loadavg.c shm_limits.c msg_limits.c \ safeio.c swap.c uptime.c loadavg.c \
sem_limits.c proclist.c procstate.c procuid.c \ proclist.c procstate.c procuid.c \
proctime.c procmem.c procsignal.c prockernel.c \ proctime.c procmem.c procsignal.c \
procsegment.c procargs.c procmap.c netload.c \ prockernel.c procsegment.c procargs.c \
ppp.c procdata.c procmap.c netload.c ppp.c procdata.c
libgtop_sysdeps_la_LDFLAGS = $(LT_VERSION_INFO) libgtop_sysdeps_la_LDFLAGS = $(LT_VERSION_INFO)
include_HEADERS = glibtop_server.h glibtop_machine.h libgtop_sysdeps_la_LIBADD = @DL_LIB@
noinst_HEADERS = glibtop_private.h
libgtop_sysdeps_suid_la_SOURCES = open_suid.c close_suid.c \
shm_limits.c msg_limits.c sem_limits.c
libgtop_sysdeps_suid_la_LDFLAGS = $(LT_VERSION_INFO)
include_HEADERS = glibtop_server.h glibtop_machine.h
noinst_HEADERS = glibtop_private.h glibtop_suid.h safeio.h

View File

@@ -0,0 +1,30 @@
/* $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/close.h>
/* Closes pipe to gtop server. */
void
glibtop_close_p (glibtop *server)
{ }

View File

@@ -35,7 +35,10 @@ static const unsigned long _glibtop_sysdeps_cpu =
(1L << GLIBTOP_CPU_SYS) + (1L << GLIBTOP_CPU_IDLE) + (1L << GLIBTOP_CPU_SYS) + (1L << GLIBTOP_CPU_IDLE) +
(1L << GLIBTOP_XCPU_TOTAL) + (1L << GLIBTOP_XCPU_USER) + (1L << GLIBTOP_XCPU_TOTAL) + (1L << GLIBTOP_XCPU_USER) +
(1L << GLIBTOP_XCPU_SYS) + (1L << GLIBTOP_XCPU_IDLE) + (1L << GLIBTOP_XCPU_SYS) + (1L << GLIBTOP_XCPU_IDLE) +
(1L << GLIBTOP_CPU_FREQUENCY) + (1L << GLIBTOP_XCPU_FLAGS); #if LIBGTOP_VERSION_CODE >= 1001002
(1L << GLIBTOP_XCPU_FLAGS) +
#endif
(1L << GLIBTOP_CPU_FREQUENCY);
/* Init function. */ /* Init function. */
@@ -77,7 +80,11 @@ glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf)
++found; ++found;
if(p_online(cpu, P_STATUS) == P_ONLINE) if(p_online(cpu, P_STATUS) == P_ONLINE)
#if LIBGTOP_VERSION_CODE >= 1001002
buf->xcpu_flags |= (1L << cpu); buf->xcpu_flags |= (1L << cpu);
#else
;
#endif
else else
continue; continue;
ret = kstat_read (kc, ksp, &cpu_stat); ret = kstat_read (kc, ksp, &cpu_stat);

View File

@@ -25,7 +25,11 @@
#define __GLIBTOP_MACHINE_H__ #define __GLIBTOP_MACHINE_H__
#include <sys/param.h> #include <sys/param.h>
#ifdef HAVE_PROCFS_H
#include <procfs.h> #include <procfs.h>
#else
#include <sys/procfs.h>
#endif
#include <fcntl.h> #include <fcntl.h>
#include <kstat.h> #include <kstat.h>
@@ -40,6 +44,7 @@ struct _glibtop_machine
{ {
uid_t uid, euid; uid_t uid, euid;
gid_t gid, egid; gid_t gid, egid;
pid_t me; /* Don't ask why we need this */
kvm_t *kd; kvm_t *kd;
@@ -51,13 +56,21 @@ struct _glibtop_machine
kstat_t *cpu_stat_kstat [64]; kstat_t *cpu_stat_kstat [64];
kstat_t *system; /* boot_time & avenrun* where needed */ kstat_t *system; /* boot_time & avenrun* where needed */
kstat_t *syspages; /* memory usage */ kstat_t *syspages; /* memory usage */
kstat_t *bunyip; /* more memory usage */ kstat_t *bunyip; /* more memory usage */
int pagesize; /* in kilobytes */ int pagesize; /* in bits to shift, ie. 2^pagesize gives Kb */
int ticks; /* clock ticks, as returned by sysconf(_SC_CLK_TCK) */ int ticks; /* clock ticks, as returned by sysconf() */
unsigned boot; /* boot time, it's ui32 in kstat */ unsigned long long boot; /* boot time, although it's ui32 in kstat */
void *libproc; /* libproc handle */
#if GLIBTOP_SOLARIS_RELEASE >= 560
void (*objname)(void *, uintptr_t, const char *, size_t);
struct ps_prochandle *(*pgrab)(pid_t, int, int *);
void (*pfree)(void *);
#else
void *filler[3];
#endif
}; };
END_LIBGTOP_DECLS END_LIBGTOP_DECLS

View File

@@ -28,23 +28,37 @@
#include <glibtop/error.h> #include <glibtop/error.h>
#include <sys/param.h> #include <sys/param.h>
#include <procfs.h>
#include <kstat.h> #include <kstat.h>
#include <fcntl.h> #include <fcntl.h>
#if defined(HAVE_PROCFS_H)
# include <procfs.h>
#elif defined(HAVE_SYS_PROCFS_H)
# include <sys/procfs.h>
#else
# error Cannot compile without <procfs.h> or <sys/procfs.h>
#endif
BEGIN_LIBGTOP_DECLS BEGIN_LIBGTOP_DECLS
#ifdef HAVE_PROCFS_H
/* Read /proc/<pid>/psinfo */ /* Read /proc/<pid>/psinfo */
int glibtop_get_proc_data_psinfo_s (glibtop *server, struct psinfo *psinfo, pid_t pid); int glibtop_get_proc_data_psinfo_s(glibtop *, struct psinfo *, pid_t pid);
/* Read /proc/<pid>/usage */
int glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t pid);
/* Read /proc/<pid>/cred */
int glibtop_get_proc_credentials_s(glibtop *, struct prcred *, pid_t);
/* Read /proc/<pid>/status */ /* Read /proc/<pid>/status */
int glibtop_get_proc_status_s(glibtop *, struct pstatus *, pid_t); int glibtop_get_proc_status_s(glibtop *, struct pstatus *, pid_t);
#else
int glibtop_get_proc_data_psinfo_s(glibtop *, struct prpsinfo *, pid_t);
int glibtop_get_proc_status_s(glibtop *, struct prstatus *, pid_t);
#endif
/* Read /proc/<pid>/usage */
int glibtop_get_proc_data_usage_s(glibtop *, struct prusage *, pid_t);
#if LIBGTOP_VERSION_CODE >= 1001002
/* Read /proc/<pid>/cred */
int glibtop_get_proc_credentials_s(glibtop *, struct prcred *, gid_t *, pid_t);
#endif
/* Reread kstat chains */ /* Reread kstat chains */
void glibtop_get_kstats(glibtop *); void glibtop_get_kstats(glibtop *);

View File

@@ -31,9 +31,9 @@ BEGIN_LIBGTOP_DECLS
#define GLIBTOP_SUID_SWAP 0 #define GLIBTOP_SUID_SWAP 0
#define GLIBTOP_SUID_UPTIME 0 #define GLIBTOP_SUID_UPTIME 0
#define GLIBTOP_SUID_LOADAVG 0 #define GLIBTOP_SUID_LOADAVG 0
#define GLIBTOP_SUID_SHM_LIMITS 0 #define GLIBTOP_SUID_SHM_LIMITS (1L << GLIBTOP_SYSDEPS_SHM_LIMITS)
#define GLIBTOP_SUID_MSG_LIMITS 0 #define GLIBTOP_SUID_MSG_LIMITS (1L << GLIBTOP_SYSDEPS_MSG_LIMITS)
#define GLIBTOP_SUID_SEM_LIMITS 0 #define GLIBTOP_SUID_SEM_LIMITS (1L << GLIBTOP_SYSDEPS_SEM_LIMITS)
#define GLIBTOP_SUID_PROCLIST 0 #define GLIBTOP_SUID_PROCLIST 0
#define GLIBTOP_SUID_PROC_STATE 0 #define GLIBTOP_SUID_PROC_STATE 0
#define GLIBTOP_SUID_PROC_UID 0 #define GLIBTOP_SUID_PROC_UID 0

View File

@@ -0,0 +1,48 @@
/* $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
static inline void glibtop_suid_enter (glibtop *server) {
setreuid (server->machine.uid, server->machine.euid);
};
static inline void glibtop_suid_leave (glibtop *server) {
if (setreuid (server->machine.euid, server->machine.uid))
_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

View File

@@ -57,9 +57,13 @@ glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
kstat_named_t *kn; kstat_named_t *kn;
int pagesize = server->machine.pagesize; int pagesize = server->machine.pagesize;
#ifndef KSTAT_DATA_UINT32
#define ui32 ul
#endif
memset (buf, 0, sizeof (glibtop_mem)); memset (buf, 0, sizeof (glibtop_mem));
buf->total = (u_int64_t)sysconf(_SC_PHYS_PAGES) * pagesize; buf->total = (u_int64_t)sysconf(_SC_PHYS_PAGES) << pagesize << 10;
buf->flags = _glibtop_sysdeps_mem_os_sysconf; buf->flags = _glibtop_sysdeps_mem_os_sysconf;
if(!kc) if(!kc)
@@ -77,18 +81,18 @@ glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
if(kn) if(kn)
{ {
#ifdef _LP64 #ifdef _LP64
buf->free = kn->value.ui64 * pagesize; buf->free = kn->value.ui64 << pagesize << 10;
#else #else
buf->free = kn->value.ui32 * pagesize; buf->free = kn->value.ui32 << pagesize << 10;
#endif #endif
buf->used = buf->total - buf->free; buf->used = buf->total - buf->free;
} }
kn = (kstat_named_t *)kstat_data_lookup(ksp, "pageslocked"); kn = (kstat_named_t *)kstat_data_lookup(ksp, "pageslocked");
if(kn) if(kn)
#ifdef _LP64 #ifdef _LP64
buf->locked = kn->value.ui64 * pagesize; buf->locked = kn->value.ui64 << pagesize;
#else #else
buf->locked = kn->value.ui32 * pagesize; buf->locked = kn->value.ui32 << pagesize;
#endif #endif
buf->flags += _glibtop_sysdeps_mem_os_kstat; buf->flags += _glibtop_sysdeps_mem_os_kstat;
} }
@@ -100,23 +104,23 @@ glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_anon"); kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_anon");
if(kn) if(kn)
#ifdef _LP64 #ifdef _LP64
buf->user = kn->value.ui64 * pagesize; buf->user = kn->value.ui64 << pagesize << 10;
#else #else
buf->user = kn->value.ui32 * pagesize; buf->user = kn->value.ui32 << pagesize << 10;
#endif #endif
kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_exec"); kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_exec");
if(kn) if(kn)
#ifdef _LP64 #ifdef _LP64
buf->shared = kn->value.ui64 * pagesize; buf->shared = kn->value.ui64 << pagesize << 10;
#else #else
buf->shared = kn->value.ui32 * pagesize; buf->shared = kn->value.ui32 << pagesize << 10;
#endif #endif
kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_vnode"); kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_vnode");
if(kn) if(kn)
#ifdef _LP64 #ifdef _LP64
buf->buffer = kn->value.ui64 * pagesize; buf->buffer = kn->value.ui64 << pagesize << 10;
#else #else
buf->buffer = kn->value.ui32 * pagesize; buf->buffer = kn->value.ui32 << pagesize << 10;
#endif #endif
buf->flags += _glibtop_sysdeps_mem_bunyip; buf->flags += _glibtop_sysdeps_mem_bunyip;
} }

View File

@@ -37,7 +37,7 @@ static const unsigned long _glibtop_sysdeps_msg_limits =
/* Init function. */ /* Init function. */
void void
glibtop_init_msg_limits_s (glibtop *server) glibtop_init_msg_limits_p (glibtop *server)
{ {
kvm_t *kd = server->machine.kd; kvm_t *kd = server->machine.kd;
@@ -50,7 +50,7 @@ glibtop_init_msg_limits_s (glibtop *server)
/* Provides information about sysv ipc limits. */ /* Provides information about sysv ipc limits. */
void void
glibtop_get_msg_limits_s (glibtop *server, glibtop_msg_limits *buf) glibtop_get_msg_limits_p (glibtop *server, glibtop_msg_limits *buf)
{ {
kvm_t *kd = server->machine.kd; kvm_t *kd = server->machine.kd;
struct msginfo minfo; struct msginfo minfo;

View File

@@ -22,8 +22,10 @@
*/ */
#include <glibtop/open.h> #include <glibtop/open.h>
#include <glibtop/cpu.h>
#include <unistd.h> #include <unistd.h>
#include <dlfcn.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/processor.h> #include <sys/processor.h>
@@ -60,7 +62,9 @@ glibtop_get_kstats(glibtop *server)
if(ksp) if(ksp)
{ {
kstat_read(kc, ksp, &server->machine.vminfo); kstat_read(kc, ksp, &server->machine.vminfo);
server->machine.vminfo_snaptime = ksp->ks_snaptime; /* Don't change snaptime if we only need to reinitialize kstats */
if(!(server->machine.vminfo_snaptime))
server->machine.vminfo_snaptime = ksp->ks_snaptime;
} }
/* We don't know why was kstat chain invalidated. It could have /* We don't know why was kstat chain invalidated. It could have
@@ -69,7 +73,7 @@ glibtop_get_kstats(glibtop *server)
life time of a process, but let's hope that's just an error in life time of a process, but let's hope that's just an error in
the documentation. */ the documentation. */
if(nproc_same = new_ncpu == server->ncpu) if((nproc_same = new_ncpu) == server->ncpu)
{ {
int checked, i; int checked, i;
char cpu[20]; char cpu[20];
@@ -128,10 +132,14 @@ glibtop_open_s (glibtop *server, const char *program_name,
kstat_ctl_t *kc; kstat_ctl_t *kc;
kstat_t *ksp; kstat_t *ksp;
kstat_named_t *kn; kstat_named_t *kn;
int i, page;
void *dl;
server->name = program_name; server->name = program_name;
server->machine.pagesize = sysconf(_SC_PAGESIZE) >> 10; page = sysconf(_SC_PAGESIZE) >> 10;
for(i = 0; page; ++i, page >>= 1);
server->machine.pagesize = i - 1;
server->machine.ticks = sysconf(_SC_CLK_TCK); server->machine.ticks = sysconf(_SC_CLK_TCK);
server->machine.kc = kc = kstat_open (); server->machine.kc = kc = kstat_open ();
@@ -164,6 +172,7 @@ glibtop_open_s (glibtop *server, const char *program_name,
glibtop_warn_io_r (server, "kstat_open ()"); glibtop_warn_io_r (server, "kstat_open ()");
server->ncpu = -1; /* Force processor detection */ server->ncpu = -1; /* Force processor detection */
server->machine.vminfo_snaptime = 0; /* Force snaptime read */
glibtop_get_kstats(server); glibtop_get_kstats(server);
server->machine.boot = 0; server->machine.boot = 0;
@@ -171,13 +180,55 @@ glibtop_open_s (glibtop *server, const char *program_name,
{ {
kn = (kstat_named_t *)kstat_data_lookup(ksp, "boot_time"); kn = (kstat_named_t *)kstat_data_lookup(ksp, "boot_time");
if(kn) if(kn)
server->machine.boot = kn->value.ui32; switch(kn->data_type)
{
#ifdef KSTAT_DATA_INT32
case KSTAT_DATA_INT32: server->machine.boot = kn->value.i32;
break;
case KSTAT_DATA_UINT32: server->machine.boot = kn->value.ui32;
break;
case KSTAT_DATA_INT64: server->machine.boot = kn->value.i64;
break;
case KSTAT_DATA_UINT64: server->machine.boot = kn->value.ui64;
break;
#else
case KSTAT_DATA_LONG: server->machine.boot = kn->value.l;
break;
case KSTAT_DATA_ULONG: server->machine.boot = kn->value.ul;
break;
case KSTAT_DATA_LONGLONG: server->machine.boot = kn->value.ll;
break;
case KSTAT_DATA_ULONGLONG: server->machine.boot = kn->value.ull;
break;
#endif
}
} }
server->machine.kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL); /* Now let's have a bit of magic dust... */
if(!server->machine.kd)
glibtop_warn_io_r(server, "kvm_open()");
fprintf (stderr, "Sleeping 2 seconds, please wait ...\n"); #if GLIBTOP_SOLARIS_RELEASE >= 560
sleep (2);
dl = dlopen("/usr/lib/libproc.so", RTLD_LAZY);
server->machine.libproc = dl;
if(dl)
{
void *func;
func = dlsym(dl, "Pobjname"); /* Solaris 8 */
if(!func)
func = dlsym(dl, "proc_objname"); /* Solaris 7 */
server->machine.objname = (void (*)
(void *, uintptr_t, const char *, size_t))func;
server->machine.pgrab = (struct ps_prochandle *(*)(pid_t, int, int *))
dlsym(dl, "Pgrab");
server->machine.pfree = (void (*)(void *))dlsym(dl, "Pfree");
}
else
{
server->machine.objname = NULL;
server->machine.pgrab = NULL;
server->machine.pfree = NULL;
}
#endif
server->machine.me = getpid();
} }

View File

@@ -0,0 +1,92 @@
/* $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_suid.h>
#include <unistd.h>
#include <sys/types.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_INIT) == 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_INIT;
}
}
/* !!! THIS FUNCTION RUNS SUID ROOT - CHANGE WITH CAUTION !!! */
void
glibtop_open_p (glibtop *server, const char *program_name,
const unsigned long features, const unsigned flags)
{
/* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */
server->name = program_name;
server->machine.uid = getuid ();
server->machine.euid = geteuid ();
server->machine.gid = getgid ();
server->machine.egid = getegid ();
server->machine.kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
if(!server->machine.kd)
glibtop_warn_io_r(server, "kvm_open()");
/* Drop priviledges; we only become root when necessary.
setreuid (ruid, euid) - set real and effective user id;
setregid (rgid, egid) - set real and effective group id;
*/
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.
*/
}

View File

@@ -26,7 +26,8 @@
#include <glibtop/xmalloc.h> #include <glibtop/xmalloc.h>
#include <glibtop/procargs.h> #include <glibtop/procargs.h>
static const unsigned long _glibtop_sysdeps_proc_args = 0; static const unsigned long _glibtop_sysdeps_proc_args =
(1L << GLIBTOP_PROC_ARGS_SIZE);
/* Init function. */ /* Init function. */
@@ -42,6 +43,41 @@ char *
glibtop_get_proc_args_s (glibtop *server, glibtop_proc_args *buf, glibtop_get_proc_args_s (glibtop *server, glibtop_proc_args *buf,
pid_t pid, unsigned max_len) pid_t pid, unsigned max_len)
{ {
#ifdef HAVE_PROCFS_H
struct psinfo pinfo;
#else
struct prpsinfo pinfo;
#endif
int len, i;
char *ret, *p;
memset (buf, 0, sizeof (glibtop_proc_args)); memset (buf, 0, sizeof (glibtop_proc_args));
return NULL;
if(glibtop_get_proc_data_psinfo_s(server, &pinfo, pid))
return NULL;
for(len = 0; len < PRARGSZ; ++len)
if(!(pinfo.pr_psargs[len]))
break;
if(max_len)
{
ret = glibtop_malloc_r(server, max_len + 1);
if(max_len < len)
len = max_len;
memcpy(ret, pinfo.pr_psargs, len);
ret[len] = 0;
}
else
{
ret = glibtop_malloc_r(server, len + 1);
memcpy(ret, pinfo.pr_psargs, len);
ret[len] = 0;
buf->size = len;
buf->flags = _glibtop_sysdeps_proc_args;
}
for(p = ret; *p; ++p)
if(*p == ' ')
*p = 0;
return ret;
} }

View File

@@ -23,9 +23,27 @@
#include <glibtop.h> #include <glibtop.h>
#include <glibtop_private.h> #include <glibtop_private.h>
#include <glibtop/procuid.h>
#include <errno.h> #include <errno.h>
#include "safeio.h"
/*
* The differences between old and new procfs API are:
* - old has /proc/<pid> file and ioctl() is used to obtain the data.
* - new has /proc/<pid>/* files and read() & friends are used to
* obtain the data.
* - names of structures and members are different. It's mostly the
* prefix. Old uses `pr' and new uses `ps'.
*
* Since almost every line would be in #ifdef, I think it would
* be more readable to just copy everything twice. This is not a big
* file, after all.
*/
#ifdef HAVE_PROCFS_H
/* Read /proc/<pid>/psinfo. */ /* Read /proc/<pid>/psinfo. */
int int
@@ -35,19 +53,21 @@ glibtop_get_proc_data_psinfo_s (glibtop *server, struct psinfo *psinfo, pid_t pi
char buffer [BUFSIZ]; char buffer [BUFSIZ];
sprintf (buffer, "/proc/%d/psinfo", (int) pid); sprintf (buffer, "/proc/%d/psinfo", (int) pid);
fd = open (buffer, O_RDONLY); fd = s_open (buffer, O_RDONLY);
if (fd < 0) { if (fd < 0) {
glibtop_warn_io_r (server, "open (%s)", buffer); glibtop_warn_io_r (server, "open (%s)", buffer);
return -1; return -1;
} }
if (pread (fd, psinfo, sizeof (struct psinfo), 0) != sizeof (struct psinfo)) { if (s_pread (fd, psinfo, sizeof (struct psinfo), 0) !=
close (fd); sizeof (struct psinfo))
{
s_close (fd);
glibtop_warn_io_r (server, "pread (%s)", buffer); glibtop_warn_io_r (server, "pread (%s)", buffer);
return -1; return -1;
} }
close (fd); s_close (fd);
return 0; return 0;
} }
@@ -58,44 +78,63 @@ glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t p
char buffer [BUFSIZ]; char buffer [BUFSIZ];
sprintf (buffer, "/proc/%d/usage", (int) pid); sprintf (buffer, "/proc/%d/usage", (int) pid);
fd = open (buffer, O_RDONLY); fd = s_open (buffer, O_RDONLY);
if (fd < 0) { if (fd < 0) {
glibtop_warn_io_r (server, "open (%s)", buffer); glibtop_warn_io_r (server, "open (%s)", buffer);
return -1; return -1;
} }
if (pread (fd, prusage, sizeof (struct prusage), 0) != sizeof (struct prusage)) { if (s_pread (fd, prusage, sizeof (struct prusage), 0) !=
close (fd); sizeof (struct prusage))
{
s_close (fd);
glibtop_warn_io_r (server, "pread (%s)", buffer); glibtop_warn_io_r (server, "pread (%s)", buffer);
return -1; return -1;
} }
close (fd); s_close (fd);
return 0; return 0;
} }
#if LIBGTOP_VERSION_CODE >= 1001002
int int
glibtop_get_proc_credentials_s(glibtop *server, struct prcred *prcred, pid_t pid) glibtop_get_proc_credentials_s(glibtop *server,
struct prcred *prcred,
gid_t *groups,
pid_t pid)
{ {
int fd; int fd;
size_t toread;
char buffer[BUFSIZ]; char buffer[BUFSIZ];
sprintf(buffer, "/proc/%d/cred", (int)pid); sprintf(buffer, "/proc/%d/cred", (int)pid);
if((fd = open(buffer, O_RDONLY)) < 0) if((fd = s_open(buffer, O_RDONLY)) < 0)
{ {
if(errno != EPERM && errno != EACCES) if(errno != EPERM && errno != EACCES)
glibtop_warn_io_r(server, "open (%s)", buffer); glibtop_warn_io_r(server, "open (%s)", buffer);
return -1; return -1;
} }
if(pread(fd, prcred, sizeof(struct prcred), 0) != sizeof(struct prcred)) if(s_pread(fd, prcred, sizeof(struct prcred), 0) !=
sizeof(struct prcred))
{ {
close(fd); s_close(fd);
glibtop_warn_io_r(server, "pread (%s)", buffer); glibtop_warn_io_r(server, "pread (%s)", buffer);
return -1; return -1;
} }
close(fd); if(prcred->pr_ngroups >= 0)
{
if(prcred->pr_ngroups <= GLIBTOP_MAX_GROUPS)
toread = prcred->pr_ngroups * sizeof(gid_t);
else
toread = GLIBTOP_MAX_GROUPS * sizeof(gid_t);
if(s_pread(fd, groups, toread,
&(((struct prcred *)0)->pr_groups[0])) != toread)
prcred->pr_ngroups = 0;
}
s_close(fd);
return 0; return 0;
} }
#endif
int int
glibtop_get_proc_status_s(glibtop *server, struct pstatus *pstatus, pid_t pid) glibtop_get_proc_status_s(glibtop *server, struct pstatus *pstatus, pid_t pid)
@@ -104,18 +143,126 @@ glibtop_get_proc_status_s(glibtop *server, struct pstatus *pstatus, pid_t pid)
char buffer[BUFSIZ]; char buffer[BUFSIZ];
sprintf(buffer, "/proc/%d/status", (int)pid); sprintf(buffer, "/proc/%d/status", (int)pid);
if((fd = open(buffer, O_RDONLY)) < 0) if((fd = s_open(buffer, O_RDONLY)) < 0)
{ {
if(errno != EPERM && errno != EACCES) if(errno != EPERM && errno != EACCES)
glibtop_warn_io_r(server, "open (%s)", buffer); glibtop_warn_io_r(server, "open (%s)", buffer);
return -1; return -1;
} }
if(pread(fd, pstatus, sizeof(struct pstatus), 0) != sizeof(struct pstatus)) if(s_pread(fd, pstatus, sizeof(struct pstatus), 0) !=
sizeof(struct pstatus))
{ {
close(fd); s_close(fd);
glibtop_warn_io_r(server, "pread (%s)", buffer); glibtop_warn_io_r(server, "pread (%s)", buffer);
return -1; return -1;
} }
close(fd); s_close(fd);
return 0; return 0;
} }
#else /* old API */
int
glibtop_get_proc_data_psinfo_s (glibtop *server,
struct prpsinfo *psinfo,
pid_t pid)
{
int fd;
char buffer [BUFSIZ];
sprintf (buffer, "/proc/%d", (int) pid);
fd = s_open (buffer, O_RDONLY);
if (fd < 0) {
if(errno != EPERM && errno != EACCES)
glibtop_warn_io_r (server, "open (%s)", buffer);
return -1;
}
if(ioctl(fd, PIOCPSINFO, psinfo) < 0)
{
s_close (fd);
glibtop_warn_io_r (server, "ioctl(%s, PIOCPSINFO)", buffer);
return -1;
}
s_close (fd);
return 0;
}
int
glibtop_get_proc_data_usage_s (glibtop *server,
struct prusage *prusage,
pid_t pid)
{
int fd;
char buffer [BUFSIZ];
sprintf (buffer, "/proc/%d", (int) pid);
fd = s_open (buffer, O_RDONLY);
if (fd < 0) {
if(errno != EPERM && errno != EACCES)
glibtop_warn_io_r (server, "open (%s)", buffer);
return -1;
}
if(ioctl(fd, PIOCUSAGE, prusage) < 0)
{
s_close (fd);
glibtop_warn_io_r (server, "ioctl(%s, PIOCUSAGE)", buffer);
return -1;
}
s_close (fd);
return 0;
}
int
glibtop_get_proc_credentials_s(glibtop *server,
struct prcred *prcred,
gid_t *groups,
pid_t pid)
{
int fd;
size_t toread;
char buffer[BUFSIZ];
sprintf(buffer, "/proc/%d", (int)pid);
if((fd = s_open(buffer, O_RDONLY)) < 0)
{
if(errno != EPERM && errno != EACCES)
glibtop_warn_io_r(server, "open (%s)", buffer);
return -1;
}
if(ioctl(fd, PIOCCRED, prcred) < 0)
{
s_close(fd);
glibtop_warn_io_r(server, "ioctl(%s, PIOCCRED)", buffer);
return -1;
}
s_close(fd);
return 0;
}
int
glibtop_get_proc_status_s(glibtop *server, struct prstatus *pstatus, pid_t pid)
{
int fd;
char buffer[BUFSIZ];
sprintf(buffer, "/proc/%d", (int)pid);
if((fd = s_open(buffer, O_RDONLY)) < 0)
{
if(errno != EPERM && errno != EACCES)
glibtop_warn_io_r(server, "open (%s)", buffer);
return -1;
}
if(ioctl(fd, PIOCSTATUS, pstatus) < 0)
{
s_close(fd);
glibtop_warn_io_r(server, "ioctl(%s, PIOCSTATUS)", buffer);
return -1;
}
s_close(fd);
return 0;
}
#endif

View File

@@ -33,8 +33,8 @@
#define GLIBTOP_PROCLIST_FLAGS 3 #define GLIBTOP_PROCLIST_FLAGS 3
static const unsigned long _glibtop_sysdeps_proclist = static const unsigned long _glibtop_sysdeps_proclist =
(1 << GLIBTOP_PROCLIST_TOTAL) + (1 << GLIBTOP_PROCLIST_NUMBER) + (1L << GLIBTOP_PROCLIST_TOTAL) + (1L << GLIBTOP_PROCLIST_NUMBER) +
(1 << GLIBTOP_PROCLIST_SIZE); (1L << GLIBTOP_PROCLIST_SIZE);
/* Init function. */ /* Init function. */
@@ -61,13 +61,47 @@ glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf,
DIR *proc; DIR *proc;
struct dirent *entry; struct dirent *entry;
char buffer [BUFSIZ]; char buffer [BUFSIZ];
unsigned count, total, pid; unsigned count, total, pid, mask;
unsigned pids [BLOCK_COUNT], *pids_chain = NULL; unsigned pids [BLOCK_COUNT], *pids_chain = NULL;
unsigned pids_size = 0, pids_offset = 0, new_size; unsigned pids_size = 0, pids_offset = 0, new_size;
struct stat statb; struct stat statb;
int len, i, ok; int len, i, ok;
memset (buf, 0, sizeof (glibtop_proclist)); memset (buf, 0, sizeof (glibtop_proclist));
mask = which & ~GLIBTOP_KERN_PROC_MASK;
which &= GLIBTOP_KERN_PROC_MASK;
/* Check if the user wanted only one process */
if(which == GLIBTOP_KERN_PROC_PID)
{
if(mask)
{
#ifdef HAVE_PROCFS_H
struct psinfo psinfo;
#else
struct prpsinfo psinfo;
#endif
if(glibtop_get_proc_data_psinfo_s(server, &psinfo, pid))
return NULL;
if(mask & GLIBTOP_EXCLUDE_IDLE && !psinfo.pr_pctcpu)
return NULL;
if(mask & GLIBTOP_EXCLUDE_SYSTEM && psinfo.pr_flag & SSYS)
return NULL;
if(mask & GLIBTOP_EXCLUDE_NOTTY && psinfo.pr_ttydev == PRNODEV)
return NULL;
}
else
{
sprintf(buffer, "/proc/%d", arg);
if(s_stat(buffer, &statb) < 0)
return NULL;
}
if(!(pids_chain = glibtop_malloc(sizeof(unsigned))))
return NULL;
*pids_chain = pid;
return pids_chain;
}
proc = opendir ("/proc"); proc = opendir ("/proc");
if (!proc) return NULL; if (!proc) return NULL;
@@ -79,23 +113,78 @@ glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf,
ok = 1; len = strlen (entry->d_name); ok = 1; len = strlen (entry->d_name);
/* does it consist entirely of digits? */ /* does it consist entirely of digits? */
#if 0
/* It does, except for "." and "..". Let's speed up */
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
if (!isdigit (entry->d_name [i])) ok = 0; if (!isdigit (entry->d_name [i])) ok = 0;
if (!ok) continue; if (!ok) continue;
#else
if(entry->d_name[0] == '.')
continue;
#endif
/* convert it in a number */ /* convert it in a number */
#if 0
if (sscanf (entry->d_name, "%u", &pid) != 1) continue; if (sscanf (entry->d_name, "%u", &pid) != 1) continue;
#else
pid = (unsigned)atol(entry->d_name);
#endif
/* is it really a directory? */ #ifdef HAVE_PROCFS_H
sprintf (buffer, "/proc/%d", pid); /* Can we skip it based on the request? We have
RUID and RGID in struct stat. But we can't do it
if (stat (buffer, &statb)) continue; like this for LP64 process, because stat() will fail.
XXX Unimplemented for now */
if (!S_ISDIR (statb.st_mode)) continue; if(!mask && which == GLIBTOP_KERN_PROC_RUID)
{
sprintf (buffer, "/proc/%d", pid);
if (s_stat (buffer, &statb)) continue;
if (!S_ISDIR (statb.st_mode)) continue;
if(statb.st_uid != arg) continue;
}
if(mask || which != GLIBTOP_KERN_PROC_ALL)
{
struct psinfo psinfo;
if(glibtop_get_proc_data_psinfo_s(server, &psinfo, pid))
continue;
if(mask)
{
if(mask & GLIBTOP_EXCLUDE_IDLE && !psinfo.pr_pctcpu)
continue;
if(mask & GLIBTOP_EXCLUDE_SYSTEM && psinfo.pr_flag & SSYS)
continue;
if(mask & GLIBTOP_EXCLUDE_NOTTY
&& psinfo.pr_ttydev == PRNODEV)
continue;
}
switch(which)
{
case GLIBTOP_KERN_PROC_PGRP: if(psinfo.pr_pgid != arg)
continue;
break;
case GLIBTOP_KERN_PROC_SESSION: if(psinfo.pr_sid != arg)
continue;
break;
case GLIBTOP_KERN_PROC_TTY: if(psinfo.pr_ttydev != arg)
continue;
break;
case GLIBTOP_KERN_PROC_UID: if(psinfo.pr_euid != arg)
continue;
break;
case GLIBTOP_KERN_PROC_RUID: if(psinfo.pr_uid != arg)
continue;
break;
default: break;
}
}
#endif
/* Fine. Now we first try to store it in pids. If this buffer is /* Fine. Now we first try to store it in pids. If this buffer is
* full, we copy it to the pids_chain. */ * full, we copy it to the pids_chain. */
@@ -126,7 +215,7 @@ glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf,
total++; total++;
} }
closedir (proc); s_closedir (proc);
/* count is only zero if an error occured (one a running Linux system, /* count is only zero if an error occured (one a running Linux system,
* we have at least one single process). */ * we have at least one single process). */

View File

@@ -30,12 +30,17 @@
#include <errno.h> #include <errno.h>
#include <alloca.h> #include <alloca.h>
#include "safeio.h"
static const unsigned long _glibtop_sysdeps_proc_map = static const unsigned long _glibtop_sysdeps_proc_map =
(1L << GLIBTOP_PROC_MAP_NUMBER) + (1L << GLIBTOP_PROC_MAP_TOTAL) + (1L << GLIBTOP_PROC_MAP_NUMBER) + (1L << GLIBTOP_PROC_MAP_TOTAL) +
(1L << GLIBTOP_PROC_MAP_SIZE); (1L << GLIBTOP_PROC_MAP_SIZE);
static const unsigned long _glibtop_sysdeps_map_entry = static const unsigned long _glibtop_sysdeps_map_entry =
(1L << GLIBTOP_MAP_ENTRY_START) + (1L << GLIBTOP_MAP_ENTRY_END) + (1L << GLIBTOP_MAP_ENTRY_START) + (1L << GLIBTOP_MAP_ENTRY_END) +
(1L << GLIBTOP_MAP_ENTRY_OFFSET) + (1L << GLIBTOP_MAP_ENTRY_PERM); (1L << GLIBTOP_MAP_ENTRY_OFFSET) + (1L << GLIBTOP_MAP_ENTRY_PERM);
static const unsigned long _glibtop_sysdeps_map_device =
(1L << GLIBTOP_MAP_ENTRY_DEVICE) + (1L << GLIBTOP_MAP_ENTRY_INODE);
/* Init function. */ /* Init function. */
@@ -51,51 +56,103 @@ glibtop_init_proc_map_s (glibtop *server)
glibtop_map_entry * glibtop_map_entry *
glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
{ {
int fd, i, nmaps; int fd, i, nmaps, pr_err, heap;
#if GLIBTOP_SOLARIS_RELEASE >= 560
prxmap_t *maps;
struct ps_prochandle *Pr;
#else
prmap_t *maps; prmap_t *maps;
#endif
/* A few defines, to make it shorter down there */
#ifdef HAVE_PROCFS_H
# define OFFSET pr_offset
#else
# define OFFSET pr_off
#endif
glibtop_map_entry *entry; glibtop_map_entry *entry;
struct stat inode; struct stat inode;
char buffer[BUFSIZ]; char buffer[BUFSIZ];
memset (buf, 0, sizeof (glibtop_proc_map)); memset (buf, 0, sizeof (glibtop_proc_map));
sprintf(buffer, "/proc/%d/map", (int)pid); #ifdef HAVE_PROCFS_H
if((fd = open(buffer, O_RDONLY)) < 0) sprintf(buffer, "/proc/%d/xmap", (int)pid);
#else
sprintf(buffer, "/proc/%d", (int)pid);
#endif
if((fd = s_open(buffer, O_RDONLY)) < 0)
{ {
if(errno != EPERM && errno != EACCES) if(errno != EPERM && errno != EACCES)
glibtop_warn_io_r(server, "open (%s)", buffer); glibtop_warn_io_r(server, "open (%s)", buffer);
return NULL; return NULL;
} }
#ifdef HAVE_PROCFS_H
if(fstat(fd, &inode) < 0) if(fstat(fd, &inode) < 0)
{ {
if(errno != EOVERFLOW) if(errno != EOVERFLOW)
glibtop_warn_io_r(server, "fstat (%s)", buffer); glibtop_warn_io_r(server, "fstat (%s)", buffer);
/* else call daemon for 64-bit support */ /* else call daemon for 64-bit support */
close(fd); s_close(fd);
return NULL; return NULL;
} }
maps = alloca(inode.st_size); maps = alloca(inode.st_size);
nmaps = inode.st_size / sizeof(prmap_t); nmaps = inode.st_size / sizeof(prxmap_t);
if(pread(fd, maps, inode.st_size, 0) != inode.st_size) if(s_pread(fd, maps, inode.st_size, 0) != inode.st_size)
{ {
glibtop_warn_io_r(server, "pread (%s)", buffer); glibtop_warn_io_r(server, "pread (%s)", buffer);
close(fd); s_close(fd);
return NULL; return NULL;
} }
close(fd); #else
if(!(entry = glibtop_malloc_r(server, nmaps * sizeof(glibtop_map_entry)))) if(ioctl(fd, PIOCNMAP, &nmaps) < 0)
{
glibtop_warn_io_r(server, "ioctl(%s, PIOCNMAP)", buffer);
s_close(fd);
return NULL;
}
maps = alloca((nmaps + 1) * sizeof(prmap_t));
if(ioctl(fd, PIOCMAP, maps) < 0)
{
glibtop_warn_io_r(server, "ioctl(%s, PIOCMAP)", buffer);
s_close(fd);
return NULL;
}
#endif
if(!(entry = glibtop_malloc_r(server,
nmaps * sizeof(glibtop_map_entry))))
return NULL; return NULL;
buf->number = nmaps; buf->number = nmaps;
buf->size = sizeof(glibtop_map_entry); buf->size = sizeof(glibtop_map_entry);
buf->total = nmaps * sizeof(glibtop_map_entry); buf->total = nmaps * sizeof(glibtop_map_entry);
memset(entry, 0, nmaps * sizeof(glibtop_map_entry)); memset(entry, 0, nmaps * sizeof(glibtop_map_entry));
for(i = 0; i < nmaps; ++i)
#if GLIBTOP_SOLARIS_RELEASE >= 560
if(server->machine.objname && server->machine.pgrab &&
server->machine.pfree)
Pr = (server->machine.pgrab)(pid, 1, &pr_err);
#endif
for(heap = 0,i = 0; i < nmaps; ++i)
{ {
int len;
entry[i].start = maps[i].pr_vaddr; entry[i].start = maps[i].pr_vaddr;
entry[i].end = maps[i].pr_vaddr + maps[i].pr_size; entry[i].end = maps[i].pr_vaddr + maps[i].pr_size;
entry[i].offset = maps[i].pr_offset;
#if GLIBTOP_SOLARIS_RELEASE >= 560
if(maps[i].pr_dev != PRNODEV)
{
entry[i].device = maps[i].pr_dev;
entry[i].inode = maps[i].pr_ino;
entry[i].flags |= _glibtop_sysdeps_map_device;
}
#endif
entry[i].offset = maps[i].OFFSET;
if(maps[i].pr_mflags & MA_READ) if(maps[i].pr_mflags & MA_READ)
entry[i].perm |= GLIBTOP_MAP_PERM_READ; entry[i].perm |= GLIBTOP_MAP_PERM_READ;
if(maps[i].pr_mflags & MA_WRITE) if(maps[i].pr_mflags & MA_WRITE)
@@ -107,8 +164,44 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
else else
entry[i].perm |= GLIBTOP_MAP_PERM_PRIVATE; entry[i].perm |= GLIBTOP_MAP_PERM_PRIVATE;
entry[i].flags = _glibtop_sysdeps_map_entry; entry[i].flags = _glibtop_sysdeps_map_entry;
#if GLIBTOP_SOLARIS_RELEASE >= 560
if(maps[i].pr_mflags & MA_ANON)
{
if(!heap)
{
++heap;
strcpy(entry[i].filename, "[ heap ]");
}
else
if(i == nmaps - 1)
strcpy(entry[i].filename, "[ stack ]");
else
strcpy(entry[i].filename, "[ anon ]");
entry[i].flags |= (1L << GLIBTOP_MAP_ENTRY_FILENAME);
}
else
if(Pr)
{
server->machine.objname(Pr, maps[i].pr_vaddr, buffer,
BUFSIZ);
if((len = resolvepath(buffer, entry[i].filename,
GLIBTOP_MAP_FILENAME_LEN)) > 0)
{
entry[i].filename[len] = 0;
entry[i].flags |= (1L << GLIBTOP_MAP_ENTRY_FILENAME);
}
}
#endif
} }
#if GLIBTOP_SOLARIS_RELEASE >= 560
if(Pr)
server->machine.pfree(Pr);
#endif
buf->flags = _glibtop_sysdeps_proc_map; buf->flags = _glibtop_sysdeps_proc_map;
s_close(fd);
return entry; return entry;
} }

View File

@@ -24,7 +24,9 @@
#include <glibtop.h> #include <glibtop.h>
#include <glibtop/procmem.h> #include <glibtop/procmem.h>
static const unsigned long _glibtop_sysdeps_proc_mem = 0; 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);
/* Init function. */ /* Init function. */
@@ -37,8 +39,26 @@ glibtop_init_proc_mem_s (glibtop *server)
/* Provides detailed information about a process. */ /* Provides detailed information about a process. */
void void
glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, pid_t pid)
pid_t pid)
{ {
#ifdef HAVE_PROCFS_H
struct psinfo psinfo;
#else
struct prpsinfo psinfo;
int pagesize = server->machine.pagesize;
#endif
memset (buf, 0, sizeof (glibtop_proc_mem)); memset (buf, 0, sizeof (glibtop_proc_mem));
if(glibtop_get_proc_data_psinfo_s(server, &psinfo, pid))
return;
#ifdef HAVE_PROCFS_H
buf->size = buf->vsize = psinfo.pr_size << 10;
buf->resident = buf->rss = psinfo.pr_rssize << 10;
#else
buf->size = buf->vsize = psinfo.pr_size << pagesize << 10;
buf->resident = buf->rss = psinfo.pr_rssize << pagesize << 10;
#endif
buf->flags = _glibtop_sysdeps_proc_mem;
} }

View File

@@ -43,7 +43,11 @@ void
glibtop_get_proc_signal_s (glibtop *server, glibtop_proc_signal *buf, glibtop_get_proc_signal_s (glibtop *server, glibtop_proc_signal *buf,
pid_t pid) pid_t pid)
{ {
#ifdef HAVE_PROCFS_H
struct pstatus pstatus; struct pstatus pstatus;
#else
struct prstatus pstatus;
#endif
int size; int size;
memset (buf, 0, sizeof (glibtop_proc_signal)); memset (buf, 0, sizeof (glibtop_proc_signal));
@@ -57,7 +61,11 @@ glibtop_get_proc_signal_s (glibtop *server, glibtop_proc_signal *buf,
size = sizeof(sigset_t); size = sizeof(sigset_t);
memcpy(buf->signal, &pstatus.pr_sigpend, size); memcpy(buf->signal, &pstatus.pr_sigpend, size);
#ifdef HAVE_PROCFS_H
memcpy(buf->blocked, &pstatus.pr_lwp.pr_lwphold, size); memcpy(buf->blocked, &pstatus.pr_lwp.pr_lwphold, size);
#else
memcpy(buf->blocked, &pstatus.pr_lwppend, size);
#endif
/* Technically, most of this is meaningless on a process level, /* Technically, most of this is meaningless on a process level,
but this should be a good enough approximation. */ but this should be a good enough approximation. */

View File

@@ -27,11 +27,15 @@
#include <glibtop_private.h> #include <glibtop_private.h>
static const unsigned long _glibtop_sysdeps_proc_state = static const unsigned long _glibtop_sysdeps_proc_state =
(1L << GLIBTOP_PROC_STATE_CMD) + (1L << GLIBTOP_PROC_STATE_STATE) + #if (LIBGTOP_VERSION_CODE >= 1001002) && defined(HAVE_PROCFS_H)
(1L << GLIBTOP_PROC_STATE_UID) + (1L << GLIBTOP_PROC_STATE_GID) +
(1L << GLIBTOP_PROC_STATE_RUID) + (1L << GLIBTOP_PROC_STATE_RGID) +
(1L << GLIBTOP_PROC_STATE_HAS_CPU) + (1L << GLIBTOP_PROC_STATE_PROCESSOR) + (1L << GLIBTOP_PROC_STATE_HAS_CPU) + (1L << GLIBTOP_PROC_STATE_PROCESSOR) +
(1L << GLIBTOP_PROC_STATE_LAST_PROCESSOR); (1L << GLIBTOP_PROC_STATE_LAST_PROCESSOR) +
#endif
#if LIBGTOP_VERSION_CODE >= 1001002
(1L << GLIBTOP_PROC_STATE_RUID) + (1L << GLIBTOP_PROC_STATE_RGID) +
#endif
(1L << GLIBTOP_PROC_STATE_CMD) + (1L << GLIBTOP_PROC_STATE_STATE) +
(1L << GLIBTOP_PROC_STATE_UID) + (1L << GLIBTOP_PROC_STATE_GID);
/* Init function. */ /* Init function. */
@@ -46,7 +50,11 @@ glibtop_init_proc_state_s (glibtop *server)
void void
glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid) glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid)
{ {
#ifdef HAVE_PROCFS_H
struct psinfo psinfo; struct psinfo psinfo;
#else
struct prpsinfo psinfo;
#endif
memset (buf, 0, sizeof (glibtop_proc_state)); memset (buf, 0, sizeof (glibtop_proc_state));
@@ -55,24 +63,59 @@ glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid)
buf->uid = psinfo.pr_euid; buf->uid = psinfo.pr_euid;
buf->gid = psinfo.pr_egid; buf->gid = psinfo.pr_egid;
#if LIBGTOP_VERSION_CODE >= 1001002
buf->ruid = psinfo.pr_uid; buf->ruid = psinfo.pr_uid;
buf->rgid = psinfo.pr_gid; buf->rgid = psinfo.pr_gid;
#endif
#ifdef HAVE_PROCFS_H
switch(psinfo.pr_lwp.pr_state) switch(psinfo.pr_lwp.pr_state)
#else
switch(psinfo.pr_state)
#endif
{ {
case SONPROC: buf->has_cpu = 1; case SONPROC:
buf->processor = psinfo.pr_lwp.pr_onpro; #if (LIBGTOP_VERSION_CODE >= 1001002) && defined(HAVE_PROCFS_H)
case SRUN: buf->state = GLIBTOP_PROCESS_RUNNING; buf->has_cpu = 1;
break; buf->processor = psinfo.pr_lwp.pr_onpro;
case SZOMB: buf->state = GLIBTOP_PROCESS_ZOMBIE; #endif
break; case SRUN:
case SSLEEP: #if LIBGTOP_VERSION_CODE >= 1001002
case SSTOP: buf->state = GLIBTOP_PROCESS_STOPPED; buf->state = GLIBTOP_PROCESS_RUNNING;
break; #else
case SIDL: buf->state = GLIBTOP_PROCESS_UNINTERRUPTIBLE; buf->state = 'R';
#endif
break;
case SZOMB:
#if LIBGTOP_VERSION_CODE >= 1001002
buf->state = GLIBTOP_PROCESS_ZOMBIE;
#else
buf->state = 'Z';
#endif
break;
case SSLEEP:
#if LIBGTOP_VERSION_CODE >= 1001002
buf->state = GLIBTOP_PROCESS_INTERRUPTIBLE;
#else
buf->state = 'S';
#endif
break;
case SSTOP:
#if LIBGTOP_VERSION_CODE >= 1001002
buf->state = GLIBTOP_PROCESS_STOPPED;
#else
buf->state = 'T';
#endif
break;
case SIDL:
#if LIBGTOP_VERSION_CODE >= 1001002
buf->state = GLIBTOP_PROCESS_UNINTERRUPTIBLE;
#else
buf->state = 'D';
#endif
} }
#if (LIBGTOP_VERSION_CODE >= 1001002) && defined(HAVE_PROCFS_H)
buf->last_processor = psinfo.pr_lwp.pr_onpro; buf->last_processor = psinfo.pr_lwp.pr_onpro;
#endif
strncpy (buf->cmd, psinfo.pr_fname, 39); strncpy (buf->cmd, psinfo.pr_fname, 39);
buf->flags = _glibtop_sysdeps_proc_state; buf->flags = _glibtop_sysdeps_proc_state;

View File

@@ -27,8 +27,8 @@
#include <glibtop_private.h> #include <glibtop_private.h>
static const unsigned long _glibtop_sysdeps_proc_time = static const unsigned long _glibtop_sysdeps_proc_time =
(1 << GLIBTOP_PROC_TIME_START_TIME) + (1 << GLIBTOP_PROC_TIME_RTIME) + (1L << GLIBTOP_PROC_TIME_START_TIME) + (1L << GLIBTOP_PROC_TIME_RTIME) +
(1 << GLIBTOP_PROC_TIME_UTIME) + (1 << GLIBTOP_PROC_TIME_STIME); (1L << GLIBTOP_PROC_TIME_UTIME) + (1L << GLIBTOP_PROC_TIME_STIME);
/* Init function. */ /* Init function. */
@@ -48,18 +48,22 @@ glibtop_get_proc_time_s (glibtop *server, glibtop_proc_time *buf,
memset (buf, 0, sizeof (glibtop_proc_time)); memset (buf, 0, sizeof (glibtop_proc_time));
if (glibtop_get_proc_data_usage_s (server, &prusage, pid)) /* Don't do it for scheduler, we don't want to frighten our users */
return;
buf->start_time = prusage.pr_create.tv_sec * 1E+6 + if(pid)
prusage.pr_create.tv_nsec / 1E+3; {
if (glibtop_get_proc_data_usage_s (server, &prusage, pid))
return;
buf->rtime = prusage.pr_rtime.tv_sec * 1E+6 + buf->start_time = prusage.pr_create.tv_sec;
prusage.pr_rtime.tv_nsec / 1E+3;
buf->utime = prusage.pr_utime.tv_sec * 1E+6 + buf->rtime = prusage.pr_rtime.tv_sec * 1E+6 +
prusage.pr_utime.tv_nsec / 1E+3; prusage.pr_rtime.tv_nsec / 1E+3;
buf->stime = prusage.pr_stime.tv_sec * 1E+6 + buf->utime = prusage.pr_utime.tv_sec * 1E+6 +
prusage.pr_stime.tv_nsec / 1E+3; prusage.pr_utime.tv_nsec / 1E+3;
buf->stime = prusage.pr_stime.tv_sec * 1E+6 +
prusage.pr_stime.tv_nsec / 1E+3;
}
buf->flags = _glibtop_sysdeps_proc_time; buf->flags = _glibtop_sysdeps_proc_time;
} }

View File

@@ -34,9 +34,15 @@ static const unsigned long _glibtop_sysdeps_proc_uid_psinfo =
(1L << GLIBTOP_PROC_UID_TTY) + (1L << GLIBTOP_PROC_UID_PRIORITY) + (1L << GLIBTOP_PROC_UID_TTY) + (1L << GLIBTOP_PROC_UID_PRIORITY) +
(1L << GLIBTOP_PROC_UID_NICE); (1L << GLIBTOP_PROC_UID_NICE);
static const unsigned long _glibtop_sysdeps_proc_uid_prcred = static const unsigned long _glibtop_sysdeps_proc_uid_prcred =
#if LIBGTOP_VERSION_CODE >= 1001002
#ifdef HAVE_PROCFS_H
(1L << GLIBTOP_PROC_UID_GROUPS) +
#endif
(1L << GLIBTOP_PROC_UID_SUID) + (1L << GLIBTOP_PROC_UID_SGID) + (1L << GLIBTOP_PROC_UID_SUID) + (1L << GLIBTOP_PROC_UID_SGID) +
(1L << GLIBTOP_PROC_UID_NGROUPS) + (1L << GLIBTOP_PROC_UID_GROUPS); (1L << GLIBTOP_PROC_UID_NGROUPS);
#else
0;
#endif
/* Init function. */ /* Init function. */
void void
@@ -51,8 +57,18 @@ glibtop_init_proc_uid_s (glibtop *server)
void void
glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid) glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid)
{ {
struct psinfo psinfo; #if LIBGTOP_VERSION_CODE >= 1001002
struct prcred prcred; struct prcred prcred;
#endif
#ifdef HAVE_PROCFS_H
struct psinfo psinfo;
#if LIBGTOP_VERSION_CODE >= 1001002
gid_t groups[GLIBTOP_MAX_GROUPS];
#endif
#else
struct prpsinfo psinfo;
gid_t groups[1]; /* dummy for consistent function prototype */
#endif
memset (buf, 0, sizeof (glibtop_proc_uid)); memset (buf, 0, sizeof (glibtop_proc_uid));
@@ -66,17 +82,27 @@ glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid)
buf->pid = psinfo.pr_pid; buf->pid = psinfo.pr_pid;
buf->ppid = psinfo.pr_ppid; buf->ppid = psinfo.pr_ppid;
#ifdef HAVE_PROCFS_H
buf->pgrp = psinfo.pr_pgid; buf->pgrp = psinfo.pr_pgid;
#else
buf->pgrp = psinfo.pr_pgrp;
#endif
buf->session = psinfo.pr_sid; buf->session = psinfo.pr_sid;
buf->tty = psinfo.pr_ttydev; buf->tty = psinfo.pr_ttydev;
#ifdef HAVE_PROCFS_H
buf->priority = psinfo.pr_lwp.pr_pri; buf->priority = psinfo.pr_lwp.pr_pri;
buf->nice = psinfo.pr_lwp.pr_nice; buf->nice = psinfo.pr_lwp.pr_nice - NZERO;
#else
buf->priority = psinfo.pr_pri;
buf->nice = psinfo.pr_nice - NZERO;
#endif
buf->flags = _glibtop_sysdeps_proc_uid_psinfo; buf->flags = _glibtop_sysdeps_proc_uid_psinfo;
if(glibtop_get_proc_credentials_s(server, &prcred, pid)) #if LIBGTOP_VERSION_CODE >= 1001002
if(glibtop_get_proc_credentials_s(server, &prcred, groups, pid))
return; return;
buf->suid = prcred.pr_suid; buf->suid = prcred.pr_suid;
@@ -84,15 +110,18 @@ glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid)
buf->ngroups = (prcred.pr_ngroups <= GLIBTOP_MAX_GROUPS) ? buf->ngroups = (prcred.pr_ngroups <= GLIBTOP_MAX_GROUPS) ?
prcred.pr_ngroups : GLIBTOP_MAX_GROUPS; prcred.pr_ngroups : GLIBTOP_MAX_GROUPS;
#ifdef HAVE_PROCFS_H
if(sizeof(int) == sizeof(gid_t)) if(sizeof(int) == sizeof(gid_t))
memcpy(buf->groups, prcred.pr_groups, memcpy(buf->groups, &groups, buf->ngroups * sizeof(gid_t));
buf->ngroups * sizeof(gid_t));
else else
{ {
int i; int i;
for(i = 0; i < buf->ngroups; ++i) for(i = 0; i < buf->ngroups; ++i)
buf->groups[i] = prcred.pr_groups[i]; buf->groups[i] = groups[i];
} }
#endif
#endif
buf->flags += _glibtop_sysdeps_proc_uid_prcred; buf->flags += _glibtop_sysdeps_proc_uid_prcred;
} }

84
sysdeps/solaris/safeio.c Normal file
View File

@@ -0,0 +1,84 @@
/* Copyright (C) 1999 Drazen Kacar
This file is part of LibGTop 1.0.
Contributed by Drazen Kacar <dave@srce.hr>, May 1999.
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 <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
int
s_open(const char *file, int mode)
{
int fd;
do {
fd = open(file, mode);
} while(fd < 0 && errno == EINTR);
return fd;
}
int
s_stat(const char *path, struct stat *buf)
{
int status;
do {
status = stat(path, buf);
} while(status < 0 && errno == EINTR);
return status;
}
int
s_close(int fd)
{
int status;
do {
status = close(fd);
} while(status < 0 && errno == EINTR);
return status;
}
ssize_t
s_pread(int fd, void *buf, size_t nbytes, off_t offset)
{
ssize_t len;
/* Now, why doesn't the pread(2) man page say anything about pread()
return values? Can it read less bytes than requested? */
do {
len = pread(fd, buf, nbytes, offset);
} while(len < 0 && errno == EINTR);
return len;
}
int s_closedir(DIR *dirp)
{
int status;
do {
status = closedir(dirp);
} while(status < 0 && errno == EINTR);
return status;
}

48
sysdeps/solaris/safeio.h Normal file
View File

@@ -0,0 +1,48 @@
/* Copyright (C) 1999 Drazen Kacar
This file is part of LibGTop 1.0.
Contributed by Drazen Kacar <dave@srce.hr>, May 1999.
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_SAFEIO_H__
#define __GLIBTOP_SAFEIO_H__
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
BEGIN_LIBGTOP_DECLS
int
s_open(const char *, int);
int
s_stat(const char *, struct stat *);
int
s_close(int);
ssize_t
s_pread(int, void *, size_t, off_t);
int
s_closedir(DIR *);
END_LIBGTOP_DECLS
#endif

View File

@@ -38,7 +38,7 @@ static const unsigned long _glibtop_sysdeps_sem_limits =
/* Init function. */ /* Init function. */
void void
glibtop_init_sem_limits_s (glibtop *server) glibtop_init_sem_limits_p (glibtop *server)
{ {
kvm_t *kd = server->machine.kd; kvm_t *kd = server->machine.kd;
@@ -51,7 +51,7 @@ glibtop_init_sem_limits_s (glibtop *server)
/* Provides information about sysv sem limits. */ /* Provides information about sysv sem limits. */
void void
glibtop_get_sem_limits_s (glibtop *server, glibtop_sem_limits *buf) glibtop_get_sem_limits_p (glibtop *server, glibtop_sem_limits *buf)
{ {
kvm_t *kd = server->machine.kd; kvm_t *kd = server->machine.kd;
struct seminfo sinfo; struct seminfo sinfo;

View File

@@ -35,7 +35,7 @@ static const unsigned long _glibtop_sysdeps_shm_limits =
/* Init function. */ /* Init function. */
void void
glibtop_init_shm_limits_s (glibtop *server) glibtop_init_shm_limits_p (glibtop *server)
{ {
kvm_t *kd = server->machine.kd; kvm_t *kd = server->machine.kd;
@@ -48,7 +48,7 @@ glibtop_init_shm_limits_s (glibtop *server)
/* Provides information about sysv ipc limits. */ /* Provides information about sysv ipc limits. */
void void
glibtop_get_shm_limits_s (glibtop *server, glibtop_shm_limits *buf) glibtop_get_shm_limits_p (glibtop *server, glibtop_shm_limits *buf)
{ {
kvm_t *kd = server->machine.kd; kvm_t *kd = server->machine.kd;
struct shminfo sinfo; struct shminfo sinfo;

View File

@@ -24,104 +24,51 @@
#include <glibtop.h> #include <glibtop.h>
#include <glibtop/signal.h> #include <glibtop/signal.h>
static const glibtop_signame glibtop_sys_siglist [] = const glibtop_signame glibtop_sys_siglist [] =
{ { 1, "SIGHUP", "Hangup" }, { { 1, "SIGHUP", "Hangup" },
{ 2, "SIGINT", "Interrupt" }, { 2, "SIGINT", "Interrupt" },
{ 3, "SIGQUIT", "Quit" }, { 3, "SIGQUIT", "Quit" },
{ 4, "SIGILL", "Illegal instruction" }, { 4, "SIGILL", "Illegal Instruction" },
{ 5, "SIGTRAP", "Trace or breakpoint trap" }, { 5, "SIGTRAP", "Trace/Breakpoint Trap" },
{ 6, "SIGABRT", "Abort" }, { 6, "SIGABRT", "Abort" },
{ 7, "SIGEMT", "Emulation trap" }, { 7, "SIGEMT", "Emulation Trap" },
{ 8, "SIGFPE", "Arithmetic exception" }, { 8, "SIGFPE", "Arithmetic Exception" },
{ 9, "SIGKILL", "Kill" }, { 9, "SIGKILL", "Killed" },
{ 10, "SIGBUS", "Bus error" }, { 10, "SIGBUS", "Bus Error" },
{ 11, "SIGSEGV", "Segmentation fault" }, { 11, "SIGSEGV", "Segmentation Fault" },
{ 12, "SIGSYS", "Bad system call" }, { 12, "SIGSYS", "Bad System Call" },
{ 13, "SIGPIPE", "Broken pipe" }, { 13, "SIGPIPE", "Broken Pipe" },
{ 14, "SIGALRM", "Alarm clock" }, { 14, "SIGALRM", "Alarm Clock" },
{ 15, "SIGTERM", "Terminate" }, { 15, "SIGTERM", "Terminated" },
{ 16, "SIGUSR1", "User signal 1" }, { 16, "SIGUSR1", "User Signal 1" },
{ 17, "SIGUSR2", "User signal 2" }, { 17, "SIGUSR2", "User Signal 2" },
{ 18, "SIGCHLD", "Child status changed" }, { 18, "SIGCHLD", "Child Status Changed" },
{ 19, "SIGPWR", "Power fail or restart" }, { 19, "SIGPWR", "Power-Fail/Restart" },
{ 20, "SIGWINCH","Window size change" }, { 20, "SIGWINCH","Window Size Change" },
{ 21, "SIGURG", "Urgent socket condition" }, { 21, "SIGURG", "Urgent Socket Condition" },
{ 22, "SIGPOLL", "Pollable event" }, { 22, "SIGPOLL", "Pollable Event" },
{ 23, "SIGSTOP", "Stop (cannot be ignored)" }, { 23, "SIGSTOP", "Stoped (signal)" },
{ 24, "SIGTSTP", "User stop requested from tty" }, { 24, "SIGTSTP", "Stopped (user)" },
{ 25, "SIGCONT", "Continue" }, { 25, "SIGCONT", "Continued" },
{ 26, "SIGTTIN", "Background tty read attempted" }, { 26, "SIGTTIN", "Stopped (tty input)" },
{ 27, "SIGTTOU", "Background tty write attempted" }, { 27, "SIGTTOU", "Stopped (tty output)" },
{ 28, "SIGVTALRM","Virtual timer expired" }, { 28, "SIGVTALRM","Virtual Timer Expired" },
{ 29, "SIGPROF", "Profiling timer expired" }, { 29, "SIGPROF", "Profiling Timer Expired" },
{ 30, "SIGXCPU", "CPU time limit exceeded" }, { 30, "SIGXCPU", "Cpu Limit Exceeded" },
{ 31, "SIGXFSZ", "File size limit exceeded" }, { 31, "SIGXFSZ", "File Size Limit Exceeded" },
{ 32, "SIGWAITING","process' lwps are blocked" }, { 32, "SIGWAITING","No runnable lwp" },
{ 33, "SIGLWP", "Inter-LWP signal reserved by threads library" }, { 33, "SIGLWP", "Inter-lwp signal" },
{ 34, "SIGFREEZE","Check point freeze" }, { 34, "SIGFREEZE","Checkpoint Freeze" },
{ 35, "SIGTHAW", "Check point thaw" }, { 35, "SIGTHAW", "Checkpoint Thaw" },
{ 36, "SIGCANCEL","Cancelation signal reserved by threads library" }, { 36, "SIGCANCEL","Thread Cancelation" },
{ 37, "SIGLOST", "Resource lost" }, { 37, "SIGLOST", "Resource Lost" },
{ 38, "SIGRTMIN","First Realtime Signal" },
{ 39, "SIGRTMIN+1", "Second Realtime Signal" },
{ 40, "SIGRTMIN+2", "Third Realtime Signal" },
{ 41, "SIGRTMIN+3", "Fourth Realtime Signal" },
{ 42, "SIGRTMAX-3", "Fourth Last Realtime Signal" },
{ 43, "SIGRTMAX-2", "Third Last Realtime Signal" },
{ 44, "SIGRTMAX-1", "Second Last Realtime Signal" },
{ 45, "SIGRTMAX", "Last Realtime Signal" },
{ 0, NULL, NULL } { 0, NULL, NULL }
}; };
/*
* Now, just for the fun of it, let's try to be forward and backward
* compatible. The above list is from Solaris 7. If later releases
* include new signals, binary from the earlier release won't be
* able to get the signal names, but it can get the correct numbers.
* So...
*/
/*
#define MY_PRIVATE_COUNTOF(x) (sizeof(x)/sizeof(x[0]))
glibtop_signame *glibtop_sys_siglist;
static char *unknown = "Unknown";
static glibtop_signame rt_min =
{ 0, "SIGRTMIN", "First (highest-priority) realtime signal" };
static glibtop_signame rt_max =
{ 0, "SIGRTMIN", "Last (lowest-priority) realtime signal" };
static char *rt_desc = "Real time signal %d";
void
glibtop_init_signals(void)
{
int rtmin, rtmax, sigs, to, i;
char *bureq, p;
rtmin = sysconf(_SC_SIGRT_MIN);
rtmax = sysconf(_SC_SIGRT_MAX);
sigs = MY_PRIVATE_COUNTOF(siglist);
glibtop_sys_siglist = (glibtop_signame *)
malloc(rtmax * sizeof(glibtop_signame));
bureq = malloc((rtmax - rtmin - 1) * (strlen(rt_desc) + 4));
to = (sigs <= rtmin) ? sigs : rtmin;
memcpy(glibtop_sys_siglist, siglist, to * sizeof(glibtop_signame));
for(i = sigs; i < rtmin; ++i)
{
glibtop_sys_siglist[i].number = i + 1;
glibtop_sys_siglist[i].name = glibtop_sys_siglist[i].label = unknown;
}
glibtop_sys_siglist[rtmin - 1].number = rtmin;
glibtop_sys_siglist[rtmin - 1].name = rt_min.name;
glibtop_sys_siglist[rtmin - 1].label = rt_min.label;
for(p = bureq, i = rtmin; i < rtmax; ++i)
{
glibtop_sys_siglist[i].number = i + 1;
to = sprintf(p, "%d", i + 1) + 1;
glibtop_sys_siglist[i].name = p;
p += to;
to = sprintf(p, rt_desc, i - rtmin + 2) + 1;
glibtop_sys_siglist[i].label = p;
p += to;
}
glibtop_sys_siglist[rtmax - 1].number = rtmax;
glibtop_sys_siglist[rtmax - 1].name = rt_max.name;
glibtop_sys_siglist[rtmax - 1].label = rt_max.label;
glibtop_sys_siglist[rtmax].number = 0;
glibtop_sys_siglist[rtmax].name = glibtop_sys_siglist[rtmax].label = NULL;
}
*/

View File

@@ -27,7 +27,10 @@
#include <time.h> #include <time.h>
static const unsigned long _glibtop_sysdeps_uptime = static const unsigned long _glibtop_sysdeps_uptime =
(1L << GLIBTOP_UPTIME_UPTIME) + (1L <<GLIBTOP_UPTIME_BOOT_TIME); #if LIBGTOP_VERSION_CODE >= 1001002
(1L <<GLIBTOP_UPTIME_BOOT_TIME) +
#endif
(1L << GLIBTOP_UPTIME_UPTIME);
/* Init function. */ /* Init function. */
@@ -46,7 +49,9 @@ glibtop_get_uptime_s (glibtop *server, glibtop_uptime *buf)
if(!(server->machine.boot)) if(!(server->machine.boot))
return; return;
#if LIBGTOP_VERSION_CODE >= 1001002
buf->boot_time = server->machine.boot; buf->boot_time = server->machine.boot;
#endif
buf->uptime = time(NULL) - server->machine.boot; buf->uptime = time(NULL) - server->machine.boot;
buf->flags = _glibtop_sysdeps_uptime; buf->flags = _glibtop_sysdeps_uptime;