kinfo_getfile.c revision 185548
1#include <sys/cdefs.h> 2__FBSDID("$FreeBSD: head/lib/libutil/kinfo_getfile.c 185548 2008-12-02 06:50:26Z peter $"); 3 4#include <sys/types.h> 5#include <sys/user.h> 6#include <sys/sysctl.h> 7#include <stdlib.h> 8#include <string.h> 9 10#include "libutil.h" 11 12struct kinfo_file * 13kinfo_getfile(pid_t pid, int *cntp) 14{ 15 int mib[4]; 16 int error; 17 int cnt; 18 size_t len; 19 char *buf, *bp, *eb; 20 struct kinfo_file *kif, *kp, *kf; 21 22 len = 0; 23 mib[0] = CTL_KERN; 24 mib[1] = KERN_PROC; 25 mib[2] = KERN_PROC_FILEDESC; 26 mib[3] = pid; 27 28 error = sysctl(mib, 4, NULL, &len, NULL, 0); 29 if (error) 30 return (0); 31 len = len * 4 / 3; 32 buf = malloc(len); 33 if (buf == NULL) 34 return (0); 35 error = sysctl(mib, 4, buf, &len, NULL, 0); 36 if (error) { 37 free(buf); 38 return (0); 39 } 40 /* Pass 1: count items */ 41 cnt = 0; 42 bp = buf; 43 eb = buf + len; 44 while (bp < eb) { 45 kf = (struct kinfo_file *)bp; 46 bp += kf->kf_structsize; 47 cnt++; 48 } 49 50 kif = calloc(cnt, sizeof(*kif)); 51 if (kif == NULL) { 52 free(buf); 53 return (0); 54 } 55 bp = buf; 56 eb = buf + len; 57 kp = kif; 58 /* Pass 2: unpack */ 59 while (bp < eb) { 60 kf = (struct kinfo_file *)bp; 61 /* Copy/expand into pre-zeroed buffer */ 62 memcpy(kp, kf, kf->kf_structsize); 63 /* Advance to next packed record */ 64 bp += kf->kf_structsize; 65 /* Set field size to fixed length, advance */ 66 kp->kf_structsize = sizeof(*kp); 67 kp++; 68 } 69 free(buf); 70 *cntp = cnt; 71 return (kif); /* Caller must free() return value */ 72} 73