diff options
author | peter <peter@FreeBSD.org> | 2008-11-30 22:40:14 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2008-11-30 22:40:14 +0000 |
commit | 16271b5bfa14998575e875d8911bbe565051831c (patch) | |
tree | 85c55795a8e2bf89d2218f061266b93e059c8813 /lib/libutil/kinfo_getvmmap.c | |
parent | 2b1f03929a1b2aede23598bc1b54f8061c22fd69 (diff) | |
download | FreeBSD-src-16271b5bfa14998575e875d8911bbe565051831c.zip FreeBSD-src-16271b5bfa14998575e875d8911bbe565051831c.tar.gz |
Add experimental front ends to the kinfo_vmentry and kinfo_filedesc
sysctls.
Diffstat (limited to 'lib/libutil/kinfo_getvmmap.c')
-rw-r--r-- | lib/libutil/kinfo_getvmmap.c | 72 |
1 files changed, 72 insertions, 0 deletions
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 */ +} |