Skip to content

Commit 2a92366

Browse files
authored
Merge pull request #339 from Uptycs/aix
Add AIX platform-specific process_file() with filename capture
2 parents 98d72f1 + 557ea3a commit 2a92366

File tree

2 files changed

+222
-1
lines changed

2 files changed

+222
-1
lines changed

lib/dialects/aix/dfile.c

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/

lib/dialects/aix/machine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ typedef long long aligned_offset_t __attribute__((aligned(8)));
603603
/* #define USE_LIB_IS_FILE_NAMED 1 isfn.c */
604604
# define USE_LIB_LKUPDEV 1 /* lkud.c */
605605
/* #define USE_LIB_PRINTDEVNAME 1 pdvn.c */
606-
# define USE_LIB_PROCESS_FILE 1 /* prfp.c */
606+
/* #define USE_LIB_PROCESS_FILE 1 prfp.c */
607607
# define USE_LIB_PRINT_TCPTPI 1 /* ptti.c */
608608
/* #define USE_LIB_READDEV 1 rdev.c */
609609
/* #define USE_LIB_READMNT 1 rmnt.c */

0 commit comments

Comments
 (0)