summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2008-11-30 22:40:14 +0000
committerpeter <peter@FreeBSD.org>2008-11-30 22:40:14 +0000
commit16271b5bfa14998575e875d8911bbe565051831c (patch)
tree85c55795a8e2bf89d2218f061266b93e059c8813 /lib
parent2b1f03929a1b2aede23598bc1b54f8061c22fd69 (diff)
downloadFreeBSD-src-16271b5bfa14998575e875d8911bbe565051831c.zip
FreeBSD-src-16271b5bfa14998575e875d8911bbe565051831c.tar.gz
Add experimental front ends to the kinfo_vmentry and kinfo_filedesc
sysctls.
Diffstat (limited to 'lib')
-rw-r--r--lib/libutil/Makefile3
-rw-r--r--lib/libutil/kinfo_getfile.c72
-rw-r--r--lib/libutil/kinfo_getvmmap.c72
-rw-r--r--lib/libutil/libutil.h6
4 files changed, 152 insertions, 1 deletions
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile
index 017c5a8..1ea4c73 100644
--- a/lib/libutil/Makefile
+++ b/lib/libutil/Makefile
@@ -9,7 +9,8 @@ LIB= util
SHLIB_MAJOR= 7
SRCS= _secure_path.c auth.c expand_number.c flopen.c fparseln.c gr_util.c \
- hexdump.c humanize_number.c kld.c login.c login_auth.c login_cap.c \
+ hexdump.c humanize_number.c kinfo_getfile.c kinfo_getvmmap.c kld.c \
+ login.c login_auth.c login_cap.c \
login_class.c login_crypt.c login_ok.c login_times.c login_tty.c \
logout.c logwtmp.c pidfile.c property.c pty.c pw_util.c realhostname.c \
stub.c trimdomain.c uucplock.c
diff --git a/lib/libutil/kinfo_getfile.c b/lib/libutil/kinfo_getfile.c
new file mode 100644
index 0000000..de68961
--- /dev/null
+++ b/lib/libutil/kinfo_getfile.c
@@ -0,0 +1,72 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libutil.h"
+
+struct kinfo_file *
+kinfo_getfile(pid_t pid, int *cntp)
+{
+ int mib[4];
+ int error;
+ int cnt;
+ size_t len;
+ char *buf, *bp, *eb;
+ struct kinfo_file *kif, *kp, *kf;
+
+ len = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_FILEDESC;
+ mib[3] = pid;
+
+ error = sysctl(mib, 4, NULL, &len, NULL, 0);
+ if (error)
+ return (0);
+ len = len * 4 / 3;
+ buf = malloc(len);
+ if (buf == NULL)
+ return (0);
+ error = sysctl(mib, 4, buf, &len, NULL, 0);
+ if (error) {
+ free(buf);
+ return (0);
+ }
+ /* Pass 1: count items */
+ cnt = 0;
+ bp = buf;
+ eb = buf + len;
+ while (bp < eb) {
+ kf = (struct kinfo_file *)bp;
+ bp += kf->kf_structsize;
+ cnt++;
+ }
+
+ kif = calloc(cnt, sizeof(*kif));
+ if (kif == NULL) {
+ free(buf);
+ return (0);
+ }
+ bp = buf;
+ eb = buf + len;
+ kp = kif;
+ /* Pass 2: unpack */
+ while (bp < eb) {
+ kf = (struct kinfo_file *)bp;
+ /* Copy/expand into pre-zeroed buffer */
+ memcpy(kp, kf, kf->kf_structsize);
+ /* Advance to next packed record */
+ bp += kf->kf_structsize;
+ /* Set field size to fixed length, advance */
+ kp->kf_structsize = sizeof(*kp);
+ kp++;
+ }
+ free(buf);
+ *cntp = cnt;
+ return (kif); /* Caller must free() return value */
+}
diff --git a/lib/libutil/kinfo_getvmmap.c b/lib/libutil/kinfo_getvmmap.c
new file mode 100644
index 0000000..b5e7c96
--- /dev/null
+++ b/lib/libutil/kinfo_getvmmap.c
@@ -0,0 +1,72 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libutil.h"
+
+struct kinfo_vmentry *
+kinfo_getvmmap(pid_t pid, int *cntp)
+{
+ int mib[4];
+ int error;
+ int cnt;
+ size_t len;
+ char *buf, *bp, *eb;
+ struct kinfo_vmentry *kiv, *kp, *kv;
+
+ len = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_VMMAP;
+ mib[3] = pid;
+
+ error = sysctl(mib, 4, NULL, &len, NULL, 0);
+ if (error)
+ return (0);
+ len = len * 4 / 3;
+ buf = malloc(len);
+ if (buf == NULL)
+ return (0);
+ error = sysctl(mib, 4, buf, &len, NULL, 0);
+ if (error) {
+ free(buf);
+ return (0);
+ }
+ /* Pass 1: count items */
+ cnt = 0;
+ bp = buf;
+ eb = buf + len;
+ while (bp < eb) {
+ kv = (struct kinfo_vmentry *)bp;
+ bp += kv->kve_structsize;
+ cnt++;
+ }
+
+ kiv = calloc(cnt, sizeof(*kiv));
+ if (kiv == NULL) {
+ free(buf);
+ return (0);
+ }
+ bp = buf;
+ eb = buf + len;
+ kp = kiv;
+ /* Pass 2: unpack */
+ while (bp < eb) {
+ kv = (struct kinfo_vmentry *)bp;
+ /* Copy/expand into pre-zeroed buffer */
+ memcpy(kp, kv, kv->kve_structsize);
+ /* Advance to next packed record */
+ bp += kv->kve_structsize;
+ /* Set field size to fixed length, advance */
+ kp->kve_structsize = sizeof(*kp);
+ kp++;
+ }
+ free(buf);
+ *cntp = cnt;
+ return (kiv); /* Caller must free() return value */
+}
diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h
index 186ee2e..3187fb3 100644
--- a/lib/libutil/libutil.h
+++ b/lib/libutil/libutil.h
@@ -64,6 +64,8 @@ struct termios;
struct winsize;
struct utmp;
struct in_addr;
+struct kinfo_file;
+struct kinfo_vmentry;
__BEGIN_DECLS
void clean_environment(const char * const *_white,
@@ -100,6 +102,10 @@ int realhostname_sa(char *host, size_t hsize, struct sockaddr *addr,
int kld_isloaded(const char *name);
int kld_load(const char *name);
+struct kinfo_file *
+ kinfo_getfile(pid_t _pid, int *_cntp);
+struct kinfo_vmentry *
+ kinfo_getvmmap(pid_t _pid, int *_cntp);
#ifdef _STDIO_H_ /* avoid adding new includes */
char *fparseln(FILE *, size_t *, size_t *, const char[3], int);
OpenPOWER on IntegriCloud