Index: usr.bin/fstat/fstat.1
===================================================================
RCS file: /cvsroot/src/usr.bin/fstat/fstat.1,v
retrieving revision 1.30
diff -u -r1.30 fstat.1
--- usr.bin/fstat/fstat.1       8 Oct 2011 22:16:03 -0000       1.30
+++ usr.bin/fstat/fstat.1       3 Oct 2012 07:55:35 -0000
@@ -37,7 +37,7 @@
.Nd display status of open files
.Sh SYNOPSIS
.Nm
-.Op Fl fnv
+.Op Fl fnAv
.Op Fl M Ar core
.Op Fl N Ar system
.Op Fl p Ar pid
@@ -87,6 +87,11 @@
Report all files open by the specified process.
.It Fl u
Report all files open by the specified user.
+.It Fl A
+Add an output column with the address of the kernel object (vnode or file),
+that can be matched with
+.Xr pstat 8
+output.
.It Fl v
Verbose mode.
Print error messages upon failures to locate particular
Index: usr.bin/fstat/fstat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/fstat/fstat.c,v
retrieving revision 1.97
diff -u -r1.97 fstat.c
--- usr.bin/fstat/fstat.c       26 Sep 2012 23:01:04 -0000      1.97
+++ usr.bin/fstat/fstat.c       3 Oct 2012 07:55:35 -0000
@@ -132,6 +132,7 @@
       uflg;   /* show files open by a particular (effective) user */
static int     checkfile; /* true if restricting to particular files or filesystems */
static int     nflg;   /* (numerical) display f.s. and rdev as dev_t */
+static int     Aflg;   /* prefix with address of file structure */
int    vflg;   /* display errors in locating kernel data objects etc... */

static fdfile_t **ofiles; /* buffer of pointers to file structures */
@@ -170,11 +171,11 @@
#endif
static const char *at_addrstr(char *, size_t, const struct sockaddr_at *);
static void    socktrans(struct socket *, int);
-static void    misctrans(struct file *);
+static void    misctrans(struct file *, int);
static int     ufs_filestat(struct vnode *, struct filestat *);
static void    usage(void) __dead;
static const char   *vfilestat(struct vnode *, struct filestat *);
-static void    vtrans(struct vnode *, int, int);
+static void    vtrans(struct vnode *, int, int, long);
static void    ftrans(fdfile_t *, int);
static void    ptrans(struct file *, struct pipe *, int);

@@ -193,7 +194,7 @@
       arg = 0;
       what = KERN_PROC_ALL;
       nlistf = memf = NULL;
-       while ((ch = getopt(argc, argv, "fnp:u:vN:M:")) != -1)
+       while ((ch = getopt(argc, argv, "fnAp:u:vN:M:")) != -1)
               switch((char)ch) {
               case 'f':
                       fsflg = 1;
@@ -207,6 +208,9 @@
               case 'n':
                       nflg = 1;
                       break;
+               case 'A':
+                       Aflg = 1;
+                       break;
               case 'p':
                       if (pflg++)
                               usage();
@@ -273,6 +277,8 @@
       if ((p = kvm_getproc2(kd, what, arg, sizeof *p, &cnt)) == NULL) {
               errx(1, "%s", kvm_geterr(kd));
       }
+       if (Aflg)
+               (void)printf("%-*s ", 2*(int)(sizeof(void*)), "ADDR");
       if (nflg)
               (void)printf("%s",
"USER     CMD          PID   FD  DEV     INUM  MODE  SZ|DV R/W");
@@ -357,11 +363,11 @@
        * root directory vnode, if one
        */
       if (cwdi.cwdi_rdir)
-               vtrans(cwdi.cwdi_rdir, RDIR, FREAD);
+               vtrans(cwdi.cwdi_rdir, RDIR, FREAD, (long)cwdi.cwdi_rdir);
       /*
        * current working directory vnode
        */
-       vtrans(cwdi.cwdi_cdir, CDIR, FREAD);
+       vtrans(cwdi.cwdi_cdir, CDIR, FREAD, (long)cwdi.cwdi_cdir);
#if 0
       /*
        * Disable for now, since p->p_tracep appears to point to a ktr_desc *
@@ -406,9 +412,12 @@
                   i, fdfile.ff_file, Pid);
               return;
       }
+       if (Aflg && file.f_type != DTYPE_VNODE)
+               (void)printf("%*lx ",
+                       2*(int)(sizeof(void*)), (long)fdfile.ff_file);
       switch (file.f_type) {
       case DTYPE_VNODE:
-               vtrans(file.f_data, i, file.f_flag);
+               vtrans(file.f_data, i, file.f_flag, (long)fdfile.ff_file);
               break;
       case DTYPE_SOCKET:
               if (checkfile == 0)
@@ -424,7 +433,7 @@
       case DTYPE_MQUEUE:
       case DTYPE_SEM:
               if (checkfile == 0)
-                       misctrans(&file);
+                       misctrans(&file, i);
               break;
       default:
               dprintf("unknown file type %d for file %d of pid %d",
@@ -500,7 +509,7 @@
}

static void
-vtrans(struct vnode *vp, int i, int flag)
+vtrans(struct vnode *vp, int i, int flag, long addr)
{
       struct vnode vn;
       struct filestat fst;
@@ -530,6 +539,8 @@
               if (fsmatch == 0 || (filename == NULL && fsflg == 0))
                       return;
       }
+       if (Aflg)
+               (void)printf("%*lx ", 2*(int)(sizeof(void*)), addr);
       PREFIX(i);
       if (badtype == dead) {
               char buf[1024];
@@ -1094,10 +1105,10 @@
}

static void
-misctrans(struct file *file)
+misctrans(struct file *file, int i)
{

-       PREFIX((int)file->f_type);
+       PREFIX(i);
       pmisc(file, dtypes[file->f_type]);
}