Initial Solaris 2.5 port. It's far from being complete and hasn't been

* 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.
This commit is contained in:
Drazen Kacar
1999-05-09 20:27:43 +00:00
parent 777c371be9
commit 03be66c857
11 changed files with 263 additions and 29 deletions

View File

@@ -1,3 +1,13 @@
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

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>
@@ -58,6 +62,7 @@ struct _glibtop_machine
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, it's ui32 in kstat */
long argvenvp; /* max length or argv + env */
};
END_LIBGTOP_DECLS

View File

@@ -57,6 +57,10 @@ 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;

View File

@@ -179,6 +179,7 @@ glibtop_open_s (glibtop *server, const char *program_name,
if(kn)
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;
@@ -187,6 +188,16 @@ glibtop_open_s (glibtop *server, const char *program_name,
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
}
}

View File

@@ -29,6 +29,21 @@
#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
@@ -135,10 +150,117 @@ glibtop_get_proc_status_s(glibtop *server, struct pstatus *pstatus, pid_t pid)
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;
}
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

@@ -79,23 +79,31 @@ 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;
/* is it really a directory? */
#else
pid = (unsigned)atol(entry->d_name);
#endif
sprintf (buffer, "/proc/%d", pid);
#ifdef HAVE_PROCFS_H
/* is it really a directory? */
if (s_stat (buffer, &statb)) continue;
if (!S_ISDIR (statb.st_mode)) continue;
#endif
/* Fine. Now we first try to store it in pids. If this buffer is
* full, we copy it to the pids_chain. */

View File

@@ -55,25 +55,39 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
{
int fd, i, nmaps;
prmap_t *maps;
/* 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));
#ifdef HAVE_PROCFS_H
sprintf(buffer, "/proc/%d/map", (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);
@@ -81,13 +95,28 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
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
s_close(fd);
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);
@@ -97,7 +126,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
{
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;
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)
@@ -110,7 +139,6 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
entry[i].perm |= GLIBTOP_MAP_PERM_PRIVATE;
entry[i].flags = _glibtop_sysdeps_map_entry;
}
buf->flags = _glibtop_sysdeps_proc_map;
return entry;
}

View File

@@ -39,19 +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)
{
int pagesize = server->machine.pagesize;
#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;
buf->size = buf->vsize = psinfo.pr_size;
buf->resident = buf->rss = psinfo.pr_rssize;
#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,13 @@
#include <glibtop_private.h>
static const unsigned long _glibtop_sysdeps_proc_state =
#ifdef HAVE_PROCFS_H
(1L << GLIBTOP_PROC_STATE_HAS_CPU) + (1L << GLIBTOP_PROC_STATE_PROCESSOR) +
(1L << GLIBTOP_PROC_STATE_LAST_PROCESSOR) +
#endif
(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) +
(1L << GLIBTOP_PROC_STATE_HAS_CPU) + (1L << GLIBTOP_PROC_STATE_PROCESSOR) +
(1L << GLIBTOP_PROC_STATE_LAST_PROCESSOR);
(1L << GLIBTOP_PROC_STATE_RUID) + (1L << GLIBTOP_PROC_STATE_RGID);
/* Init function. */
@@ -46,7 +48,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));
@@ -57,10 +63,17 @@ glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid)
buf->gid = psinfo.pr_egid;
buf->ruid = psinfo.pr_uid;
buf->rgid = psinfo.pr_gid;
#ifdef HAVE_PROCFS_H
switch(psinfo.pr_lwp.pr_state)
#else
switch(psinfo.pr_state)
#endif
{
case SONPROC: buf->has_cpu = 1;
case SONPROC:
#ifdef HAVE_PROCFS_H
buf->has_cpu = 1;
buf->processor = psinfo.pr_lwp.pr_onpro;
#endif
case SRUN: buf->state = GLIBTOP_PROCESS_RUNNING;
break;
case SZOMB: buf->state = GLIBTOP_PROCESS_ZOMBIE;
@@ -70,9 +83,9 @@ glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid)
break;
case SIDL: buf->state = GLIBTOP_PROCESS_UNINTERRUPTIBLE;
}
#ifdef 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

@@ -34,9 +34,11 @@ 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 =
#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);
/* Init function. */
void
@@ -51,9 +53,14 @@ 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;
struct prcred prcred;
#ifdef HAVE_PROCFS_H
struct psinfo psinfo;
gid_t groups[GLIBTOP_MAX_GROUPS];
#else
struct prpsinfo psinfo;
gid_t groups[1]; /* dummy for consistent function prototype */
#endif
memset (buf, 0, sizeof (glibtop_proc_uid));
@@ -67,13 +74,22 @@ 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 - NZERO;
#else
buf->priority = psinfo.pr_pri;
buf->nice = psinfo.pr_nice - NZERO;
#endif
buf->flags = _glibtop_sysdeps_proc_uid_psinfo;
@@ -85,6 +101,7 @@ 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, &groups, buf->ngroups * sizeof(gid_t));
else
@@ -94,5 +111,6 @@ glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid)
for(i = 0; i < buf->ngroups; ++i)
buf->groups[i] = groups[i];
}
#endif
buf->flags += _glibtop_sysdeps_proc_uid_prcred;
}