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