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; 47*14bdbaf2SConrad Meyer if (kf->kf_structsize == 0) 48*14bdbaf2SConrad Meyer break; 4943151ee6SPeter Wemm bp += kf->kf_structsize; 5043151ee6SPeter Wemm cnt++; 5143151ee6SPeter Wemm } 5243151ee6SPeter Wemm 5343151ee6SPeter Wemm kif = calloc(cnt, sizeof(*kif)); 5443151ee6SPeter Wemm if (kif == NULL) { 5543151ee6SPeter Wemm free(buf); 566c3b8117SJoe Marcus Clarke return (NULL); 5743151ee6SPeter Wemm } 5843151ee6SPeter Wemm bp = buf; 5943151ee6SPeter Wemm eb = buf + len; 6043151ee6SPeter Wemm kp = kif; 6143151ee6SPeter Wemm /* Pass 2: unpack */ 6243151ee6SPeter Wemm while (bp < eb) { 63de94a63bSPeter Wemm kf = (struct kinfo_file *)(uintptr_t)bp; 64*14bdbaf2SConrad Meyer if (kf->kf_structsize == 0) 65*14bdbaf2SConrad Meyer break; 6643151ee6SPeter Wemm /* Copy/expand into pre-zeroed buffer */ 6743151ee6SPeter Wemm memcpy(kp, kf, kf->kf_structsize); 6843151ee6SPeter Wemm /* Advance to next packed record */ 6943151ee6SPeter Wemm bp += kf->kf_structsize; 7043151ee6SPeter Wemm /* Set field size to fixed length, advance */ 7143151ee6SPeter Wemm kp->kf_structsize = sizeof(*kp); 7243151ee6SPeter Wemm kp++; 7343151ee6SPeter Wemm } 7443151ee6SPeter Wemm free(buf); 7543151ee6SPeter Wemm *cntp = cnt; 7643151ee6SPeter Wemm return (kif); /* Caller must free() return value */ 7743151ee6SPeter Wemm } 78