@@ -382,6 +382,227 @@ char *print_dev(struct lfile *lf, /* file whose device to be printed */
382382 return (buf );
383383}
384384
385+ /*
386+ * process_file() - process file structure
387+ */
388+
389+ void process_file (struct lsof_context * ctx , /* context */
390+ KA_T fp ) /* kernel file structure address */
391+ {
392+ struct file f ;
393+ int flag ;
394+ char tbuf [32 ];
395+ struct vnode v ;
396+ struct gnode g ;
397+
398+ #if defined(FILEPTR )
399+ /*
400+ * Save file structure address for process_node().
401+ */
402+ FILEPTR = & f ;
403+ #endif /* defined(FILEPTR) */
404+
405+ /*
406+ * Read file structure.
407+ */
408+ if (kread (ctx , (KA_T )fp , (char * )& f , sizeof (f ))) {
409+ (void )snpf (Namech , Namechl , "can't read file struct from %s" ,
410+ print_kptr (fp , (char * )NULL , 0 ));
411+ enter_nm (ctx , Namech );
412+ return ;
413+ }
414+ Lf -> off = (SZOFFTYPE )f .f_offset ;
415+ Lf -> off_def = 1 ;
416+ if (f .f_count ) {
417+
418+ /*
419+ * Construct access code.
420+ */
421+ if ((flag = (f .f_flag & (FREAD | FWRITE ))) == FREAD )
422+ Lf -> access = LSOF_FILE_ACCESS_READ ;
423+ else if (flag == FWRITE )
424+ Lf -> access = LSOF_FILE_ACCESS_WRITE ;
425+ else if (flag == (FREAD | FWRITE ))
426+ Lf -> access = LSOF_FILE_ACCESS_READ_WRITE ;
427+
428+ #if defined(HASFSTRUCT )
429+ /*
430+ * Save file structure values.
431+ */
432+
433+ #if !defined(HASNOFSCOUNT )
434+ Lf -> fct = (long )f .f_count ;
435+ Lf -> fsv |= FSV_CT ;
436+ #endif /* !defined(HASNOFSCOUNT) */
437+
438+ #if !defined(HASNOFSADDR )
439+ Lf -> fsa = fp ;
440+ Lf -> fsv |= FSV_FA ;
441+ #endif /* !defined(HASNOFSADDR) */
442+
443+ #if !defined(HASNOFSFLAGS )
444+ Lf -> ffg = (long )f .f_flag ;
445+ Lf -> fsv |= FSV_FG ;
446+ #endif /* !defined(HASNOFSFLAGS) */
447+
448+ #if !defined(HASNOFSNADDR )
449+ Lf -> fna = (KA_T )f .f_data ;
450+ Lf -> fsv |= FSV_NI ;
451+ #endif /* !defined(HASNOFSNADDR) */
452+ #endif /* defined(HASFSTRUCT) */
453+
454+ /*
455+ * Process structure by its type.
456+ */
457+ switch (f .f_type ) {
458+
459+ #if defined(DTYPE_PIPE )
460+ case DTYPE_PIPE :
461+ #if defined(HASPIPEFN )
462+ if (!Selinet )
463+ HASPIPEFN (ctx , (KA_T )f .f_data );
464+ #endif /* defined(HASPIPEFN) */
465+ return ;
466+ #endif /* defined(DTYPE_PIPE) */
467+
468+ #if defined(DTYPE_PTS )
469+ case DTYPE_PTS :
470+ #if defined(HASPTSFN )
471+ HASPTSFN (ctx , (KA_T )f .f_data );
472+ #endif /* defined(HASPTSFN) */
473+ return ;
474+ #endif /* defined(DTYPE_PTS) */
475+
476+ #if defined(DTYPE_FIFO )
477+ case DTYPE_FIFO :
478+ #endif /* defined(DTYPE_FIFO) */
479+
480+ #if defined(DTYPE_GNODE )
481+ case DTYPE_GNODE :
482+ #endif /* defined(DTYPE_GNODE) */
483+
484+ #if defined(DTYPE_INODE )
485+ case DTYPE_INODE :
486+ #endif /* defined(DTYPE_INODE) */
487+
488+ #if defined(DTYPE_PORT )
489+ case DTYPE_PORT :
490+ #endif /* defined(DTYPE_PORT) */
491+
492+ #if defined(DTYPE_VNODE )
493+ case DTYPE_VNODE :
494+ /*
495+ * AIX-specific: Capture filename from file structure.
496+ *
497+ * AIX limitation: The kernel doesn't provide an accessible name cache,
498+ * so we can only obtain the leaf filename from f_fnamep. We'll combine
499+ * this with the filesystem mount point (if available) after calling
500+ * process_node() to provide partial path context.
501+ *
502+ * Full path reconstruction is not possible on AIX without expensive
503+ * userspace filesystem scanning.
504+ */
505+ {
506+ char leafname [MAXPATHLEN ];
507+ int have_leaf = 0 ;
508+
509+ /* Try to read the leaf filename from the file structure */
510+ if (f .f_vnode && f .f_fnamep
511+ && !kread (ctx , (KA_T )f .f_vnode , (char * )& v , sizeof (v ))
512+ && v .v_gnode && !kread (ctx , (KA_T )v .v_gnode , (char * )& g , sizeof (g ))
513+ && (g .gn_type == VREG || g .gn_type == VDIR )) {
514+ if (!kread (ctx , (KA_T )f .f_fnamep , leafname , sizeof (leafname )- 1 )) {
515+ leafname [sizeof (leafname )- 1 ] = '\0' ;
516+ /* Only use if we got a non-empty string */
517+ if (leafname [0 ]) {
518+ have_leaf = 1 ;
519+ }
520+ }
521+ }
522+
523+ /* Process the node to get vfs/mount info and other metadata */
524+ #if defined(HASF_VNODE )
525+ process_node (ctx , (KA_T )f .f_vnode );
526+ #else /* !defined(HASF_VNODE) */
527+ process_node (ctx , (KA_T )f .f_data );
528+ #endif /* defined(HASF_VNODE) */
529+
530+ /*
531+ * If we have a leaf name, combine it with mount point info.
532+ * This provides better context than just the leaf name alone.
533+ * Use ellipsis (...) to indicate missing path components between
534+ * the mount point and the leaf filename.
535+ */
536+ if (have_leaf ) {
537+ if (Lf -> fsdir && Lf -> fsdir [0 ] && strcmp (Lf -> fsdir , "/" ) != 0 ) {
538+ /* We have a non-root mount point, show mount/.../leaf */
539+ (void )snpf (Namech , Namechl , "%s/.../%s" , Lf -> fsdir , leafname );
540+ } else if (Lf -> fsdir && strcmp (Lf -> fsdir , "/" ) == 0 ) {
541+ /* Root filesystem, show /.../leaf */
542+ (void )snpf (Namech , Namechl , "/.../%s" , leafname );
543+ } else {
544+ /* No mount point info, just show .../leaf */
545+ (void )snpf (Namech , Namechl , ".../%s" , leafname );
546+ }
547+ /* Enter the name we constructed */
548+ enter_nm (ctx , Namech );
549+ }
550+ }
551+ #endif /* defined(DTYPE_VNODE) */
552+
553+ return ;
554+ case DTYPE_SOCKET :
555+ process_socket (ctx , (KA_T )f .f_data );
556+ return ;
557+
558+ #if defined(HASKQUEUE )
559+ case DTYPE_KQUEUE :
560+ process_kqueue (ctx , (KA_T )f .f_data );
561+ return ;
562+ #endif /* defined(HASKQUEUE) */
563+
564+ #if defined(HASPSXSEM )
565+ case DTYPE_PSXSEM :
566+ process_psxsem (ctx , (KA_T )f .f_data );
567+ return ;
568+ #endif /* defined(HASPSXSEM) */
569+
570+ #if defined(HASPSXSHM )
571+ case DTYPE_PSXSHM :
572+ process_psxshm (ctx , (KA_T )f .f_data );
573+ return ;
574+ #endif /* defined(HASPSXSHM) */
575+
576+ #if defined(HASPRIVFILETYPE )
577+ case PRIVFILETYPE :
578+ HASPRIVFILETYPE (ctx , (KA_T )f .f_data );
579+ return ;
580+ #endif /* defined(HASPRIVFILETYPE) */
581+
582+ default :
583+
584+ #if defined(X_BADFILEOPS )
585+ if (X_bfopsa && f .f_ops && (X_bfopsa == (KA_T )f .f_ops )) {
586+ (void )snpf (Namech , Namechl ,
587+ "no more information; ty=%d file may be closing" ,
588+ (int )f .f_type );
589+ enter_nm (ctx , Namech );
590+ return ;
591+ }
592+ #endif /* defined(X_BADFILEOPS) */
593+
594+ if (f .f_type || f .f_ops ) {
595+ (void )snpf (Namech , Namechl , "%s file struct, ty=%d, op=%s" ,
596+ print_kptr (fp , tbuf , sizeof (tbuf )), (int )f .f_type ,
597+ print_kptr ((KA_T )f .f_ops , (char * )NULL , 0 ));
598+ enter_nm (ctx , Namech );
599+ return ;
600+ }
601+ }
602+ }
603+ enter_nm (ctx , "no more information" );
604+ }
605+
385606/*
386607 * readvfs() - read vfs structure
387608 */
0 commit comments