kinfo_getfile.c revision 185493
1181053Srwatson#include <sys/cdefs.h>
2184825Srwatson__FBSDID("$FreeBSD: user/peter/kinfo/lib/libutil/kinfo_getfile.c 185493 2008-11-30 22:40:14Z peter $");
3176627Srwatson
4156888Srwatson#include <sys/types.h>
5156888Srwatson#include <sys/user.h>
6156888Srwatson#include <sys/sysctl.h>
7156888Srwatson#include <stdlib.h>
8156888Srwatson#include <string.h>
9156888Srwatson
10156888Srwatson#include "libutil.h"
11156888Srwatson
12156888Srwatsonstruct kinfo_file *
13156888Srwatsonkinfo_getfile(pid_t pid, int *cntp)
14180701Srwatson{
15156888Srwatson	int mib[4];
16156888Srwatson	int error;
17156888Srwatson	int cnt;
18156888Srwatson	size_t len;
19156888Srwatson	char *buf, *bp, *eb;
20156888Srwatson	struct kinfo_file *kif, *kp, *kf;
21156888Srwatson
22156888Srwatson	len = 0;
23156888Srwatson	mib[0] = CTL_KERN;
24156888Srwatson	mib[1] = KERN_PROC;
25156888Srwatson	mib[2] = KERN_PROC_FILEDESC;
26156888Srwatson	mib[3] = pid;
27156888Srwatson
28156888Srwatson	error = sysctl(mib, 4, NULL, &len, NULL, 0);
29156888Srwatson	if (error)
30156888Srwatson		return (0);
31178186Srwatson	len = len * 4 / 3;
32178186Srwatson	buf = malloc(len);
33178186Srwatson	if (buf == NULL)
34156888Srwatson		return (0);
35156888Srwatson	error = sysctl(mib, 4, buf, &len, NULL, 0);
36156888Srwatson	if (error) {
37156888Srwatson		free(buf);
38156888Srwatson		return (0);
39156888Srwatson	}
40156888Srwatson	/* Pass 1: count items */
41156888Srwatson	cnt = 0;
42156888Srwatson	bp = buf;
43156888Srwatson	eb = buf + len;
44156888Srwatson	while (bp < eb) {
45156888Srwatson		kf = (struct kinfo_file *)bp;
46156888Srwatson		bp += kf->kf_structsize;
47156888Srwatson		cnt++;
48156888Srwatson	}
49156888Srwatson
50156888Srwatson	kif = calloc(cnt, sizeof(*kif));
51156888Srwatson	if (kif == NULL) {
52176627Srwatson		free(buf);
53156888Srwatson		return (0);
54156888Srwatson	}
55156888Srwatson	bp = buf;
56156888Srwatson	eb = buf + len;
57156888Srwatson	kp = kif;
58156888Srwatson	/* Pass 2: unpack */
59156888Srwatson	while (bp < eb) {
60156888Srwatson		kf = (struct kinfo_file *)bp;
61156888Srwatson		/* Copy/expand into pre-zeroed buffer */
62156888Srwatson		memcpy(kp, kf, kf->kf_structsize);
63156888Srwatson		/* Advance to next packed record */
64156888Srwatson		bp += kf->kf_structsize;
65156888Srwatson		/* Set field size to fixed length, advance */
66156888Srwatson		kp->kf_structsize = sizeof(*kp);
67156888Srwatson		kp++;
68156888Srwatson	}
69156888Srwatson	free(buf);
70156888Srwatson	*cntp = cnt;
71156888Srwatson	return (kif);	/* Caller must free() return value */
72156888Srwatson}
73156888Srwatson