1/* 2 * dfile.c - Darwin file processing functions for /dev/kmem-based lsof 3 */ 4 5 6/* 7 * Copyright 2005 Purdue Research Foundation, West Lafayette, Indiana 8 * 47907. All rights reserved. 9 * 10 * Written by Victor A. Abell 11 * 12 * This software is not subject to any license of the American Telephone 13 * and Telegraph Company or the Regents of the University of California. 14 * 15 * Permission is granted to anyone to use this software for any purpose on 16 * any computer system, and to alter it and redistribute it freely, subject 17 * to the following restrictions: 18 * 19 * 1. Neither the authors nor Purdue University are responsible for any 20 * consequences of the use of this software. 21 * 22 * 2. The origin of this software must not be misrepresented, either by 23 * explicit claim or by omission. Credit to the authors and Purdue 24 * University must appear in documentation and sources. 25 * 26 * 3. Altered versions must be plainly marked as such, and must not be 27 * misrepresented as being the original software. 28 * 29 * 4. This notice may not be removed or altered. 30 */ 31 32#ifndef lint 33static char copyright[] = 34"@(#) Copyright 2005 Purdue Research Foundation.\nAll rights reserved.\n"; 35static char *rcsid = "$Id$"; 36#endif 37 38 39#include "lsof.h" 40 41 42/* 43 * Local definitions 44 */ 45 46#if DARWINV>=800 47#define file fileglob 48#define f_flag fg_flag 49#define f_type fg_type 50#define f_count fg_count 51#define f_ops fg_ops 52#define f_offset fg_offset 53#define f_data fg_data 54#endif /* DARWINV>=800 */ 55 56#if defined(HASPSXSEM) 57#define PSEMNAMLEN 31 /* from kern/posix_sem.c */ 58#endif /* defined(HASPSXSEM) */ 59 60#if defined(HASPSXSHM) 61#define PSHMNAMLEN 31 /* from kern/posix_shm.c */ 62#endif /* defined(HASPSXSHM) */ 63 64 65/* 66 * Local structure definitions 67 */ 68 69#if defined(HASPSXSEM) 70struct pseminfo { /* from kern/posix_sem.c */ 71 unsigned int psem_flags; 72 unsigned int psem_usecount; 73 mode_t psem_mode; 74 uid_t psem_uid; 75 gid_t psem_gid; 76 char psem_name[PSEMNAMLEN + 1]; 77 void *psem_semobject; 78 struct proc *sem_proc; 79}; 80 81struct psemnode { 82 struct pseminfo *pinfo; 83}; 84#endif /* defined(HASPSXSEM) */ 85 86#if defined(HASPSXSHM) /* from kern/posix_shm.c */ 87struct pshminfo { 88 unsigned int pshm_flags; 89 unsigned int pshm_usecount; 90 off_t pshm_length; 91 mode_t pshm_mode; 92 uid_t pshm_uid; 93 gid_t pshm_gid; 94 char pshm_name[PSHMNAMLEN + 1]; 95 void *pshm_memobject; 96}; 97 98struct pshmnode { 99 off_t mapp_addr; 100 101# if DARWINV<800 102 size_t map_size; 103# else /* DARWINV>=800 */ 104 user_size_t map_size; 105# endif /* DARWINV>=800 */ 106 107 struct pshminfo *pinfo; 108}; 109#endif /* defined(HASPSXSHM) */ 110 111 112#if DARWINV>=800 113/* 114 * print_v_path() - print vnode's path 115 */ 116 117int 118print_v_path(lf) 119 struct lfile *lf; 120{ 121 if (lf->V_path) { 122 safestrprt(lf->V_path, stdout, 0); 123 return(1); 124 } 125 return(0); 126} 127#endif /* DARWINV>=800 */ 128 129 130#if defined(HASKQUEUE) 131/* 132 * process_kqueue() -- process kqueue file 133 */ 134 135void 136process_kqueue(ka) 137 KA_T ka; /* kqueue file structure address */ 138{ 139 struct kqueue kq; /* kqueue structure */ 140 141 (void) snpf(Lf->type, sizeof(Lf->type), "KQUEUE"); 142 enter_dev_ch(print_kptr(ka, (char *)NULL, 0)); 143 if (!ka || kread(ka, (char *)&kq, sizeof(kq))) 144 return; 145 (void) snpf(Namech, Namechl, "count=%d, state=%#x", kq.kq_count, 146 kq.kq_state); 147 enter_nm(Namech); 148} 149#endif /* defined(HASKQUEUE) */ 150 151 152#if DARWINV>=800 153/* 154 * process_pipe() - process a file structure whose type is DTYPE_PIPE 155 */ 156 157void 158process_pipe(pa) 159 KA_T pa; /* pipe structure address */ 160{ 161 (void) snpf(Lf->type, sizeof(Lf->type), "PIPE"); 162 enter_dev_ch(print_kptr(pa, (char *)NULL, 0)); 163 Namech[0] = '\0'; 164} 165#endif /* DARWINV>=800 */ 166 167 168#if defined(HASPSXSEM) 169/* 170 * process_psxsem() -- process POSIX semaphore file 171 */ 172 173void 174process_psxsem(pa) 175 KA_T pa; /* psxsem file structure address */ 176{ 177 struct pseminfo pi; 178 struct psemnode pn; 179 180 (void) snpf(Lf->type, sizeof(Lf->type), "PSXSEM"); 181 enter_dev_ch(print_kptr(pa, (char *)NULL, 0)); 182 if (!Fsize) 183 Lf->off_def = 1; 184 if (pa && !kread(pa, (char *)&pn, sizeof(pn))) { 185 if (pn.pinfo && !kread((KA_T)pn.pinfo, (char *)&pi, sizeof(pi))) { 186 if (pi.psem_name[0]) { 187 pi.psem_name[PSEMNAMLEN] = '\0'; 188 (void) snpf(Namech, Namechl, "%s", pi.psem_name); 189 enter_nm(Namech); 190 } 191 } 192 } 193} 194#endif /* defined(HASPSXSEM) */ 195 196 197#if defined(HASPSXSHM) 198/* 199 * process_psxshm() -- process POSIX shared memory file 200 */ 201 202void 203process_psxshm(pa) 204 KA_T pa; /* psxshm file structure address */ 205{ 206 struct pshminfo pi; 207 struct pshmnode pn; 208 int pns = 0; 209 210 (void) snpf(Lf->type, sizeof(Lf->type), "PSXSHM"); 211 enter_dev_ch(print_kptr(pa, (char *)NULL, 0)); 212 if (pa && !kread(pa, (char *)&pn, sizeof(pn))) { 213 pns = 1; 214 if (pn.pinfo && !kread((KA_T)pn.pinfo, (char *)&pi, sizeof(pi))) { 215 if (pi.pshm_name[0]) { 216 pi.pshm_name[PSEMNAMLEN] = '\0'; 217 (void) snpf(Namech, Namechl, "%s", pi.pshm_name); 218 enter_nm(Namech); 219 } else if (pi.pshm_memobject) { 220 (void) snpf(Namech, Namechl, "obj=%s", 221 print_kptr((KA_T)pi.pshm_memobject, (char *)NULL, 0)); 222 enter_nm(Namech); 223 } 224 } 225 } 226 if (Foffset) 227 Lf->off_def = 1; 228 else if (pns) { 229 Lf->sz = (SZOFFTYPE)pn.map_size; 230 Lf->sz_def = 1; 231 } 232} 233#endif /* defined(HASPSXSHM) */ 234 235 236/* 237 * process_file() - process file 238 */ 239 240/* 241 * The caller may define: 242 * 243 * FILEPTR as the name of the location to store a pointer 244 * to the current file struct -- e.g., 245 * 246 * struct file *foobar; 247 * #define FILEPTR foobar 248 */ 249 250void 251process_file(fp) 252 KA_T fp; /* kernel file structure address */ 253{ 254 255#if DARWINV<800 256 struct file f; 257#else /* DARWINV>=800 */ 258 struct fileglob f; 259 struct fileproc fileproc; 260#endif /* DARWINV>=800 */ 261 262 int flag; 263 264#if defined(FILEPTR) 265/* 266 * Save file structure address for process_node(). 267 */ 268 FILEPTR = &f; 269#endif /* defined(FILEPTR) */ 270 271/* 272 * Read file structure. 273 */ 274 275#if DARWINV<800 276 if (kread((KA_T)fp, (char *)&f, sizeof(f))) { 277 (void) snpf(Namech, Namechl, "can't read file struct from %s", 278 print_kptr(fp, (char *)NULL, 0)); 279 enter_nm(Namech); 280 return; 281 } 282#else /* DARWINV>=800 */ 283 if (kread((KA_T)fp, (char *)&fileproc, sizeof(fileproc))) { 284 (void) snpf(Namech, Namechl, "can't read fileproc struct from %s", 285 print_kptr(fp, (char *)NULL, 0)); 286 enter_nm(Namech); 287 return; 288 } 289 if (kread((KA_T)fileproc.f_fglob, (char *)&f, sizeof(f))) { 290 (void) snpf(Namech, Namechl, "can't read fileglob struct from %s", 291 print_kptr((KA_T)fileproc.f_fglob, (char *)NULL, 0)); 292 enter_nm(Namech); 293 return; 294 } 295#endif /* DARWINV>=800 */ 296 297 Lf->off = (SZOFFTYPE)f.f_offset; 298 if (f.f_count) { 299 300 /* 301 * Construct access code. 302 */ 303 if ((flag = (f.f_flag & (FREAD | FWRITE))) == FREAD) 304 Lf->access = 'r'; 305 else if (flag == FWRITE) 306 Lf->access = 'w'; 307 else if (flag == (FREAD | FWRITE)) 308 Lf->access = 'u'; 309 310#if defined(HASFSTRUCT) 311 /* 312 * Save file structure values. 313 */ 314 if (Fsv & FSV_CT) { 315 Lf->fct = (long)f.f_count; 316 Lf->fsv |= FSV_CT; 317 } 318 if (Fsv & FSV_FA) { 319 Lf->fsa = fp; 320 Lf->fsv |= FSV_FA; 321 } 322 if (Fsv & FSV_FG) { 323 Lf->ffg = (long)f.f_flag; 324 Lf->fsv |= FSV_FG; 325 } 326 if (Fsv & FSV_NI) { 327 Lf->fna = (KA_T)f.f_data; 328 Lf->fsv |= FSV_NI; 329 } 330#endif /* defined(HASFSTRUCT) */ 331 332 /* 333 * Process structure by its type. 334 */ 335 switch (f.f_type) { 336 337 338#if defined(DTYPE_PIPE) 339 case DTYPE_PIPE: 340# if defined(HASPIPEFN) 341 if (!Selinet) 342 HASPIPEFN((KA_T)f.f_data); 343# endif /* defined(HASPIPEFN) */ 344 return; 345#endif /* defined(DTYPE_PIPE) */ 346 347 case DTYPE_VNODE: 348 if (!Selinet) 349 process_node((KA_T)f.f_data); 350 return; 351 case DTYPE_SOCKET: 352 process_socket((KA_T)f.f_data); 353 return; 354 355#if defined(HASKQUEUE) 356 case DTYPE_KQUEUE: 357 process_kqueue((KA_T)f.f_data); 358 return; 359#endif /* defined(HASKQUEUE) */ 360 361#if defined(HASPSXSEM) 362 case DTYPE_PSXSEM: 363 process_psxsem((KA_T)f.f_data); 364 return; 365#endif /* defined(HASPSXSEM) */ 366 367#if defined(HASPSXSHM) 368 case DTYPE_PSXSHM: 369 process_psxshm((KA_T)f.f_data); 370 return; 371#endif /* defined(HASPSXSHM) */ 372 373#if defined(HASPRIVFILETYPE) 374 case PRIVFILETYPE: 375 HASPRIVFILETYPE((KA_T)f.f_data); 376 return; 377#endif /* defined(HASPRIVFILETYPE) */ 378 379 default: 380 if (f.f_type || f.f_ops) { 381 (void) snpf(Namech, Namechl, 382 "%s file struct, ty=%#x, op=%p", 383 print_kptr(fp, (char *)NULL, 0), f.f_type, f.f_ops); 384 enter_nm(Namech); 385 return; 386 } 387 } 388 } 389 enter_nm("no more information"); 390} 391