Blame sysdeps/openbsd/procopenfiles.c

Packit Service 407539
/* Copyright (C) 1998-99 Martin Baulig
Packit Service 407539
   Copyright (C) 2004 Nicol\ufffds Lichtmaier
Packit Service 407539
   Copyright (C) 2007 Joe Marcus Clarke
Packit Service 407539
   Copyright (C) 2013 Robert Nagy
Packit Service 407539
   This file is part of LibGTop 1.0.
Packit Service 407539
Packit Service 407539
   Modified by Nicol\ufffds Lichtmaier to give a process open files.
Packit Service 407539
Packit Service 407539
   Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998.
Packit Service 407539
Packit Service 407539
   LibGTop is free software; you can redistribute it and/or modify it
Packit Service 407539
   under the terms of the GNU General Public License as published by
Packit Service 407539
   the Free Software Foundation; either version 2 of the License,
Packit Service 407539
   or (at your option) any later version.
Packit Service 407539
Packit Service 407539
   LibGTop is distributed in the hope that it will be useful, but WITHOUT
Packit Service 407539
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit Service 407539
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit Service 407539
   for more details.
Packit Service 407539
Packit Service 407539
   You should have received a copy of the GNU General Public License
Packit Service 407539
   along with LibGTop; see the file COPYING. If not, write to the
Packit Service 407539
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit Service 407539
   Boston, MA 02110-1301, USA.
Packit Service 407539
*/
Packit Service 407539
Packit Service 407539
#include <config.h>
Packit Service 407539
#include <glibtop.h>
Packit Service 407539
#include <glibtop/error.h>
Packit Service 407539
#include <glibtop/procopenfiles.h>
Packit Service 407539
#include <sys/types.h>
Packit Service 407539
#include <sys/socket.h>
Packit Service 407539
#include <sys/param.h>
Packit Service 407539
#include <sys/sysctl.h>
Packit Service 407539
#define _KERNEL
Packit Service 407539
#include <sys/file.h>
Packit Service 407539
#undef _KERNEL
Packit Service 407539
#include <sys/mount.h>
Packit Service 407539
#include <sys/un.h>
Packit Service 407539
#include <sys/vnode.h>
Packit Service 407539
#include <netinet/in.h>
Packit Service 407539
#include <arpa/inet.h>
Packit Service 407539
#include <string.h>
Packit Service 407539
#include <stdlib.h>
Packit Service 407539
#include <kvm.h>
Packit Service 407539
Packit Service 407539
#include "glibtop_private.h"
Packit Service 407539
Packit Service 407539
static const unsigned long _glibtop_sysdeps_proc_open_files =
Packit Service 407539
(1L << GLIBTOP_PROC_OPEN_FILES_NUMBER)|
Packit Service 407539
(1L << GLIBTOP_PROC_OPEN_FILES_TOTAL)|
Packit Service 407539
(1L << GLIBTOP_PROC_OPEN_FILES_SIZE);
Packit Service 407539
Packit Service 407539
kvm_t *kd;
Packit Service 407539
Packit Service 407539
struct filearg {
Packit Service 407539
	SLIST_ENTRY(filearg) next;
Packit Service 407539
	dev_t dev;
Packit Service 407539
	ino_t ino;
Packit Service 407539
	char *name;
Packit Service 407539
	TAILQ_HEAD(fuserhead, fuser) fusers;
Packit Service 407539
};
Packit Service 407539
Packit Service 407539
SLIST_HEAD(fileargs, filearg);
Packit Service 407539
Packit Service 407539
struct fileargs fileargs = SLIST_HEAD_INITIALIZER(fileargs);
Packit Service 407539
Packit Service 407539
/* Init function. */
Packit Service 407539
Packit Service 407539
void
Packit Service 407539
_glibtop_init_proc_open_files_s (glibtop *server)
Packit Service 407539
{
Packit Service 407539
	server->sysdeps.proc_open_files = _glibtop_sysdeps_proc_open_files;
Packit Service 407539
}
Packit Service 407539
Packit Service 407539
static char *
Packit Service 407539
addr_to_string(struct kinfo_file *kf)
Packit Service 407539
{
Packit Service 407539
	char *buffer = NULL;
Packit Service 407539
	struct in_addr faddr;
Packit Service 407539
Packit Service 407539
	memcpy(&faddr, kf->inp_faddru, sizeof(faddr));
Packit Service 407539
Packit Service 407539
	if ((kf->so_protocol == IPPROTO_TCP) ||
Packit Service 407539
	    (kf->so_protocol == IPPROTO_UDP)) {
Packit Service 407539
		if (kf->inp_fport) {
Packit Service 407539
			buffer = g_strdup(faddr.s_addr == INADDR_ANY ? "*" :
Packit Service 407539
 			    inet_ntoa(faddr));
Packit Service 407539
		}
Packit Service 407539
	}
Packit Service 407539
Packit Service 407539
	return buffer;
Packit Service 407539
}
Packit Service 407539
Packit Service 407539
glibtop_open_files_entry *
Packit Service 407539
glibtop_get_proc_open_files_s (glibtop *server, glibtop_proc_open_files *buf,	pid_t pid)
Packit Service 407539
{
Packit Service 407539
	struct kinfo_file *kf, *kflast;
Packit Service 407539
	int cnt;
Packit Service 407539
	char kbuf[_POSIX2_LINE_MAX];
Packit Service 407539
	GArray *entries;
Packit Service 407539
Packit Service 407539
	memset(buf, 0, sizeof (glibtop_proc_open_files));
Packit Service 407539
Packit Service 407539
	if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, kbuf)) == NULL)
Packit Service 407539
		g_warning("%s", kbuf);
Packit Service 407539
Packit Service 407539
	if ((kf = kvm_getfiles(kd, KERN_FILE_BYPID, pid, sizeof(*kf), &cnt)) == NULL)
Packit Service 407539
		g_warning("%s", kvm_geterr(kd));
Packit Service 407539
Packit Service 407539
	entries = g_array_new(FALSE, FALSE, sizeof(glibtop_open_files_entry));
Packit Service 407539
Packit Service 407539
	for (kflast = &kf[cnt]; kf < kflast; ++kf) {
Packit Service 407539
		glibtop_open_files_entry entry = {0};
Packit Service 407539
Packit Service 407539
		if (kf->fd_fd < 0)
Packit Service 407539
			continue;
Packit Service 407539
Packit Service 407539
		if (kf->f_type == DTYPE_SOCKET) {
Packit Service 407539
			if (kf->so_family == AF_LOCAL) {
Packit Service 407539
				entry.type = GLIBTOP_FILE_TYPE_LOCALSOCKET;
Packit Service 407539
				static char *stypename[] = {
Packit Service 407539
					"unused",	/* 0 */
Packit Service 407539
					"stream",
Packit Service 407539
					"dgram",
Packit Service 407539
					"raw",
Packit Service 407539
					"rdm",
Packit Service 407539
					"seqpak"
Packit Service 407539
				};
Packit Service 407539
#define STYPEMAX 5
Packit Service 407539
				char *stype, stypebuf[24];
Packit Service 407539
Packit Service 407539
				if (kf->so_type > STYPEMAX) {
Packit Service 407539
					snprintf(stypebuf, sizeof(stypebuf), "?%d", kf->so_type);
Packit Service 407539
					stype = stypebuf;
Packit Service 407539
				} else {
Packit Service 407539
					stype = stypename[kf->so_type];
Packit Service 407539
				}
Packit Service 407539
				g_strlcpy(entry.info.localsock.name, stype,
Packit Service 407539
				    sizeof(entry.info.localsock.name));
Packit Service 407539
			} else if (kf->so_family == AF_INET ||
Packit Service 407539
				   kf->so_family == AF_INET6) {
Packit Service 407539
				char *addrstr;
Packit Service 407539
Packit Service 407539
				if (kf->so_family == AF_INET)
Packit Service 407539
					entry.type = GLIBTOP_FILE_TYPE_INETSOCKET;
Packit Service 407539
				else
Packit Service 407539
					entry.type = GLIBTOP_FILE_TYPE_INET6SOCKET;
Packit Service 407539
Packit Service 407539
				addrstr = addr_to_string(kf);
Packit Service 407539
				g_strlcpy(entry.info.sock.dest_host,
Packit Service 407539
					  addrstr,
Packit Service 407539
					  sizeof(entry.info.sock.dest_host));
Packit Service 407539
				g_free(addrstr);
Packit Service 407539
				entry.info.sock.dest_port = kf->inp_fport ? ntohs(kf->inp_fport) : 0;
Packit Service 407539
			}
Packit Service 407539
		} else if (kf->f_type == DTYPE_PIPE) {
Packit Service 407539
			entry.type = GLIBTOP_FILE_TYPE_PIPE;
Packit Service 407539
		} else if (kf->f_type == DTYPE_VNODE) {
Packit Service 407539
			int badtype = 0;
Packit Service 407539
			char nbuf[MAXPATHLEN];
Packit Service 407539
Packit Service 407539
			entry.type = GLIBTOP_FILE_TYPE_FILE;
Packit Service 407539
Packit Service 407539
			if ((kf->v_type == VNON) ||
Packit Service 407539
			    (kf->v_type == VBAD) ||
Packit Service 407539
			    (kf->v_tag == VT_NON && !(kf->v_flag & VCLONE))) {
Packit Service 407539
				badtype = 1;
Packit Service 407539
			}
Packit Service 407539
Packit Service 407539
			if (badtype)
Packit Service 407539
				continue;
Packit Service 407539
Packit Service 407539
			if ((kf->v_type == VBLK) ||
Packit Service 407539
			    (kf->v_type == VCHR)) {
Packit Service 407539
				snprintf(nbuf, sizeof(nbuf), "/dev/%s",
Packit Service 407539
				    devname(kf->va_rdev, kf->v_type == VCHR ?  S_IFCHR : S_IFBLK));
Packit Service 407539
			} else {
Packit Service 407539
				snprintf(nbuf, sizeof(nbuf), "inode %llu on %s", kf->va_fileid,
Packit Service 407539
				    kf->f_mntonname);
Packit Service 407539
			}
Packit Service 407539
			g_strlcpy(entry.info.file.name, nbuf,
Packit Service 407539
			    sizeof(entry.info.file.name));
Packit Service 407539
		} else
Packit Service 407539
			continue;
Packit Service 407539
Packit Service 407539
		entry.fd = kf->fd_fd;
Packit Service 407539
Packit Service 407539
		g_array_append_val(entries, entry);
Packit Service 407539
	}
Packit Service 407539
Packit Service 407539
	buf->flags = _glibtop_sysdeps_proc_open_files;
Packit Service 407539
	buf->number = entries->len;
Packit Service 407539
	buf->size = sizeof(glibtop_open_files_entry);
Packit Service 407539
	buf->total = buf->number * buf->size;
Packit Service 407539
Packit Service 407539
	return (glibtop_open_files_entry*)g_array_free(entries, FALSE);
Packit Service 407539
}