kinfo_getfile.c revision 185553
19313Ssos#include <sys/cdefs.h> 29313Ssos__FBSDID("$FreeBSD: head/lib/libutil/kinfo_getfile.c 185553 2008-12-02 10:10:50Z peter $"); 39313Ssos 49313Ssos#include <sys/types.h> 59313Ssos#include <sys/user.h> 69313Ssos#include <sys/sysctl.h> 79313Ssos#include <stdlib.h> 89313Ssos#include <string.h> 9111798Sdes 109313Ssos#include "libutil.h" 119313Ssos 129313Ssosstruct kinfo_file * 139313Ssoskinfo_getfile(pid_t pid, int *cntp) 149313Ssos{ 1597748Sschweikh int mib[4]; 169313Ssos int error; 179313Ssos int cnt; 189313Ssos size_t len; 199313Ssos char *buf, *bp, *eb; 209313Ssos struct kinfo_file *kif, *kp, *kf; 219313Ssos 229313Ssos len = 0; 239313Ssos mib[0] = CTL_KERN; 249313Ssos mib[1] = KERN_PROC; 259313Ssos mib[2] = KERN_PROC_FILEDESC; 269313Ssos mib[3] = pid; 279313Ssos 289313Ssos error = sysctl(mib, 4, NULL, &len, NULL, 0); 29116173Sobrien if (error) 30116173Sobrien return (0); 31116173Sobrien len = len * 4 / 3; 32156874Sru buf = malloc(len); 33101189Srwatson if (buf == NULL) 3431784Seivind return (0); 359313Ssos error = sysctl(mib, 4, buf, &len, NULL, 0); 369313Ssos if (error) { 3776166Smarkm free(buf); 3876166Smarkm return (0); 399313Ssos } 409313Ssos /* Pass 1: count items */ 419313Ssos cnt = 0; 4231561Sbde bp = buf; 439313Ssos eb = buf + len; 4472538Sjlemon while (bp < eb) { 4576166Smarkm kf = (struct kinfo_file *)(uintptr_t)bp; 46168014Sjulian bp += kf->kf_structsize; 4776166Smarkm cnt++; 48162201Snetchild } 49166085Skib 50102814Siedowse kif = calloc(cnt, sizeof(*kif)); 5176166Smarkm if (kif == NULL) { 5214331Speter free(buf); 53162585Snetchild return (0); 5476166Smarkm } 5512458Sbde bp = buf; 56163606Srwatson eb = buf + len; 57163606Srwatson kp = kif; 5872538Sjlemon /* Pass 2: unpack */ 5972538Sjlemon while (bp < eb) { 6072538Sjlemon kf = (struct kinfo_file *)(uintptr_t)bp; 6172538Sjlemon /* Copy/expand into pre-zeroed buffer */ 62140214Sobrien memcpy(kp, kf, kf->kf_structsize); 63140214Sobrien /* Advance to next packed record */ 64140214Sobrien bp += kf->kf_structsize; 65140214Sobrien /* Set field size to fixed length, advance */ 6664905Smarcel kp->kf_structsize = sizeof(*kp); 6768583Smarcel kp++; 68133816Stjr } 6964905Smarcel free(buf); 709313Ssos *cntp = cnt; 719313Ssos return (kif); /* Caller must free() return value */ 7283366Sjulian} 739313Ssos