Blame sysdeps/solaris/procdata.c

Packit d37888
/* Copyright (C) 1998-99 Martin Baulig
Packit d37888
   This file is part of LibGTop 1.0.
Packit d37888
Packit d37888
   Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998.
Packit d37888
Packit d37888
   LibGTop is free software; you can redistribute it and/or modify it
Packit d37888
   under the terms of the GNU General Public License as published by
Packit d37888
   the Free Software Foundation; either version 2 of the License,
Packit d37888
   or (at your option) any later version.
Packit d37888
Packit d37888
   LibGTop is distributed in the hope that it will be useful, but WITHOUT
Packit d37888
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit d37888
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit d37888
   for more details.
Packit d37888
Packit d37888
   You should have received a copy of the GNU General Public License
Packit d37888
   along with LibGTop; see the file COPYING. If not, write to the
Packit d37888
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit d37888
   Boston, MA 02110-1301, USA.
Packit d37888
*/
Packit d37888
Packit d37888
#include <config.h>
Packit d37888
#include <glibtop.h>
Packit d37888
#include <glibtop_private.h>
Packit d37888
#include <glibtop/procuid.h>
Packit d37888
#include <glibtop/error.h>
Packit d37888
Packit d37888
#include <errno.h>
Packit d37888
Packit d37888
#include "safeio.h"
Packit d37888
Packit d37888
/*
Packit d37888
 * The differences between old and new procfs API are:
Packit d37888
 * - old has /proc/<pid> file and ioctl() is used to obtain the data.
Packit d37888
 * - new has /proc/<pid>/* files and read() & friends are used to
Packit d37888
 *   obtain the data.
Packit d37888
 * - names of structures and members are different. It's mostly the
Packit d37888
 *   prefix. Old uses `pr' and new uses `ps'.
Packit d37888
 *
Packit d37888
 * Since almost every line would be in #ifdef, I think it would
Packit d37888
 * be more readable to just copy everything twice. This is not a big
Packit d37888
 * file, after all.
Packit d37888
 */
Packit d37888
Packit d37888
#ifdef HAVE_PROCFS_H
Packit d37888
Packit d37888
/* Read /proc/<pid>/psinfo. */
Packit d37888
Packit d37888
int
Packit d37888
glibtop_get_proc_data_psinfo_s (glibtop *server, struct psinfo *psinfo, pid_t pid)
Packit d37888
{
Packit d37888
	int fd;
Packit d37888
	char buffer [BUFSIZ];
Packit d37888
Packit d37888
	sprintf (buffer, "/proc/%d/psinfo", (int) pid);
Packit d37888
Packit d37888
	fd = s_open (buffer, O_RDONLY);
Packit d37888
Packit d37888
	if (fd < 0) {
Packit d37888
		glibtop_warn_io_r (server, "open (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	if (s_pread (fd, psinfo, sizeof (struct psinfo), 0)
Packit d37888
	    != sizeof (struct psinfo))
Packit d37888
	{
Packit d37888
		s_close (fd);
Packit d37888
		glibtop_warn_io_r (server, "pread (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	s_close (fd);
Packit d37888
	return 0;
Packit d37888
}
Packit d37888
Packit d37888
int
Packit d37888
glibtop_get_proc_data_usage_s (glibtop *server, struct prusage *prusage, pid_t pid)
Packit d37888
{
Packit d37888
	int fd;
Packit d37888
	char buffer [BUFSIZ];
Packit d37888
Packit d37888
	sprintf (buffer, "/proc/%d/usage", (int) pid);
Packit d37888
Packit d37888
	fd = s_open (buffer, O_RDONLY);
Packit d37888
Packit d37888
	if (fd < 0) {
Packit d37888
		glibtop_warn_io_r (server, "open (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	if (s_pread (fd, prusage, sizeof (struct prusage), 0)
Packit d37888
	    != sizeof (struct prusage))
Packit d37888
	{
Packit d37888
		s_close (fd);
Packit d37888
		glibtop_warn_io_r (server, "pread (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	s_close (fd);
Packit d37888
	return 0;
Packit d37888
}
Packit d37888
Packit d37888
#if LIBGTOP_VERSION_CODE >= 1001002
Packit d37888
int
Packit d37888
glibtop_get_proc_credentials_s(glibtop *server,
Packit d37888
			       struct prcred *prcred,
Packit d37888
			       gid_t *groups,
Packit d37888
			       pid_t pid)
Packit d37888
{
Packit d37888
	int fd;
Packit d37888
	size_t toread;
Packit d37888
	char buffer[BUFSIZ];
Packit d37888
Packit d37888
	sprintf(buffer, "/proc/%d/cred", (int)pid);
Packit d37888
Packit d37888
	if((fd = s_open(buffer, O_RDONLY)) < 0)
Packit d37888
	{
Packit d37888
		if(errno != EPERM && errno != EACCES)
Packit d37888
			glibtop_warn_io_r(server, "open (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	if(s_pread(fd, prcred, sizeof(struct prcred), 0)
Packit d37888
	   != sizeof(struct prcred))
Packit d37888
	{
Packit d37888
		s_close(fd);
Packit d37888
		glibtop_warn_io_r(server, "pread (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	if(prcred->pr_ngroups >= 0)
Packit d37888
	{
Packit d37888
		toread = MIN(prcred->pr_ngroups, GLIBTOP_MAX_GROUPS) * sizeof(gid_t);
Packit d37888
Packit d37888
		if((size_t) s_pread(fd,groups, toread,
Packit d37888
				    G_STRUCT_OFFSET(struct prcred, pr_groups))
Packit d37888
		   != toread)
Packit d37888
			prcred->pr_ngroups = 0;
Packit d37888
	}
Packit d37888
	s_close(fd);
Packit d37888
	return 0;
Packit d37888
}
Packit d37888
#endif /* LIBGTOP_VERSION_CODE >= 1001002 */
Packit d37888
Packit d37888
int
Packit d37888
glibtop_get_proc_status_s(glibtop *server, struct pstatus *pstatus, pid_t pid)
Packit d37888
{
Packit d37888
	int fd;
Packit d37888
	char buffer[BUFSIZ];
Packit d37888
Packit d37888
	sprintf(buffer, "/proc/%d/status", (int)pid);
Packit d37888
	if((fd = s_open(buffer, O_RDONLY)) < 0)
Packit d37888
	{
Packit d37888
		if(errno != EPERM && errno != EACCES)
Packit d37888
			glibtop_warn_io_r(server, "open (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
	if(s_pread(fd, pstatus, sizeof(struct pstatus), 0)
Packit d37888
	   != sizeof(struct pstatus))
Packit d37888
	{
Packit d37888
		s_close(fd);
Packit d37888
		glibtop_warn_io_r(server, "pread (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
	s_close(fd);
Packit d37888
	return 0;
Packit d37888
}
Packit d37888
Packit d37888
#else /* old API */
Packit d37888
Packit d37888
int
Packit d37888
glibtop_get_proc_data_psinfo_s (glibtop *server,
Packit d37888
				struct prpsinfo *psinfo,
Packit d37888
				pid_t pid)
Packit d37888
{
Packit d37888
	int fd;
Packit d37888
	char buffer [BUFSIZ];
Packit d37888
Packit d37888
	sprintf (buffer, "/proc/%d", (int) pid);
Packit d37888
	fd = s_open (buffer, O_RDONLY);
Packit d37888
	if (fd < 0) {
Packit d37888
		if(errno != EPERM && errno != EACCES)
Packit d37888
			glibtop_warn_io_r (server, "open (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	if(ioctl(fd, PIOCPSINFO, psinfo) < 0)
Packit d37888
	{
Packit d37888
		s_close (fd);
Packit d37888
		glibtop_warn_io_r (server, "ioctl(%s, PIOCPSINFO)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	s_close (fd);
Packit d37888
	return 0;
Packit d37888
}
Packit d37888
Packit d37888
int
Packit d37888
glibtop_get_proc_data_usage_s (glibtop *server,
Packit d37888
			       struct prusage *prusage,
Packit d37888
			       pid_t pid)
Packit d37888
{
Packit d37888
	int fd;
Packit d37888
	char buffer [BUFSIZ];
Packit d37888
Packit d37888
	sprintf (buffer, "/proc/%d", (int) pid);
Packit d37888
	fd = s_open (buffer, O_RDONLY);
Packit d37888
	if (fd < 0) {
Packit d37888
		if(errno != EPERM && errno != EACCES)
Packit d37888
			glibtop_warn_io_r (server, "open (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	if(ioctl(fd, PIOCUSAGE, prusage) < 0)
Packit d37888
	{
Packit d37888
		s_close (fd);
Packit d37888
		glibtop_warn_io_r (server, "ioctl(%s, PIOCUSAGE)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
Packit d37888
	s_close (fd);
Packit d37888
	return 0;
Packit d37888
}
Packit d37888
Packit d37888
int
Packit d37888
glibtop_get_proc_credentials_s(glibtop *server,
Packit d37888
			       struct prcred *prcred,
Packit d37888
			       gid_t *groups,
Packit d37888
			       pid_t pid)
Packit d37888
{
Packit d37888
	int fd;
Packit d37888
	size_t toread;
Packit d37888
	char buffer[BUFSIZ];
Packit d37888
Packit d37888
	sprintf(buffer, "/proc/%d", (int)pid);
Packit d37888
	if((fd = s_open(buffer, O_RDONLY)) < 0)
Packit d37888
	{
Packit d37888
		if(errno != EPERM && errno != EACCES)
Packit d37888
			glibtop_warn_io_r(server, "open (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
	if(ioctl(fd, PIOCCRED, prcred) < 0)
Packit d37888
	{
Packit d37888
		s_close(fd);
Packit d37888
		glibtop_warn_io_r(server, "ioctl(%s, PIOCCRED)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
	s_close(fd);
Packit d37888
	return 0;
Packit d37888
}
Packit d37888
Packit d37888
int
Packit d37888
glibtop_get_proc_status_s(glibtop *server, struct prstatus *pstatus, pid_t pid)
Packit d37888
{
Packit d37888
	int fd;
Packit d37888
	char buffer[BUFSIZ];
Packit d37888
Packit d37888
	sprintf(buffer, "/proc/%d", (int)pid);
Packit d37888
	if((fd = s_open(buffer, O_RDONLY)) < 0)
Packit d37888
	{
Packit d37888
		if(errno != EPERM && errno != EACCES)
Packit d37888
			glibtop_warn_io_r(server, "open (%s)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
	if(ioctl(fd, PIOCSTATUS, pstatus) < 0)
Packit d37888
	{
Packit d37888
		s_close(fd);
Packit d37888
		glibtop_warn_io_r(server, "ioctl(%s, PIOCSTATUS)", buffer);
Packit d37888
		return -1;
Packit d37888
	}
Packit d37888
	s_close(fd);
Packit d37888
	return 0;
Packit d37888
}
Packit d37888
#endif