kinfo_getfile.c revision 185493
1185493Speter#include <sys/cdefs.h> 2185493Speter__FBSDID("$FreeBSD: user/peter/kinfo/lib/libutil/kinfo_getfile.c 185493 2008-11-30 22:40:14Z peter $"); 3185493Speter 4185493Speter#include <sys/types.h> 5185493Speter#include <sys/user.h> 6185493Speter#include <sys/sysctl.h> 7185493Speter#include <stdlib.h> 8185493Speter#include <string.h> 9185493Speter 10185493Speter#include "libutil.h" 11185493Speter 12185493Speterstruct kinfo_file * 13185493Speterkinfo_getfile(pid_t pid, int *cntp) 14185493Speter{ 15185493Speter int mib[4]; 16185493Speter int error; 17185493Speter int cnt; 18185493Speter size_t len; 19185493Speter char *buf, *bp, *eb; 20185493Speter struct kinfo_file *kif, *kp, *kf; 21185493Speter 22185493Speter len = 0; 23185493Speter mib[0] = CTL_KERN; 24185493Speter mib[1] = KERN_PROC; 25185493Speter mib[2] = KERN_PROC_FILEDESC; 26185493Speter mib[3] = pid; 27185493Speter 28185493Speter error = sysctl(mib, 4, NULL, &len, NULL, 0); 29185493Speter if (error) 30185493Speter return (0); 31185493Speter len = len * 4 / 3; 32185493Speter buf = malloc(len); 33185493Speter if (buf == NULL) 34185493Speter return (0); 35185493Speter error = sysctl(mib, 4, buf, &len, NULL, 0); 36185493Speter if (error) { 37185493Speter free(buf); 38185493Speter return (0); 39185493Speter } 40185493Speter /* Pass 1: count items */ 41185493Speter cnt = 0; 42185493Speter bp = buf; 43185493Speter eb = buf + len; 44185493Speter while (bp < eb) { 45185493Speter kf = (struct kinfo_file *)bp; 46185493Speter bp += kf->kf_structsize; 47185493Speter cnt++; 48185493Speter } 49185493Speter 50185493Speter kif = calloc(cnt, sizeof(*kif)); 51185493Speter if (kif == NULL) { 52185493Speter free(buf); 53185493Speter return (0); 54185493Speter } 55185493Speter bp = buf; 56185493Speter eb = buf + len; 57185493Speter kp = kif; 58185493Speter /* Pass 2: unpack */ 59185493Speter while (bp < eb) { 60185493Speter kf = (struct kinfo_file *)bp; 61185493Speter /* Copy/expand into pre-zeroed buffer */ 62185493Speter memcpy(kp, kf, kf->kf_structsize); 63185493Speter /* Advance to next packed record */ 64185493Speter bp += kf->kf_structsize; 65185493Speter /* Set field size to fixed length, advance */ 66185493Speter kp->kf_structsize = sizeof(*kp); 67185493Speter kp++; 68185493Speter } 69185493Speter free(buf); 70185493Speter *cntp = cnt; 71185493Speter return (kif); /* Caller must free() return value */ 72185493Speter} 73