143151ee6SPeter Wemm #include <sys/cdefs.h> 243151ee6SPeter Wemm __FBSDID("$FreeBSD$"); 343151ee6SPeter Wemm 4aa334e41SRobert Watson #include <sys/param.h> 543151ee6SPeter Wemm #include <sys/user.h> 643151ee6SPeter Wemm #include <sys/sysctl.h> 743151ee6SPeter Wemm #include <stdlib.h> 843151ee6SPeter Wemm #include <string.h> 943151ee6SPeter Wemm 1043151ee6SPeter Wemm #include "libutil.h" 1143151ee6SPeter Wemm 1243151ee6SPeter Wemm struct kinfo_file * 1343151ee6SPeter Wemm kinfo_getfile(pid_t pid, int *cntp) 1443151ee6SPeter Wemm { 1543151ee6SPeter Wemm int mib[4]; 1643151ee6SPeter Wemm int error; 1743151ee6SPeter Wemm int cnt; 1843151ee6SPeter Wemm size_t len; 1943151ee6SPeter Wemm char *buf, *bp, *eb; 2043151ee6SPeter Wemm struct kinfo_file *kif, *kp, *kf; 2143151ee6SPeter Wemm 226c3b8117SJoe Marcus Clarke *cntp = 0; 2343151ee6SPeter Wemm len = 0; 2443151ee6SPeter Wemm mib[0] = CTL_KERN; 2543151ee6SPeter Wemm mib[1] = KERN_PROC; 2643151ee6SPeter Wemm mib[2] = KERN_PROC_FILEDESC; 2743151ee6SPeter Wemm mib[3] = pid; 2843151ee6SPeter Wemm 2943151ee6SPeter Wemm error = sysctl(mib, 4, NULL, &len, NULL, 0); 3043151ee6SPeter Wemm if (error) 316c3b8117SJoe Marcus Clarke return (NULL); 3243151ee6SPeter Wemm len = len * 4 / 3; 3343151ee6SPeter Wemm buf = malloc(len); 3443151ee6SPeter Wemm if (buf == NULL) 356c3b8117SJoe Marcus Clarke return (NULL); 3643151ee6SPeter Wemm error = sysctl(mib, 4, buf, &len, NULL, 0); 3743151ee6SPeter Wemm if (error) { 3843151ee6SPeter Wemm free(buf); 396c3b8117SJoe Marcus Clarke return (NULL); 4043151ee6SPeter Wemm } 4143151ee6SPeter Wemm /* Pass 1: count items */ 4243151ee6SPeter Wemm cnt = 0; 4343151ee6SPeter Wemm bp = buf; 4443151ee6SPeter Wemm eb = buf + len; 4543151ee6SPeter Wemm while (bp < eb) { 46de94a63bSPeter Wemm kf = (struct kinfo_file *)(uintptr_t)bp; 4743151ee6SPeter Wemm bp += kf->kf_structsize; 4843151ee6SPeter Wemm cnt++; 4943151ee6SPeter Wemm } 5043151ee6SPeter Wemm 5143151ee6SPeter Wemm kif = calloc(cnt, sizeof(*kif)); 5243151ee6SPeter Wemm if (kif == NULL) { 5343151ee6SPeter Wemm free(buf); 546c3b8117SJoe Marcus Clarke return (NULL); 5543151ee6SPeter Wemm } 5643151ee6SPeter Wemm bp = buf; 5743151ee6SPeter Wemm eb = buf + len; 5843151ee6SPeter Wemm kp = kif; 5943151ee6SPeter Wemm /* Pass 2: unpack */ 6043151ee6SPeter Wemm while (bp < eb) { 61de94a63bSPeter Wemm kf = (struct kinfo_file *)(uintptr_t)bp; 6243151ee6SPeter Wemm /* Copy/expand into pre-zeroed buffer */ 6343151ee6SPeter Wemm memcpy(kp, kf, kf->kf_structsize); 6443151ee6SPeter Wemm /* Advance to next packed record */ 6543151ee6SPeter Wemm bp += kf->kf_structsize; 6643151ee6SPeter Wemm /* Set field size to fixed length, advance */ 6743151ee6SPeter Wemm kp->kf_structsize = sizeof(*kp); 6843151ee6SPeter Wemm kp++; 6943151ee6SPeter Wemm } 7043151ee6SPeter Wemm free(buf); 7143151ee6SPeter Wemm *cntp = cnt; 7243151ee6SPeter Wemm return (kif); /* Caller must free() return value */ 7343151ee6SPeter Wemm } 74