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 | |
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')
-rw-r--r-- | lib/libutil/Makefile | 3 | ||||
-rw-r--r-- | lib/libutil/kinfo_getfile.c | 72 | ||||
-rw-r--r-- | lib/libutil/kinfo_getvmmap.c | 72 | ||||
-rw-r--r-- | lib/libutil/libutil.h | 6 |
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); |