**** 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
libgtop_sysdeps.la
*.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>
* glibtop_private.h: Fixed typoo.

View File

@@ -2,17 +2,25 @@ LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
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 \
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 procdata.c
libgtop_sysdeps_la_SOURCES = open.c close.c siglist.c cpu.c mem.c \
safeio.c swap.c uptime.c loadavg.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 procdata.c
libgtop_sysdeps_la_LDFLAGS = $(LT_VERSION_INFO)
include_HEADERS = glibtop_server.h glibtop_machine.h
noinst_HEADERS = glibtop_private.h
libgtop_sysdeps_la_LIBADD = @DL_LIB@
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_XCPU_TOTAL) + (1L << GLIBTOP_XCPU_USER) +
(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. */
@@ -77,7 +80,11 @@ glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf)
++found;
if(p_online(cpu, P_STATUS) == P_ONLINE)
#if LIBGTOP_VERSION_CODE >= 1001002
buf->xcpu_flags |= (1L << cpu);
#else
;
#endif
else
continue;
ret = kstat_read (kc, ksp, &cpu_stat);

View File

@@ -25,7 +25,11 @@
#define __GLIBTOP_MACHINE_H__
#include <sys/param.h>
#ifdef HAVE_PROCFS_H
#include <procfs.h>
#else
#include <sys/procfs.h>
#endif
#include <fcntl.h>
#include <kstat.h>
@@ -40,6 +44,7 @@ struct _glibtop_machine
{
uid_t uid, euid;
gid_t gid, egid;
pid_t me; /* Don't ask why we need this */
kvm_t *kd;
@@ -55,9 +60,17 @@ struct _glibtop_machine
kstat_t *syspages; /* memory usage */
kstat_t *bunyip; /* more memory usage */
int pagesize; /* in kilobytes */
int ticks; /* clock ticks, as returned by sysconf(_SC_CLK_TCK) */
unsigned boot; /* boot time, it's ui32 in kstat */
int pagesize; /* in bits to shift, ie. 2^pagesize gives Kb */
int ticks; /* clock ticks, as returned by sysconf() */
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

View File

@@ -28,23 +28,37 @@
#include <glibtop/error.h>
#include <sys/param.h>
#include <procfs.h>
#include <kstat.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
#ifdef HAVE_PROCFS_H
/* Read /proc/<pid>/psinfo */
int glibtop_get_proc_data_psinfo_s (glibtop *server, struct psinfo *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);
int glibtop_get_proc_data_psinfo_s(glibtop *, struct psinfo *, pid_t pid);
/* Read /proc/<pid>/status */
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 */
void glibtop_get_kstats(glibtop *);

View File

@@ -31,9 +31,9 @@ BEGIN_LIBGTOP_DECLS
#define GLIBTOP_SUID_SWAP 0
#define GLIBTOP_SUID_UPTIME 0
#define GLIBTOP_SUID_LOADAVG 0
#define GLIBTOP_SUID_SHM_LIMITS 0
#define GLIBTOP_SUID_MSG_LIMITS 0
#define GLIBTOP_SUID_SEM_LIMITS 0
#define GLIBTOP_SUID_SHM_LIMITS (1L << GLIBTOP_SYSDEPS_SHM_LIMITS)
#define GLIBTOP_SUID_MSG_LIMITS (1L << GLIBTOP_SYSDEPS_MSG_LIMITS)
#define GLIBTOP_SUID_SEM_LIMITS (1L << GLIBTOP_SYSDEPS_SEM_LIMITS)
#define GLIBTOP_SUID_PROCLIST 0
#define GLIBTOP_SUID_PROC_STATE 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;
int pagesize = server->machine.pagesize;
#ifndef KSTAT_DATA_UINT32
#define ui32 ul
#endif
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;
if(!kc)
@@ -77,18 +81,18 @@ glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
if(kn)
{
#ifdef _LP64
buf->free = kn->value.ui64 * pagesize;
buf->free = kn->value.ui64 << pagesize << 10;
#else
buf->free = kn->value.ui32 * pagesize;
buf->free = kn->value.ui32 << pagesize << 10;
#endif
buf->used = buf->total - buf->free;
}
kn = (kstat_named_t *)kstat_data_lookup(ksp, "pageslocked");
if(kn)
#ifdef _LP64
buf->locked = kn->value.ui64 * pagesize;
buf->locked = kn->value.ui64 << pagesize;
#else
buf->locked = kn->value.ui32 * pagesize;
buf->locked = kn->value.ui32 << pagesize;
#endif
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");
if(kn)
#ifdef _LP64
buf->user = kn->value.ui64 * pagesize;
buf->user = kn->value.ui64 << pagesize << 10;
#else
buf->user = kn->value.ui32 * pagesize;
buf->user = kn->value.ui32 << pagesize << 10;
#endif
kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_exec");
if(kn)
#ifdef _LP64
buf->shared = kn->value.ui64 * pagesize;
buf->shared = kn->value.ui64 << pagesize << 10;
#else
buf->shared = kn->value.ui32 * pagesize;
buf->shared = kn->value.ui32 << pagesize << 10;
#endif
kn = (kstat_named_t *)kstat_data_lookup(ksp, "pages_vnode");
if(kn)
#ifdef _LP64
buf->buffer = kn->value.ui64 * pagesize;
buf->buffer = kn->value.ui64 << pagesize << 10;
#else
buf->buffer = kn->value.ui32 * pagesize;
buf->buffer = kn->value.ui32 << pagesize << 10;
#endif
buf->flags += _glibtop_sysdeps_mem_bunyip;
}

View File

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

View File

@@ -22,8 +22,10 @@
*/
#include <glibtop/open.h>
#include <glibtop/cpu.h>
#include <unistd.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/processor.h>
@@ -60,6 +62,8 @@ glibtop_get_kstats(glibtop *server)
if(ksp)
{
kstat_read(kc, ksp, &server->machine.vminfo);
/* Don't change snaptime if we only need to reinitialize kstats */
if(!(server->machine.vminfo_snaptime))
server->machine.vminfo_snaptime = ksp->ks_snaptime;
}
@@ -69,7 +73,7 @@ glibtop_get_kstats(glibtop *server)
life time of a process, but let's hope that's just an error in
the documentation. */
if(nproc_same = new_ncpu == server->ncpu)
if((nproc_same = new_ncpu) == server->ncpu)
{
int checked, i;
char cpu[20];
@@ -128,10 +132,14 @@ glibtop_open_s (glibtop *server, const char *program_name,
kstat_ctl_t *kc;
kstat_t *ksp;
kstat_named_t *kn;
int i, page;
void *dl;
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.kc = kc = kstat_open ();
@@ -164,6 +172,7 @@ glibtop_open_s (glibtop *server, const char *program_name,
glibtop_warn_io_r (server, "kstat_open ()");
server->ncpu = -1; /* Force processor detection */
server->machine.vminfo_snaptime = 0; /* Force snaptime read */
glibtop_get_kstats(server);
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");
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);
if(!server->machine.kd)
glibtop_warn_io_r(server, "kvm_open()");
/* Now let's have a bit of magic dust... */
fprintf (stderr, "Sleeping 2 seconds, please wait ...\n");
sleep (2);
#if GLIBTOP_SOLARIS_RELEASE >= 560
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/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. */
@@ -42,6 +43,41 @@ char *
glibtop_get_proc_args_s (glibtop *server, glibtop_proc_args *buf,
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));
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_private.h>
#include <glibtop/procuid.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. */
int
@@ -35,19 +53,21 @@ glibtop_get_proc_data_psinfo_s (glibtop *server, struct psinfo *psinfo, pid_t pi
char buffer [BUFSIZ];
sprintf (buffer, "/proc/%d/psinfo", (int) pid);
fd = open (buffer, O_RDONLY);
fd = s_open (buffer, O_RDONLY);
if (fd < 0) {
glibtop_warn_io_r (server, "open (%s)", buffer);
return -1;
}
if (pread (fd, psinfo, sizeof (struct psinfo), 0) != sizeof (struct psinfo)) {
close (fd);
if (s_pread (fd, psinfo, sizeof (struct psinfo), 0) !=
sizeof (struct psinfo))
{
s_close (fd);
glibtop_warn_io_r (server, "pread (%s)", buffer);
return -1;
}
close (fd);
s_close (fd);
return 0;
}
@@ -58,44 +78,63 @@ glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t p
char buffer [BUFSIZ];
sprintf (buffer, "/proc/%d/usage", (int) pid);
fd = open (buffer, O_RDONLY);
fd = s_open (buffer, O_RDONLY);
if (fd < 0) {
glibtop_warn_io_r (server, "open (%s)", buffer);
return -1;
}
if (pread (fd, prusage, sizeof (struct prusage), 0) != sizeof (struct prusage)) {
close (fd);
if (s_pread (fd, prusage, sizeof (struct prusage), 0) !=
sizeof (struct prusage))
{
s_close (fd);
glibtop_warn_io_r (server, "pread (%s)", buffer);
return -1;
}
close (fd);
s_close (fd);
return 0;
}
#if LIBGTOP_VERSION_CODE >= 1001002
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;
size_t toread;
char buffer[BUFSIZ];
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)
glibtop_warn_io_r(server, "open (%s)", buffer);
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);
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;
}
#endif
int
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];
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)
glibtop_warn_io_r(server, "open (%s)", buffer);
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);
return -1;
}
close(fd);
s_close(fd);
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
static const unsigned long _glibtop_sysdeps_proclist =
(1 << GLIBTOP_PROCLIST_TOTAL) + (1 << GLIBTOP_PROCLIST_NUMBER) +
(1 << GLIBTOP_PROCLIST_SIZE);
(1L << GLIBTOP_PROCLIST_TOTAL) + (1L << GLIBTOP_PROCLIST_NUMBER) +
(1L << GLIBTOP_PROCLIST_SIZE);
/* Init function. */
@@ -61,13 +61,47 @@ glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf,
DIR *proc;
struct dirent *entry;
char buffer [BUFSIZ];
unsigned count, total, pid;
unsigned count, total, pid, mask;
unsigned pids [BLOCK_COUNT], *pids_chain = NULL;
unsigned pids_size = 0, pids_offset = 0, new_size;
struct stat statb;
int len, i, ok;
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");
if (!proc) return NULL;
@@ -79,23 +113,78 @@ glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf,
ok = 1; len = strlen (entry->d_name);
/* does it consist entirely of digits? */
#if 0
/* It does, except for "." and "..". Let's speed up */
for (i = 0; i < len; i++)
if (!isdigit (entry->d_name [i])) ok = 0;
if (!ok) continue;
#else
if(entry->d_name[0] == '.')
continue;
#endif
/* convert it in a number */
#if 0
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
/* Can we skip it based on the request? We have
RUID and RGID in struct stat. But we can't do it
like this for LP64 process, because stat() will fail.
XXX Unimplemented for now */
if(!mask && which == GLIBTOP_KERN_PROC_RUID)
{
sprintf (buffer, "/proc/%d", pid);
if (stat (buffer, &statb)) continue;
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
* full, we copy it to the pids_chain. */
@@ -126,7 +215,7 @@ glibtop_get_proclist_s (glibtop *server, glibtop_proclist *buf,
total++;
}
closedir (proc);
s_closedir (proc);
/* count is only zero if an error occured (one a running Linux system,
* we have at least one single process). */

View File

@@ -30,12 +30,17 @@
#include <errno.h>
#include <alloca.h>
#include "safeio.h"
static const unsigned long _glibtop_sysdeps_proc_map =
(1L << GLIBTOP_PROC_MAP_NUMBER) + (1L << GLIBTOP_PROC_MAP_TOTAL) +
(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);
static const unsigned long _glibtop_sysdeps_map_device =
(1L << GLIBTOP_MAP_ENTRY_DEVICE) + (1L << GLIBTOP_MAP_ENTRY_INODE);
/* Init function. */
@@ -51,51 +56,103 @@ glibtop_init_proc_map_s (glibtop *server)
glibtop_map_entry *
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;
#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;
struct stat inode;
char buffer[BUFSIZ];
memset (buf, 0, sizeof (glibtop_proc_map));
sprintf(buffer, "/proc/%d/map", (int)pid);
if((fd = open(buffer, O_RDONLY)) < 0)
#ifdef HAVE_PROCFS_H
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)
glibtop_warn_io_r(server, "open (%s)", buffer);
return NULL;
}
#ifdef HAVE_PROCFS_H
if(fstat(fd, &inode) < 0)
{
if(errno != EOVERFLOW)
glibtop_warn_io_r(server, "fstat (%s)", buffer);
/* else call daemon for 64-bit support */
close(fd);
s_close(fd);
return NULL;
}
maps = alloca(inode.st_size);
nmaps = inode.st_size / sizeof(prmap_t);
if(pread(fd, maps, inode.st_size, 0) != inode.st_size)
nmaps = inode.st_size / sizeof(prxmap_t);
if(s_pread(fd, maps, inode.st_size, 0) != inode.st_size)
{
glibtop_warn_io_r(server, "pread (%s)", buffer);
close(fd);
s_close(fd);
return NULL;
}
close(fd);
if(!(entry = glibtop_malloc_r(server, nmaps * sizeof(glibtop_map_entry))))
#else
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;
buf->number = nmaps;
buf->size = sizeof(glibtop_map_entry);
buf->total = 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].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)
entry[i].perm |= GLIBTOP_MAP_PERM_READ;
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
entry[i].perm |= GLIBTOP_MAP_PERM_PRIVATE;
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;
s_close(fd);
return entry;
}

View File

@@ -24,7 +24,9 @@
#include <glibtop.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. */
@@ -37,8 +39,26 @@ glibtop_init_proc_mem_s (glibtop *server)
/* Provides detailed information about a process. */
void
glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf,
pid_t pid)
glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, 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));
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,
pid_t pid)
{
#ifdef HAVE_PROCFS_H
struct pstatus pstatus;
#else
struct prstatus pstatus;
#endif
int size;
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);
memcpy(buf->signal, &pstatus.pr_sigpend, size);
#ifdef HAVE_PROCFS_H
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,
but this should be a good enough approximation. */

View File

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

View File

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

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_NICE);
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_NGROUPS) + (1L << GLIBTOP_PROC_UID_GROUPS);
(1L << GLIBTOP_PROC_UID_NGROUPS);
#else
0;
#endif
/* Init function. */
void
@@ -51,8 +57,18 @@ glibtop_init_proc_uid_s (glibtop *server)
void
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;
#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));
@@ -66,17 +82,27 @@ glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid)
buf->pid = psinfo.pr_pid;
buf->ppid = psinfo.pr_ppid;
#ifdef HAVE_PROCFS_H
buf->pgrp = psinfo.pr_pgid;
#else
buf->pgrp = psinfo.pr_pgrp;
#endif
buf->session = psinfo.pr_sid;
buf->tty = psinfo.pr_ttydev;
#ifdef HAVE_PROCFS_H
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;
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;
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) ?
prcred.pr_ngroups : GLIBTOP_MAX_GROUPS;
#ifdef HAVE_PROCFS_H
if(sizeof(int) == sizeof(gid_t))
memcpy(buf->groups, prcred.pr_groups,
buf->ngroups * sizeof(gid_t));
memcpy(buf->groups, &groups, buf->ngroups * sizeof(gid_t));
else
{
int 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;
}

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. */
void
glibtop_init_sem_limits_s (glibtop *server)
glibtop_init_sem_limits_p (glibtop *server)
{
kvm_t *kd = server->machine.kd;
@@ -51,7 +51,7 @@ glibtop_init_sem_limits_s (glibtop *server)
/* Provides information about sysv sem limits. */
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;
struct seminfo sinfo;

View File

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

View File

@@ -24,104 +24,51 @@
#include <glibtop.h>
#include <glibtop/signal.h>
static const glibtop_signame glibtop_sys_siglist [] =
const glibtop_signame glibtop_sys_siglist [] =
{ { 1, "SIGHUP", "Hangup" },
{ 2, "SIGINT", "Interrupt" },
{ 3, "SIGQUIT", "Quit" },
{ 4, "SIGILL", "Illegal instruction" },
{ 5, "SIGTRAP", "Trace or breakpoint trap" },
{ 4, "SIGILL", "Illegal Instruction" },
{ 5, "SIGTRAP", "Trace/Breakpoint Trap" },
{ 6, "SIGABRT", "Abort" },
{ 7, "SIGEMT", "Emulation trap" },
{ 8, "SIGFPE", "Arithmetic exception" },
{ 9, "SIGKILL", "Kill" },
{ 10, "SIGBUS", "Bus error" },
{ 11, "SIGSEGV", "Segmentation fault" },
{ 12, "SIGSYS", "Bad system call" },
{ 13, "SIGPIPE", "Broken pipe" },
{ 14, "SIGALRM", "Alarm clock" },
{ 15, "SIGTERM", "Terminate" },
{ 16, "SIGUSR1", "User signal 1" },
{ 17, "SIGUSR2", "User signal 2" },
{ 18, "SIGCHLD", "Child status changed" },
{ 19, "SIGPWR", "Power fail or restart" },
{ 20, "SIGWINCH","Window size change" },
{ 21, "SIGURG", "Urgent socket condition" },
{ 22, "SIGPOLL", "Pollable event" },
{ 23, "SIGSTOP", "Stop (cannot be ignored)" },
{ 24, "SIGTSTP", "User stop requested from tty" },
{ 25, "SIGCONT", "Continue" },
{ 26, "SIGTTIN", "Background tty read attempted" },
{ 27, "SIGTTOU", "Background tty write attempted" },
{ 28, "SIGVTALRM","Virtual timer expired" },
{ 29, "SIGPROF", "Profiling timer expired" },
{ 30, "SIGXCPU", "CPU time limit exceeded" },
{ 31, "SIGXFSZ", "File size limit exceeded" },
{ 32, "SIGWAITING","process' lwps are blocked" },
{ 33, "SIGLWP", "Inter-LWP signal reserved by threads library" },
{ 34, "SIGFREEZE","Check point freeze" },
{ 35, "SIGTHAW", "Check point thaw" },
{ 36, "SIGCANCEL","Cancelation signal reserved by threads library" },
{ 37, "SIGLOST", "Resource lost" },
{ 7, "SIGEMT", "Emulation Trap" },
{ 8, "SIGFPE", "Arithmetic Exception" },
{ 9, "SIGKILL", "Killed" },
{ 10, "SIGBUS", "Bus Error" },
{ 11, "SIGSEGV", "Segmentation Fault" },
{ 12, "SIGSYS", "Bad System Call" },
{ 13, "SIGPIPE", "Broken Pipe" },
{ 14, "SIGALRM", "Alarm Clock" },
{ 15, "SIGTERM", "Terminated" },
{ 16, "SIGUSR1", "User Signal 1" },
{ 17, "SIGUSR2", "User Signal 2" },
{ 18, "SIGCHLD", "Child Status Changed" },
{ 19, "SIGPWR", "Power-Fail/Restart" },
{ 20, "SIGWINCH","Window Size Change" },
{ 21, "SIGURG", "Urgent Socket Condition" },
{ 22, "SIGPOLL", "Pollable Event" },
{ 23, "SIGSTOP", "Stoped (signal)" },
{ 24, "SIGTSTP", "Stopped (user)" },
{ 25, "SIGCONT", "Continued" },
{ 26, "SIGTTIN", "Stopped (tty input)" },
{ 27, "SIGTTOU", "Stopped (tty output)" },
{ 28, "SIGVTALRM","Virtual Timer Expired" },
{ 29, "SIGPROF", "Profiling Timer Expired" },
{ 30, "SIGXCPU", "Cpu Limit Exceeded" },
{ 31, "SIGXFSZ", "File Size Limit Exceeded" },
{ 32, "SIGWAITING","No runnable lwp" },
{ 33, "SIGLWP", "Inter-lwp signal" },
{ 34, "SIGFREEZE","Checkpoint Freeze" },
{ 35, "SIGTHAW", "Checkpoint Thaw" },
{ 36, "SIGCANCEL","Thread Cancelation" },
{ 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 }
};
/*
* 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>
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. */
@@ -46,7 +49,9 @@ glibtop_get_uptime_s (glibtop *server, glibtop_uptime *buf)
if(!(server->machine.boot))
return;
#if LIBGTOP_VERSION_CODE >= 1001002
buf->boot_time = server->machine.boot;
#endif
buf->uptime = time(NULL) - server->machine.boot;
buf->flags = _glibtop_sysdeps_uptime;