diff --git a/sysutils/lsof/Makefile b/sysutils/lsof/Makefile index c391b6437419..30dd11b52e79 100644 --- a/sysutils/lsof/Makefile +++ b/sysutils/lsof/Makefile @@ -5,6 +5,7 @@ PORTNAME= lsof DISTVERSION= 4.95.0 +PORTREVISION= 1 PORTEPOCH= 8 CATEGORIES= sysutils diff --git a/sysutils/lsof/files/patch-00CREDITS b/sysutils/lsof/files/patch-00CREDITS new file mode 100644 index 000000000000..799902fda8e3 --- /dev/null +++ b/sysutils/lsof/files/patch-00CREDITS @@ -0,0 +1,11 @@ +--- 00CREDITS.orig 2022-04-27 22:38:44 UTC ++++ 00CREDITS +@@ -560,7 +560,7 @@ provided test systems where I was able to do developme + Grisha Levit + @10ne1 (github account) + @a1346054 +- Damjan Jovanovic ++ @Damjan Jovanovic + Fabrice Fontaine and + Danny Fowler + diff --git a/sysutils/lsof/files/patch-00DIST b/sysutils/lsof/files/patch-00DIST new file mode 100644 index 000000000000..f023b90d628f --- /dev/null +++ b/sysutils/lsof/files/patch-00DIST @@ -0,0 +1,27 @@ +--- 00DIST.orig 2022-04-27 22:38:44 UTC ++++ 00DIST +@@ -5290,6 +5290,24 @@ July 14, 2018 + [FreeBSD] remove various old FreeBSD versions from support + submitted by @emaste + ++ [FreeBSD] Use user mode APIs on FreeBSD ++ Extensively changes the FreeBSD dialect to use user mode APIs ++ (sysctls and libutil's kinfo_getfile()), only falling back to kvm ++ access when it's available and required for certain features. lsof can ++ now run as an ordinary user, though not all processes may be visible ++ and some features will be absent without kvm access (file lock state, ++ kqueue info, some pipe details, nullfs details). ++ This also fixes numerous long standing issues: file lock state is now ++ visible on all filesystems, the cwd, root dir, jail dir, text file and ++ controlling TTY are now visible, filenames are shown for all ++ filesystems, procfs is working again and supports file searches even ++ when there are multiple procfs mountpoints, the code is shorter, ++ cleaner and should need much less future maintenance. ++ It builds and works from FreeBSD 9.0 to 14-CURRENT, though older ++ versions have less features (eg. 12 doesn't provide socket buffer ++ usage, 11 also lacks TCP flags and state). ++ Provided by @DamjanJovanovic in #184. ++ + + [FreeBSD] configure: suggest variable to set if FreeBSD sys not + found diff --git a/sysutils/lsof/files/patch-00PORTING b/sysutils/lsof/files/patch-00PORTING new file mode 100644 index 000000000000..ee69817df23d --- /dev/null +++ b/sysutils/lsof/files/patch-00PORTING @@ -0,0 +1,26 @@ +--- 00PORTING.orig 2022-04-27 22:38:44 UTC ++++ 00PORTING +@@ -142,7 +142,12 @@ any functions from the lsof library in the lib/ subdir + One final note about the /proc-based Linux lsof: it doesn't need + any functions from the lsof library in the lib/ subdirectory. + ++FreeBSD is now also using a similar approach. Sysctls are used ++to retrieve processes, files, socket PCBs etc. Access to kernel ++memory is optional and only used as a last resort when data is ++not provided by the kernel. + ++ + General Guidelines + ------------------ + +@@ -1395,6 +1400,10 @@ possibilities + + HASXOPT_VALUE defines the default binary value for the X option + in store.c. ++ ++ HAS_XTCPCB_TMAXSEG indicates that in this FreeBSD ++ version exists and its struct xtcpcb has a ++ t_magseg field. + + HAS_ZFS indicates the dialect has support for the ZFS file + system. diff --git a/sysutils/lsof/files/patch-Configure b/sysutils/lsof/files/patch-Configure new file mode 100644 index 000000000000..44adef1f7286 --- /dev/null +++ b/sysutils/lsof/files/patch-Configure @@ -0,0 +1,162 @@ +--- Configure.orig 2022-04-27 22:38:44 UTC ++++ Configure +@@ -1473,71 +1473,88 @@ kernel generation process. + echo "!!!WARNING!!! Configuring for FreeBSD 6.0" + ;; + 7.0*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=7000 + ;; + 7.1*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=7010 + ;; + 7.2*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=7020 + ;; + 7.3*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=7030 + ;; + 7.4*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=7040 + ;; + 7*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_VERS=7000 + echo "!!!WARNING!!! Unsupported FreeBSD version: $LSOF_VSTR" + echo "!!!WARNING!!! Configuring for FreeBSD 7.0" + ;; + 8.0*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=8000 + ;; + 8.1*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=8010 + ;; + 8.2*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=8020 + ;; + 8.3*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=8030 + ;; + 8.4*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=8040 + ;; + 9*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=9000 + ;; + 10*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=10000 + ;; + 11*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=11000 + ;; + 12*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=12000 + ;; + 13*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=13000 + ;; + 14*) ++ LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_TSTBIGF=" " + LSOF_VERS=14000 + ;; +@@ -1648,7 +1665,7 @@ kernel generation process. + + case $LSOF_VERS in # { + 1000) +- LSOF_CFGF="$LSOF_CFGF -DHASPROCFS" ++ LSOF_CFGF="$LSOF_CFGF" + LSOF_CFGL="$LSOF_CFGL -lutil" + LSOF_DINC="$LSOF_DINC -I`pwd`/dialects/freebsd/include" + if test "X$FREEBSD_KERNEL" = "X" # { +@@ -2195,19 +2212,11 @@ LOCKF_OWNER4 + else + LSOF_TMP1="miscfs" + fi # } +- if test $LSOF_VERS -lt 5000 # { +- then +- if test -d ${FREEBSD_SYS}/${LSOF_TMP1}/procfs # { +- then +- LSOF_CFGF="$LSOF_CFGF -DHASPROCFS" +- LSOF_DINC_ADD=1 +- fi # } +- else +- if test -d ${FREEBSD_SYS}/${LSOF_TMP1}/pseudofs # { +- then +- LSOF_CFGF="$LSOF_CFGF -DHASPSEUDOFS" +- LSOF_DINC_ADD=1 +- fi # } ++ LSOF_CFGF="$LSOF_CFGF -DHASPROCFS" ++ if test -d ${FREEBSD_SYS}/${LSOF_TMP1}/pseudofs # { ++ then ++ LSOF_CFGF="$LSOF_CFGF -DHASPSEUDOFS" ++ LSOF_DINC_ADD=1 + fi # } + if test -r ${LSOF_INCLUDE}/${LSOF_TMP1}/nullfs/null.h # { + then +@@ -2285,6 +2294,36 @@ LOCKF_OWNER4 + then + LSOF_CFGF="$LSOF_CFGF -DHASUTMPX" + fi # } ++ ++ # Does struct xtcpcb have t_maxseg? ++ rm -f ${LSOF_TMPC}.* ++ cat > ${LSOF_TMPC}.c << .LSOF_END_HERE_DOC4 ++#undef _KERNEL ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++main() { ++struct xtcpcb pcb; pcb.t_maxseg = 0; ++} ++.LSOF_END_HERE_DOC4 ++ $LSOF_CC ${LSOF_TMPC}.c -o ${LSOF_TMPC}.x > /dev/null 2>&1 ++ if test $? -eq 0 # { ++ then ++ LSOF_CFGF="$LSOF_CFGF -DHAS_XTCPCB_TMAXSEG" ++ fi # } ++ rm -f ${LSOF_TMPC}.* ++ ++ # Does struct kinfo_file have kf_un.kf_sock.kf_sock_sendq? ++ grep -q kf_sock_sendq ${LSOF_INCLUDE}/sys/user.h ++ if test $? -eq 0 # { ++ then ++ LSOF_CFGF="$LSOF_CFGF -DHAS_KF_SOCK_SENDQ" ++ fi # } ++ + LSOF_DIALECT_DIR=freebsd + ;; + diff --git a/sysutils/lsof/files/patch-arg.c b/sysutils/lsof/files/patch-arg.c new file mode 100644 index 000000000000..3530bbb130ee --- /dev/null +++ b/sysutils/lsof/files/patch-arg.c @@ -0,0 +1,11 @@ +--- arg.c.orig 2022-04-27 22:38:44 UTC ++++ arg.c +@@ -478,7 +478,7 @@ ck_file_arg(i, ac, av, fv, rs, sbp, accept_deleted_fil + } + + if (accept_deleted_file) { +- if (!ss & ErrStat == 0) ++ if (!ss && ErrStat == 0) + err = 1; + if (ErrStat) + ErrStat = 0; diff --git a/sysutils/lsof/files/patch-dialects_freebsd_Makefile b/sysutils/lsof/files/patch-dialects_freebsd_Makefile new file mode 100644 index 000000000000..6f3b8712cd38 --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_Makefile @@ -0,0 +1,36 @@ +--- dialects/freebsd/Makefile.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/Makefile +@@ -21,13 +21,13 @@ GRP= + + GRP= + +-HDR= lsof.h lsof_fields.h dlsof.h machine.h proto.h dproto.h dzfs.h ++HDR= lsof.h lsof_fields.h dlsof.h machine.h proto.h dproto.h + +-SRC= dmnt.c dnode.c dnode1.c dnode2.c dproc.c dsock.c dstore.c \ ++SRC= dmnt.c dnode.c dproc.c dsock.c dstore.c \ + arg.c main.c misc.c node.c print.c proc.c store.c usage.c \ + util.c + +-OBJ= dmnt.o dnode.o dnode1.o dnode2.o dproc.o dsock.o dstore.o \ ++OBJ= dmnt.o dnode.o dproc.o dsock.o dstore.o \ + arg.o main.o misc.o node.o print.o proc.o store.o usage.o \ + util.o + +@@ -123,16 +123,6 @@ dnode.o: ${HDR} dnode.c + dmnt.o: ${HDR} dmnt.c + + dnode.o: ${HDR} dnode.c +- +-dnode1.o: ${HDR} dnode1.c +- +-dnode2.o: dzfs.h dnode2.c +- @if [ -f ./Makefile.zfs ]; then \ +- ${MAKE} -f Makefile.zfs dnode2.o; \ +- else \ +- echo "${CC} ${CFLAGS} -c dnode2.c"; \ +- ${CC} ${CFLAGS} -c dnode2.c; \ +- fi; + + dproc.o: ${HDR} dproc.c + diff --git a/sysutils/lsof/files/patch-dialects_freebsd_Makefile.zfs b/sysutils/lsof/files/patch-dialects_freebsd_Makefile.zfs new file mode 100644 index 000000000000..0862e236f350 --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_Makefile.zfs @@ -0,0 +1,20 @@ +--- dialects/freebsd/Makefile.zfs.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/Makefile.zfs +@@ -1,17 +0,0 @@ +- +-# Makefile.zfs -- FreeBSD Makefile remainder for ZFS modules +-# +-# $Id: Makefile.zfs,v 1.3 2011/08/07 22:51:28 abe Exp $ +- +-CFLAGS+=-D_SOLARIS_C_SOURCE +-CFLAGS+=${DEBUG} +-CFLAGS+=-I${OPENSOLARIS}/compat/opensolaris +-CFLAGS+=-I${OPENSOLARIS}/contrib/opensolaris/uts/common/fs/zfs +-CFLAGS+=-I${OPENSOLARIS}/contrib/opensolaris/uts/common/zmod +-CFLAGS+=-I${OPENSOLARIS}/contrib/opensolaris/uts/common +-CFLAGS+=-I${OPENSOLARIS}/contrib/opensolaris/common/zfs +-CFLAGS+=-I${OPENSOLARIS}/contrib/opensolaris/common +-CFLAGS+=-I${.CURDIR}/usr/src/include +-CFLAGS+=-I`pwd` +- +-dnode2.o: dzfs.h dnode2.c diff --git a/sysutils/lsof/files/patch-dialects_freebsd_Mksrc b/sysutils/lsof/files/patch-dialects_freebsd_Mksrc new file mode 100644 index 000000000000..0135f802f311 --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_Mksrc @@ -0,0 +1,19 @@ +--- dialects/freebsd/Mksrc.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/Mksrc +@@ -14,7 +14,7 @@ D=dialects/freebsd + + + D=dialects/freebsd +-L="dlsof.h dmnt.c dnode.c dnode1.c dnode2.c dproc.c dproto.h dsock.c dstore.c dzfs.h machine.h" ++L="dlsof.h dmnt.c dnode.c dproc.c dproto.h dsock.c dstore.c machine.h" + + for i in $L + do +@@ -23,7 +23,3 @@ done + echo "$LSOF_MKC $D/$i $i" + done + +-# For ZFS +- +-rm -f vnode_if.h +-touch vnode_if.h diff --git a/sysutils/lsof/files/patch-dialects_freebsd_dlsof.h b/sysutils/lsof/files/patch-dialects_freebsd_dlsof.h new file mode 100644 index 000000000000..06ef385de019 --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_dlsof.h @@ -0,0 +1,83 @@ +--- dialects/freebsd/dlsof.h.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/dlsof.h +@@ -133,6 +133,8 @@ typedef struct device *device_t; + #define NFS + #define m_stat mnt_stat + ++struct statfs; ++extern int statfs(const char *, struct statfs *); + #define _KERNEL + + #include +@@ -237,7 +239,9 @@ struct vop_setextattr_args; + #include + #include + ++#define syscall_args __bad_syscall_args + #include ++#undef __bad_syscall_args + #include + #undef TRUE + #undef FALSE +@@ -261,21 +265,11 @@ struct vop_generic_args; + #undef KERNEL + # endif /* defined(HASNULLFS) */ + +-# if defined(HASPROCFS) +-#include +- +-#define PNSIZ 5 +-# endif /* defined(HASPROCFS) */ +- + # if defined(HASPSEUDOFS) + #include + # endif /* defined(HASPSEUDOFS) */ + +-# if defined(HAS_ZFS) +-#include "dzfs.h" +-# endif /* defined(HAS_ZFS) */ + +- + #define P_ADDR ki_paddr + #define P_COMM ki_comm + #define P_FD ki_fd +@@ -454,8 +448,7 @@ struct l_vfs { + # endif /* defined(P_ADDR) */ + + struct l_vfs { +- KA_T addr; /* kernel address */ +- fsid_t fsid; /* file system ID */ ++ uint64_t fsid; /* file system ID */ + + # if defined(MOUNT_NONE) + short type; /* type of file system */ +@@ -512,6 +505,20 @@ struct sfile { + #define XDR_PMAPLIST (const xdrproc_t)xdr_pmaplist + + ++struct pcb_lists { ++ struct xunpcb *un_stream_pcbs; ++ size_t n_un_stream_pcbs; ++ struct xunpcb *un_dgram_pcbs; ++ size_t n_un_dgram_pcbs; ++ struct xunpcb *un_seqpacket_pcbs; ++ size_t n_un_seqpacket_pcbs; ++ struct xtcpcb *tcp_pcbs; ++ size_t n_tcp_pcbs; ++ struct xinpcb *udp_pcbs; ++ size_t n_udp_pcbs; ++}; ++ ++ + /* + * Definitions for rdev.c + */ +@@ -583,5 +590,8 @@ struct namecache { + + #define VNODE_VFLAG v_iflag + #define NCACHE_VROOT VV_ROOT ++ ++ ++#include + + #endif /* defined(FREEBSD_LSOF_H) */ diff --git a/sysutils/lsof/files/patch-dialects_freebsd_dmnt.c b/sysutils/lsof/files/patch-dialects_freebsd_dmnt.c new file mode 100644 index 000000000000..9dd6965d9868 --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_dmnt.c @@ -0,0 +1,318 @@ +--- dialects/freebsd/dmnt.c.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/dmnt.c +@@ -53,185 +53,8 @@ static char *mnt_names[] = INITMOUNTNAMES; + # endif /* defined(MOUNT_NONE)) */ + + +-#if defined(HAS_NO_SI_UDEV) +-/* +- * Dev2Udev() -- convert a kernel device number to a user device number +- */ + +-dev_t +-Dev2Udev(c) +- +-# if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) +- KA_T c; +-# else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +- struct cdev *c; +-# endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ +- +-{ +- +-# if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) +- char *cp; +- char *dn = (char *)NULL; +- char *ln = (char *)NULL; +- struct statfs *mb; +- int n, sr; +- static u_int s; +- struct stat sb; +- static int ss = 0; +-# endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +- +-# if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) +- KA_T ca; +- struct cdev_priv cp; +- +- if (!c) +- return(NODEV); +- +-# if defined(HAS_CDEV2PRIV) +- ca = (KA_T)cdev2priv((struct cdev *)c); +-# else /* !defined(HAS_CDEV2PRIV) */ +- ca = (KA_T)member2struct(cdev_priv, cdp_c, c); +-# endif /* defined(HAS_CDEV2PRIV) */ +- +- if (kread((KA_T)ca, (char *)&cp, sizeof(cp))) +- return(NODEV); +- return((dev_t)cp.cdp_inode); +-# else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +-# if defined(HAS_SI_PRIV) + /* +- * If the cdev structure has a private sub-structure, read it. +- */ +- struct cdev_priv sp; +- +- if (!c->si_priv || kread((KA_T)c->si_priv, (char *)&sp, sizeof(sp))) +- return(0); +-# endif /* defined(HAS_SI_PRIV) */ +- +- if (ss) { +- +-# if defined(HAS_SI_PRIV) +- return(sp.cdp_inode ^ s); +-# else /* !defined(HAS_SI_PRIV) */ +- return(c->si_inode ^ s); +-# endif /* defined(HAS_SI_PRIV) */ +- +- } +- +-/* +- * Determine the random udev seed from stat(2) operations on "/" and +- * its device. +- */ +- if ((n = getmntinfo(&mb, MNT_NOWAIT)) <= 0) { +- (void) fprintf(stderr, "%s: no mount information\n", Pn); +- Error(); +- } +- for (; n; n--, mb++) { +- +-# if defined(MOUNT_NONE) +- if (mb->f_type == MOUNT_NONE || mb->f_type >= MOUNT_MAXTYPE) +-# else /* !defined(MOUNT_NONE) */ +- if (!mb->f_type) +-# endif /* defined(MOUNT_NONE) */ +- +- continue; +- /* +- * Get the real directory name. Ignore all but the root directory; +- * safely stat("/"). +- */ +- if (dn) +- (void) free((FREE_P *)dn); +- if (!(dn = mkstrcpy(mb->f_mntonname, (MALLOC_S *)NULL))) { +- +-Dev2Udev_no_space: +- +- (void) fprintf(stderr, "%s: no space for mount at ", Pn); +- safestrprt(mb->f_mntonname, stderr, 0); +- (void) fprintf(stderr, " ("); +- safestrprt(mb->f_mntfromname, stderr, 0); +- (void) fprintf(stderr, ")\n"); +- Error(); +- } +- if (!(ln = Readlink(dn))) { +- if (!Fwarn) { +- (void) fprintf(stderr, +- " Output information may be incomplete.\n"); +- } +- continue; +- } +- if (ln != dn) { +- (void) free((FREE_P *)dn); +- dn = ln; +- } +- ln = (char *)NULL; +- if (strcmp(dn, "/")) +- continue; +- if (statsafely(dn, &sb)) +- continue; +- /* +- * Get the real device name and safely stat(2) it. +- */ +- (void) free((FREE_P *)dn); +- if (!(dn = mkstrcpy(mb->f_mntfromname, (MALLOC_S *)NULL))) +- goto Dev2Udev_no_space; +- ln = Readlink(dn); +- if ((sr = statsafely(ln, &sb))) { +- +- /* +- * If the device stat(2) failed, see if the device name indicates +- * an NFS mount, a cd9660 device, or a ZFS mount. If any condition +- * is true, set the user device number seed to zero. +- */ +- if (((cp = strrchr(ln, ':')) && (*(cp + 1) == '/')) +- || !strcasecmp(mb->f_fstypename, "cd9660") +- || !strcasecmp(mb->f_fstypename, "zfs") +- ) { +- ss = 1; +- s = (u_int)0; +- } +- } +- if (ln != dn) +- (void) free((FREE_P *)ln); +- ln = (char *)NULL; +- (void) free((FREE_P *)dn); +- dn = (char *)NULL; +- if (sr && !ss) +- continue; +- if (!ss) { +- ss = 1; +- s = (u_int)sb.st_ino ^ (u_int)sb.st_rdev; +- } +- break; +- } +-/* +- * Free string copies, as required. +- */ +- if (dn) +- (void) free((FREE_P *)dn); +- if (ln) +- (void) free((FREE_P *)ln); +-/* +- * If the device seed is known, return its application to the cdev structure's +- * inode. +- */ +- if (ss) { +- +-# if defined(HAS_SI_PRIV) +- return(sp.cdp_inode ^ s); +-# else /* !defined(HAS_SI_PRIV) */ +- return(c->si_inode ^ s); +-# endif /* defined(HAS_SI_PRIV) */ +- +- } +- (void) fprintf(stderr, "%s: can't determine user device random seed.\n", Pn); +- Error(); +- +-# endif /* !defined(HAS_CONF_MINOR) */ +- +-} +-#endif /* defined(HAS_NO_SI_UDEV) */ +- +- +-/* + * readmnt() - read mount table + */ + +@@ -244,10 +67,7 @@ readmnt() + struct mounts *mtp; + int n; + struct stat sb; +- +-#if defined(HASPROCFS) + unsigned char procfs = 0; +-#endif /* defined(HASPROCFS) */ + + if (Lmi || Lmist) + return(Lmi); +@@ -284,7 +104,7 @@ no_space_for_mount: + (void) fprintf(stderr, " ("); + safestrprt(mb->f_mntfromname, stderr, 0); + (void) fprintf(stderr, ")\n"); +- Error(); ++ Exit(1); + } + if (!(ln = Readlink(dn))) { + if (!Fwarn) { +@@ -334,16 +154,7 @@ no_space_for_mount: + mtp->dir = dn; + dn = (char *)NULL; + +-#if defined(HASPROCFS) +- +-#if defined(MOUNT_NONE) +- if (mb->f_type == MOUNT_PROCFS) +-#else /* !defined(MOUNT_NONE) */ +- if (strcasecmp(mb->f_fstypename, "procfs") == 0) +-#endif /* defined(MOUNT_NONE) */ +- +- { +- ++ if (strcasecmp(mb->f_fstypename, "procfs") == 0) { + /* + * Save information on exactly one procfs file system. + */ +@@ -354,7 +165,6 @@ no_space_for_mount: + Mtprocfs = mtp; + } + } +-#endif /* defined(HASPROCFS) */ + + mtp->next = Lmi; + mtp->dev = sb.st_dev; +@@ -394,55 +204,65 @@ struct l_vfs * + */ + + struct l_vfs * +-readvfs(vm) +- KA_T vm; /* kernel mount address from vnode */ ++readvfs(uint64_t fsid, const char *path) + { +- struct mount m; ++ struct statfs m; + struct l_vfs *vp; + /* + * Search for match on existing entry. + */ +- for (vp = Lvfs; vp; vp = vp->next) { +- if (vm == vp->addr) +- return(vp); ++ if (fsid != VNOVAL) { ++ for (vp = Lvfs; vp; vp = vp->next) { ++ if (fsid == vp->fsid) ++ return(vp); ++ } + } + /* + * Read the (new) mount structure, allocate a local entry, and fill it. + */ +- if (kread((KA_T)vm, (char *)&m, sizeof(m)) != 0) ++ if (path == NULL || path[0] == '\0') + return((struct l_vfs *)NULL); ++ if (statfs(path, &m) != 0) ++ return((struct l_vfs *)NULL); ++ ++/* ++ * If the previous search by fsid couldn't be done, search by mountpoint instead. ++ */ ++ for (vp = Lvfs; vp; vp = vp->next) { ++ if (!strcmp(vp->fsname, m.f_mntfromname) && !strcmp(vp->dir, m.f_mntonname)) ++ return(vp); ++ } + if (!(vp = (struct l_vfs *)malloc(sizeof(struct l_vfs)))) { + (void) fprintf(stderr, "%s: PID %d, no space for vfs\n", + Pn, Lp->pid); +- Error(); ++ Exit(1); + } +- if (!(vp->dir = mkstrcpy(m.m_stat.f_mntonname, (MALLOC_S *)NULL)) +- || !(vp->fsname = mkstrcpy(m.m_stat.f_mntfromname, (MALLOC_S *)NULL))) ++ if (!(vp->dir = mkstrcpy(m.f_mntonname, (MALLOC_S *)NULL)) ++ || !(vp->fsname = mkstrcpy(m.f_mntfromname, (MALLOC_S *)NULL))) + { + (void) fprintf(stderr, "%s: PID %d, no space for mount names\n", + Pn, Lp->pid); +- Error(); ++ Exit(1); + } +- vp->addr = vm; +- vp->fsid = m.m_stat.f_fsid; ++ vp->fsid = fsid; + + #if defined(MOUNT_NONE) +- vp->type = m.m_stat.f_type; ++ vp->type = m.f_type; + #else /* !defined(MOUNT_NONE) */ + { + int len; + +- if ((len = strlen(m.m_stat.f_fstypename))) { ++ if ((len = strlen(m.f_fstypename))) { + if (len > (MFSNAMELEN - 1)) + len = MFSNAMELEN - 1; +- if (!(vp->typnm = mkstrcat(m.m_stat.f_fstypename, len, ++ if (!(vp->typnm = mkstrcat(m.f_fstypename, len, + (char *)NULL, -1, (char *)NULL, -1, + (MALLOC_S *)NULL))) + { + (void) fprintf(stderr, + "%s: no space for fs type name: ", Pn); +- safestrprt(m.m_stat.f_fstypename, stderr, 1); +- Error(); ++ safestrprt(m.f_fstypename, stderr, 1); ++ Exit(1); + } + } else + vp->typnm = ""; diff --git a/sysutils/lsof/files/patch-dialects_freebsd_dnode.c b/sysutils/lsof/files/patch-dialects_freebsd_dnode.c new file mode 100644 index 000000000000..661a79b2d10e --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_dnode.c @@ -0,0 +1,1780 @@ +--- dialects/freebsd/dnode.c.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/dnode.c +@@ -41,34 +41,66 @@ static char copyright[] = + #include "./lockf_owner.h" + #endif /* defined(HAS_LOCKF_ENTRY) */ + +-#if defined(HAS_ZFS) +-#include "dzfs.h" +-#endif /* defined(HAS_ZFS) */ + +- +-#if defined(HASFDESCFS) && HASFDESCFS==1 +-_PROTOTYPE(static int lkup_dev_tty,(dev_t *dr, INODETYPE *ir)); +-#endif /* defined(HASFDESCFS) && HASFDESCFS==1 */ +- +- + #if defined(HASPTSFN) && defined(DTYPE_PTS) + #include + #endif /* defined(HASPTSFN) && defined(DTYPE_PTS) */ + + +-#if defined(HAS_TMPFS) +-#include +-#endif /* defined(HAS_TMPFS) */ ++_PROTOTYPE(static void get_lock_state_kvm,(KA_T f)); + +-_PROTOTYPE(static void get_lock_state,(KA_T f)); + +- + /* +- * get_lock_state() - get the lock state ++ * get_lock_state_*() - get the lock state + */ + ++#if __FreeBSD_version >= 1400053 + static void +-get_lock_state(f) ++get_lock_state_sysctl(int fd, struct xfile *xfile) ++{ ++ int mib[4]; ++ size_t len; ++ int ret; ++ char *buffer; ++ ++ len = 2; ++ ret = sysctlnametomib("kern.lockf", mib, &len); ++ if (ret < 0) ++ return; ++ ++ mib[2] = (pid_t)Lp->pid; ++ mib[3] = fd; ++ ret = sysctl(mib, 4, NULL, &len, NULL, 0); ++ if (ret < 0) ++ return; ++ buffer = malloc(len); ++ if (buffer == NULL) ++ return; ++ ret = sysctl(mib, 4, buffer, &len, NULL, 0); ++ if (ret == 0) { ++ int i; ++ struct xlockf *xl; ++ int whole_file; ++ ++ for (i = 0; i < len; i += sizeof(struct xlockf)) { ++ xl = (struct xlockf *)&buffer[i]; ++ if (xl->xl_sysid == 0 && ((xl->xl_pid != -1 && xl->xl_pid == (pid_t)Lp->pid) ++ || (xl->xl_pid == -1 && xfile && xfile->xf_file == xl->xl_id))) { ++ whole_file = xl->xl_start == 0 && xl->xl_len == 0; ++ if (xl->xl_type == F_RDLCK) ++ Lf->lock = whole_file ? 'R' : 'r'; ++ else if (xl->xl_type == F_WRLCK) ++ Lf->lock = whole_file ? 'W' : 'w'; ++ break; ++ } ++ } ++ } ++ free(buffer); ++} ++#endif /* __FreeBSD_version >= 1400053 */ ++ ++static void ++get_lock_state_kvm(f) + KA_T f; /* inode's lock pointer */ + { + struct lockf lf; /* lockf structure */ +@@ -100,8 +132,6 @@ get_lock_state(f) + Lf->lock = lt ? 'R' : 'r'; + else if (le.lf_type == F_WRLCK) + Lf->lock = lt ? 'W' : 'w'; +- else if (le.lf_type == (F_RDLCK | F_WRLCK)) +- Lf->lock = 'u'; + return; + } + } while ((lep = (KA_T)le.lf_link.le_next) && (lep != lef)); +@@ -144,8 +174,6 @@ get_lock_state(f) + Lf->lock = lt ? 'R' : 'r'; + else if (lf.lf_type == F_WRLCK) + Lf->lock = lt ? 'W' : 'w'; +- else if (lf.lf_type == (F_RDLCK | F_WRLCK)) +- Lf->lock = 'u'; + break; + } while ((lfp = (KA_T)lf.lf_next) && (lfp != f)); + } +@@ -154,85 +182,9 @@ get_lock_state(f) + } + + +-# if defined(HASPROCFS) +-_PROTOTYPE(static void getmemsz,(pid_t pid)); +- +- +-/* +- * getmemsz() - get memory size of a /proc//mem entry +- */ +- +-static void +-getmemsz(pid) +- pid_t pid; +-{ +- int n; +- struct kinfo_proc *p; +- struct vmspace vm; +- +- for (n = 0, p = P; n < Np; n++, p++) { +- if (p->P_PID == pid) { +- if (!p->P_VMSPACE +- || kread((KA_T)p->P_VMSPACE, (char *)&vm, sizeof(vm))) +- return; +- Lf->sz = (SZOFFTYPE)ctob(vm.vm_tsize+vm.vm_dsize+vm.vm_ssize); +- Lf->sz_def = 1; +- return; +- } +- } +-} +-# endif /* defined(HASPROCFS) */ +- +- +-#if defined(HASFDESCFS) && HASFDESCFS==1 +-/* +- * lkup_dev_tty() - look up /dev/tty +- */ +- +-static int +-lkup_dev_tty(dr, ir) +- dev_t *dr; /* place to return device number */ +- INODETYPE *ir; /* place to return inode number */ +-{ +- int i; +- +- readdev(0); +- +-# if defined(HASDCACHE) +- +-lkup_dev_tty_again: +- +-# endif /* defined(HASDCACHE) */ +- +- for (i = 0; i < Ndev; i++) { +- if (strcmp(Devtp[i].name, "/dev/tty") == 0) { +- +-# if defined(HASDCACHE) +- if (DCunsafe && !Devtp[i].v && !vfy_dev(&Devtp[i])) +- goto lkup_dev_tty_again; +-# endif /* defined(HASDCACHE) */ +- +- *dr = Devtp[i].rdev; +- *ir = Devtp[i].inode; +- return(1); +- } +- } +- +-# if defined(HASDCACHE) +- if (DCunsafe) { +- (void) rereaddev(); +- goto lkup_dev_tty_again; +- } +-# endif /* defined(HASDCACHE) */ +- +- return(-1); +-} +-#endif /* defined(HASFDESCFS) && HASFDESCFS==1 */ +- +- + #if defined(HASKQUEUE) + /* +- * process_kqueue() - process kqueue file ++ * process_kf_kqueue() - process kqueue file + * + * Strictly speaking this function should appear in dfile.c, because it is + * a file processing function. However, the Net and Open BSD sources don't +@@ -240,113 +192,144 @@ void + */ + + void +-process_kqueue(ka) +- KA_T ka; /* kqueue file structure address */ ++process_kf_kqueue(struct kinfo_file *kf, KA_T ka) + { ++#if __FreeBSD_version < 1400052 + struct kqueue kq; /* kqueue structure */ ++#endif /* __FreeBSD_version < 1400052 */ + + (void) snpf(Lf->type, sizeof(Lf->type), "KQUEUE"); + enter_dev_ch(print_kptr(ka, (char *)NULL, 0)); ++#if __FreeBSD_version >= 1400052 ++ (void) snpf(Namech, Namechl, "count=%d, state=%#x", ++ kf->kf_un.kf_kqueue.kf_kqueue_count, ++ kf->kf_un.kf_kqueue.kf_kqueue_state); ++#else /* __FreeBSD_version < 1400052 */ + if (!ka || kread(ka, (char *)&kq, sizeof(kq))) + return; + (void) snpf(Namech, Namechl, "count=%d, state=%#x", kq.kq_count, + kq.kq_state); ++#endif /* __FreeBSD_version >= 1400052 */ + enter_nm(Namech); + } + #endif /* defined(HASKQUEUE) */ + + +-/* +- * process_node() - process vnode +- */ +- ++#if defined(KF_TYPE_EVENTFD) + void +-process_node(va) +- KA_T va; /* vnode kernel space address */ ++process_eventfd(struct kinfo_file *kf) + { +- dev_t dev, rdev; +- unsigned char devs; +- unsigned char rdevs; +- char dev_ch[32], *ep; +- struct inode *i; +- struct nfsnode *n; +- size_t sz; +- char *ty; +- unsigned char ums; +- enum vtype type; +- struct vnode *v, vb; +- struct l_vfs *vfs; ++ (void) snpf(Lf->type, sizeof(Lf->type), "EVENTFD"); ++#if __FreeBSD_version >= 1400052 ++ enter_dev_ch(print_kptr(kf->kf_un.kf_eventfd.kf_eventfd_addr, (char *)NULL, 0)); ++#endif /* __FreeBSD_version >= 1400052 */ ++ (void) snpf(Namech, Namechl, "value=%ju, flags=0x%x", ++ kf->kf_un.kf_eventfd.kf_eventfd_value, kf->kf_un.kf_eventfd.kf_eventfd_flags); ++ enter_nm(Namech); ++} ++#endif /* defined(KF_TYPE_EVENTFD) */ + +- struct inode ib; +- struct nfsnode nb; +-# if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) +- struct cdev si; +-# endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ + ++void ++process_shm(struct kinfo_file *kf) ++{ ++ (void) snpf(Lf->type, sizeof(Lf->type), "SHM"); ++ Lf->sz = kf->kf_un.kf_file.kf_file_size; ++ Lf->sz_def = 1; ++ Lf->off_def = 0; ++ if (kf->kf_un.kf_file.kf_file_fileid != VNOVAL) { ++ Lf->inode = kf->kf_un.kf_file.kf_file_fileid; ++ Lf->inp_ty = 1; ++ } ++ if (kf->kf_path[0]) { ++ snpf(Namech, Namechl, "%s", kf->kf_path); ++ enter_nm(Namech); ++ } ++} + +-#if defined(HAS9660FS) +- dev_t iso_dev; +- int iso_dev_def, iso_stat; +- INODETYPE iso_ino; +- long iso_links; +- SZOFFTYPE iso_sz; +-#endif /* defined(HAS9660FS) */ + +-#if defined(HASFDESCFS) +- struct fdescnode *f; ++void ++process_procdesc(struct kinfo_file *kf) ++{ ++ char pidstr[50]; + +-# if HASFDESCFS==1 +- static dev_t f_tty_dev; +- static INODETYPE f_tty_ino; +- static int f_tty_s = 0; +-# endif /* HASFDESCFS==1 */ ++ snpf(Lf->type, sizeof(Lf->type), "PROCDSC"); ++ snpf(pidstr, sizeof(pidstr), "pid=%d", kf->kf_un.kf_proc.kf_pid); ++ add_nma(pidstr, strlen(pidstr)); ++ if (kf->kf_path[0]) { ++ snpf(Namech, Namechl, "%s", kf->kf_path); ++ enter_nm(Namech); ++ } ++} + +- struct fdescnode fb; + +-#endif /* defined(HASFDESCFS) */ ++static const char* ++parse_proc_path(struct kinfo_file *kf, int *proc_pid) ++{ ++ const char *ty; ++ char *basename; + +-#if defined(HASFUSEFS) +- dev_t fuse_dev; +- int fuse_dev_def, fuse_stat; +- INODETYPE fuse_ino; +- long fuse_links; +- SZOFFTYPE fuse_sz; +-#endif /* defined(HASFUSEFS) */ ++ ty = (char *)NULL; ++ basename = strrchr(kf->kf_path, '/'); ++ if (basename) { ++ ++basename; ++ if (!strcmp(basename, "cmdline")) { ++ } else if (!strcmp(basename, "dbregs")) { ++ } else if (!strcmp(basename, "etype")) { ++ ty = "PETY"; ++ } else if (!strcmp(basename, "file")) { ++ ty = "PFIL"; ++ } else if (!strcmp(basename, "fpregs")) { ++ ty = "PFPR"; ++ } else if (!strcmp(basename, "map")) { ++ ty = "PMAP"; ++ } else if (!strcmp(basename, "mem")) { ++ ty = "PMEM"; ++ } else if (!strcmp(basename, "note")) { ++ ty = "PNTF"; ++ } else if (!strcmp(basename, "notepg")) { ++ ty = "PGID"; ++ } else if (!strcmp(basename, "osrel")) { ++ } else if (!strcmp(basename, "regs")) { ++ ty = "PREG"; ++ } else if (!strcmp(basename, "rlimit")) { ++ } else if (!strcmp(basename, "status")) { ++ ty = "PSTA"; ++ } else { ++ /* we're excluded all files - must be a directory, either /proc/ or /proc itself */ ++ ty = "PDIR"; ++ } ++ if (ty && strcmp(ty, "PDIR") != 0) { ++ char *parent_dir; ++ --basename; ++ *basename = '\0'; ++ parent_dir = strrchr(kf->kf_path, '/'); ++ if (parent_dir) ++ *proc_pid = strtol(++parent_dir, NULL, 10); ++ *basename = '/'; ++ } ++ } ++ return ty; ++} + +-#if defined(HASMSDOSFS) +- dev_t msdos_dev; +- int msdos_dev_def, msdos_stat; +- INODETYPE msdos_ino; +- long msdos_links; +- SZOFFTYPE msdos_sz; +-#endif /* defined(HASMSDOSFS) */ + +-# if defined(HAS_UFS1_2) +- int ufst; +- struct ufsmount um; +- struct ufs1_dinode d1; +- struct ufs2_dinode d2; +-# endif /* !defined(HAS_UFS1_2) */ ++/* ++ * process_vnode() - process vnode ++ */ + +-# if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) +- struct cdev cd; +-# endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ ++void ++process_vnode(struct kinfo_file *kf, struct xfile *xfile) ++{ ++ dev_t dev = 0, rdev = 0; ++ unsigned char devs; ++ unsigned char rdevs; ++ const char *ty; ++ KA_T va; ++ struct vnode *v, vb; ++ struct l_vfs *vfs; ++ uint64_t fsid; ++ char vfs_path[PATH_MAX]; + +- int cds; +- struct devfs_dirent de; +- struct devfs_dirent *d; +- char vtbuf[32]; +- char *vtbp; +- enum vtagtype { VT_DEVFS, VT_FDESC, VT_FUSEFS, VT_ISOFS, VT_PSEUDOFS, +- VT_NFS, VT_NULL, VT_TMPFS, VT_UFS, VT_ZFS, VT_MSDOSFS, +- VT_UNKNOWN +- }; +- +-# if defined(HAS_TMPFS) +- struct tmpfs_node tn; +- struct tmpfs_node *tnp; +-# endif /* defined(HAS_TMPFS) */ +- + #if defined(HASNULLFS) + # if !defined(HASPRINTDEV) + char dbuf[32]; +@@ -356,33 +339,16 @@ process_node(va) + int sc = 0; + #endif /* defined(HASNULLFS) */ + +-#if defined(HASPROCFS) +- struct pfsnode *p; ++ int proc_pid = 0; + struct procfsid *pfi; +- static int pgsz = -1; +- struct vmspace vm; + +- struct pfsnode pb; +-#endif /* defined(HASPROCFS) */ ++ struct stat st; ++ const int kf_vtype = kf->kf_vnode_type; + +-#if defined(HASPSEUDOFS) +- struct pfs_node pn; +- struct pfs_node *pnp; +-#endif /* defined(HASPSEUDOFS) */ ++ fsid = kf->kf_un.kf_file.kf_file_fsid; ++ va = xfile ? xfile->xf_vnode : 0; ++ strcpy(vfs_path, kf->kf_path); + +-#if defined(HAS_ZFS) +- zfs_info_t *z = (zfs_info_t *)NULL; +- zfs_info_t zi; +- char *zm = (char *)NULL; +-#else /* !defined(HAS_ZFS) */ +- static unsigned char zw = 0; +-#endif /* HAS_VFS */ +- +- enum vtagtype vtag; /* placed here to use the +- * artificial vtagtype +- * definition required for +- * FREEBSDV>=5000 */ +- + #if defined(HASNULLFS) + + process_overlaid_node: +@@ -398,122 +364,68 @@ process_overlaid_node: + * Initialize miscellaneous variables. This is done so that processing an + * overlaid node will be a fresh start. + */ +- devs = rdevs = ums = 0; +- i = (struct inode *)NULL; +- n = (struct nfsnode *)NULL; ++ devs = rdevs = 0; + Namech[0] = '\0'; + +-#if defined(HAS9660FS) +- iso_dev_def = iso_stat = 0; +-#endif /* defined(HAS9660FS) */ + +-#if defined(HASFDESCFS) +- f = (struct fdescnode *)NULL; +-#endif /* defined(HASFDESCFS) */ +- +-#if defined(HASFUSEFS) +- fuse_dev_def = fuse_stat = 0; +-#endif /* defined(HASFUSEFS) */ +- +-#if defined(HASMSDOSFS) +- msdos_dev_def = msdos_stat = 0; +-#endif /* defined(HASMSDOSFS) */ +- +- cds = 0; +- d = (struct devfs_dirent *)NULL; +-# if defined(HAS_UFS1_2) +- ufst = 0; +-# endif /* !defined(HAS_UFS1_2) */ +- +-#if defined(HASPROCFS) +- p = (struct pfsnode *)NULL; +-#endif /* defined(HASPROCFS) */ +- +-#if defined(HASPSEUDOFS) +- pnp = (struct pfs_node *)NULL; +-#endif /* defined(HASPSEUDOFS) */ +- +-# if defined(HAS_TMPFS) +- tnp = (struct tmpfs_node *)NULL; +-# endif /* defined(HAS_TMPFS) */ +- +- +-#if defined(HAS_ZFS) +- z = (zfs_info_t *)NULL; +- zm = (char *)NULL; +-#endif /* defined(HAS_ZFS) */ +- + /* + * Read the vnode. + */ +- if ( ! va) { +- enter_nm("no vnode address"); +- return; ++ v = NULL; ++ if (va) { ++ v = &vb; ++ if (kread((KA_T)va, (char *)v, sizeof(struct vnode))) ++ v = NULL; + } +- v = &vb; +- if (readvnode(va, v)) { +- enter_nm(Namech); +- return; +- } + +-#if defined(HASNCACHE) +- Lf->na = va; +-# if defined(HASNCVPID) +- Lf->id = v->v_id; +-# endif /* defined(HASNCVPID) */ +-#endif /* defined(HASNCACHE) */ ++ if (xfile) { + + #if defined(HASFSTRUCT) +- Lf->fna = va; +- Lf->fsv |= FSV_NI; ++ Lf->fna = (KA_T)xfile->xf_vnode; ++ Lf->fsv |= FSV_NI; + #endif /* defined(HASFSTRUCT) */ + ++ } ++ + /* + * Get the vnode type. + */ +- if (!v->v_mount) +- vfs = (struct l_vfs *)NULL; +- else { +- vfs = readvfs((KA_T)v->v_mount); +- if (vfs) { ++ vfs = readvfs(fsid, vfs_path); ++ if (vfs) { ++ fsid = vfs->fsid; + + #if defined(MOUNT_NONE) +- switch (vfs->type) { +- case MOUNT_NFS: +- Ntype = N_NFS; +- break; ++ switch (vfs->type) { ++ case MOUNT_NFS: ++ Ntype = N_NFS; ++ break; + +-# if defined(HASPROCFS) +- case MOUNT_PROCFS: +- Ntype = N_PROC; +- break; +-# endif /* defined(HASPROCFS) */ +- } ++ case MOUNT_PROCFS: ++ Ntype = N_PROC; ++ break; ++ } + #else /* !defined(MOUNT_NONE) */ +- if (strcasecmp(vfs->typnm, "nfs") == 0) +- Ntype = N_NFS; ++ if (strcasecmp(vfs->typnm, "nfs") == 0) ++ Ntype = N_NFS; + +-# if defined(HASPROCFS) +- else if (strcasecmp(vfs->typnm, "procfs") == 0) +- Ntype = N_PROC; +-# endif /* defined(HASPROCFS) */ ++ else if (strcasecmp(vfs->typnm, "procfs") == 0) ++ Ntype = N_PROC; + + # if defined(HASPSEUDOFS) +- else if (strcasecmp(vfs->typnm, "pseudofs") == 0) +- Ntype = N_PSEU; ++ else if (strcasecmp(vfs->typnm, "pseudofs") == 0) ++ Ntype = N_PSEU; + # endif /* defined(HASPSEUDOFS) */ + + # if defined(HAS_TMPFS) +- else if (strcasecmp(vfs->typnm, "tmpfs") == 0) +- Ntype = N_TMP; ++ else if (strcasecmp(vfs->typnm, "tmpfs") == 0) ++ Ntype = N_TMP; + # endif /* defined(HAS_TMPFS) */ + #endif /* defined(MOUNT_NONE) */ + +- } + } + if (Ntype == N_REGLR) { +- switch (v->v_type) { +- case VFIFO: ++ switch (kf_vtype) { ++ case KF_VTYPE_VFIFO: + Ntype = N_FIFO; + break; + default: +@@ -521,170 +433,20 @@ process_overlaid_node: + } + } + +-/* +- * For FreeBSD 5 and above VCHR and VBLK vnodes get the v_rdev structure. +- */ +- if (((v->v_type == VCHR) || (v->v_type == VBLK)) +- && v->v_rdev ++#if __FreeBSD_version >= 1400053 ++ get_lock_state_sysctl(kf->kf_fd, xfile); ++#elif defined(HAS_V_LOCKF) ++ if (v && v->v_lockf) ++ (void) get_lock_state_kvm((KA_T)v->v_lockf); ++#endif /* __FreeBSD_version >= 1400053 */ + +-# if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) +- && !kread((KA_T)v->v_rdev, (char *)&cd, sizeof(cd)) +-# endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ + +- ) { +- cds = 1; +- } +- + /* +- * Define the specific node pointer. ++ * Deal with special filesystems. + */ ++ if (vfs && (!strcmp(vfs->typnm, "null") || !strcmp(vfs->typnm, "nullfs"))) { + +-/* +- * Get the pseudo vnode tag type for FreeBSD >= 5. +- */ +- vtag = VT_UNKNOWN; +- if (!kread((KA_T)v->v_lock.lock_object.lo_name, (char *)&vtbuf, sizeof(vtbuf))) +- { +- vtbuf[sizeof(vtbuf) - 1] = '\0'; +- vtbp = vtbuf; +- if (!strcmp(vtbuf, "ufs")) +- vtag = VT_UFS; +- else if (!strcmp(vtbuf, "zfs")) { +- +-#if !defined(HAS_ZFS) +- if (!Fwarn && !zw) { +- (void) fprintf(stderr, +- "%s: WARNING: no ZFS support has been defined.\n", +- Pn); +- (void) fprintf(stderr, +- " See 00FAQ for more information.\n"); +- zw = 1; +- } +-#else /* defined(HAS_ZFS) */ +- vtag = VT_ZFS; +-#endif /* !defined(HAS_ZFS) */ +- +- } else if (!strcmp(vtbuf, "devfs")) +- vtag = VT_DEVFS; +- else if (!strcmp(vtbuf, "nfs")) +- vtag = VT_NFS; +- else if (!strcmp(vtbuf, "newnfs")) +- vtag = VT_NFS; +- else if (!strcmp(vtbuf, "oldnfs")) +- vtag = VT_NFS; +- else if (!strcmp(vtbuf, "isofs")) +- vtag = VT_ISOFS; +- else if (!strcmp(vtbuf, "pseudofs")) +- vtag = VT_PSEUDOFS; +- else if (!strcmp(vtbuf, "nullfs")) +- vtag = VT_NULL; +- else if (!strcmp(vtbuf, "null")) +- vtag = VT_NULL; +- else if (!strcmp(vtbuf, "fdesc")) +- vtag = VT_FDESC; +- else if (!strcmp(vtbuf, "fuse")) +- vtag = VT_FUSEFS; +- else if (!strcmp(vtbuf, "tmpfs")) +- vtag = VT_TMPFS; +- else if (!strcmp(vtbuf, "msdosfs")) +- vtag = VT_MSDOSFS; +- } else +- vtbp = "(unknown)"; +- +- switch (vtag) { +- +- case VT_DEVFS: +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&de, sizeof(de))) +- { +- (void) snpf(Namech, Namechl, "no devfs node: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- d = &de; +- if (v->v_type == VDIR) { +- if (!d->de_dir +- || kread((KA_T)d->de_dir, (char *)&de, sizeof(de))) { +- (void) snpf(Namech, Namechl, "no devfs dir node: %s", +- print_kptr((KA_T)d->de_dir, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- } +- break; +- +-#if defined(HASFDESCFS) +- case VT_FDESC: +- +- if (kread((KA_T)v->v_data, (char *)&fb, sizeof(fb)) != 0) { +- (void) snpf(Namech, Namechl, "can't read fdescnode at: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- f = &fb; +- break; +-#endif /* defined(HASFDESCFS) */ +- +-#if defined(HASFUSEFS) +- case VT_FUSEFS: +- if (read_fuse_node(v, &fuse_dev, &fuse_dev_def, &fuse_ino, +- &fuse_links, &fuse_sz)) +- { +- (void) snpf(Namech, Namechl, "no fuse node: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- fuse_stat = 1; +- break; +-#endif /* defined(HASFUSEFS) */ +- +-#if defined(HASMSDOSFS) +- case VT_MSDOSFS: +- if (read_msdos_node(v, &msdos_dev, &msdos_dev_def, &msdos_ino, +- &msdos_links, &msdos_sz)) +- { +- (void) snpf(Namech, Namechl, "can't read denode at: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- msdos_stat = 1; +- break; +-#endif /* defined(HASMSDOSFS) */ +- +-#if defined(HAS9660FS) +- case VT_ISOFS: +- if (read_iso_node(v, &iso_dev, &iso_dev_def, &iso_ino, &iso_links, +- &iso_sz)) +- { +- (void) snpf(Namech, Namechl, "no iso node: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- iso_stat = 1; +- break; +-#endif /* defined(HAS9660FS) */ +- +- break; +- case VT_NFS: +- +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&nb, sizeof(nb))) { +- (void) snpf(Namech, Namechl, "no nfs node: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- n = &nb; +- +- break; +- + #if defined(HASNULLFS) +- case VT_NULL: + if (sc == 1) { + + /* +@@ -692,14 +454,14 @@ process_overlaid_node: + * the mounted-on directory, the file system name, and the device + * number. + */ +- if (vfs && (vfs->dir || vfs->fsname || vfs->fsid.val[0])) { +- if (vfs->fsid.val[0]) { ++ if (vfs && (vfs->dir || vfs->fsname || vfs->fsid != VNOVAL)) { ++ if (vfs->fsid != VNOVAL) { + + #if defined(HASPRINTDEV) +- dp = HASPRINTDEV(Lf, &dev); ++ dp = HASPRINTDEV(Lf, &vfs->fsid); + #else /* !defined(HASPRINTDEV) */ + (void) snpf(dbuf, sizeof(dbuf) - 1, "%d,%d", +- GET_MAJ_DEV(dev), GET_MIN_DEV(dev)); ++ GET_MAJ_DEV(vfs->fsid), GET_MIN_DEV(vfs->fsid)); + dbuf[sizeof(dbuf) - 1] = '\0'; + dp = dbuf; + #endif /* defined(HASPRINTDEV) */ +@@ -721,406 +483,40 @@ process_overlaid_node: + np = "(nullfs)"; + (void) add_nma(np, (int)strlen(np)); + } +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&nu, sizeof(nu))) { +- (void) snpf(Namech, Namechl, "can't read null_node at: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- if (!nu.null_lowervp) { +- (void) snpf(Namech, Namechl, "null_node overlays nothing"); +- enter_nm(Namech); +- return; +- } +- va = (KA_T)nu.null_lowervp; ++ fsid = VNOVAL; ++ /* -------dir-------- ++ * /nullfs_mountpoint/path/to/file ++ * /original_mountpoint/path/to/file ++ * ------fsname-------- ++ */ ++ memmove(&vfs_path[strlen(vfs->fsname) + 1], &vfs_path[strlen(vfs->dir) + 1], ++ strlen(vfs_path) - strlen(vfs->dir) + 1); ++ memcpy(vfs_path, vfs->fsname, strlen(vfs->fsname)); + goto process_overlaid_node; + #endif /* defined(HASNULLFS) */ + +-#if defined(HASPROCFS) +- case VT_PROCFS: +- +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&pb, sizeof(pb))) { +- (void) snpf(Namech, Namechl, "no pfs node: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- p = &pb; +- +- break; +-#endif /* defined(HASPROCFS) */ +- +-#if defined(HASPSEUDOFS) +- case VT_PSEUDOFS: +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&pn, sizeof(pn))) { +- (void) snpf(Namech, Namechl, "no pfs_node: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- pnp = &pn; +- break; +-#endif /* defined(HASPSEUDOFS) */ +- +-# if defined(HAS_TMPFS) +- case VT_TMPFS: +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&tn, sizeof(tn))) { +- (void) snpf(Namech, Namechl, "no tmpfs_node: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- tnp = &tn; +- break; +-# endif /* defined(HAS_TMPFS) */ +- +- case VT_UFS: +- +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&ib, sizeof(ib))) { +- (void) snpf(Namech, Namechl, "no ufs node: %s", +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- i = &ib; +- +-# if defined(HAS_UFS1_2) +- if (i->i_ump && !kread((KA_T)i->i_ump, (char *)&um, sizeof(um))) { +- ums = 1; +- if (um.um_fstype == UFS1) { +- if (i->i_din1 +- && !kread((KA_T)i->i_din1, (char *)&d1, sizeof(d1))) +- ufst = 1; +- } else { +- if (i->i_din2 +- && !kread((KA_T)i->i_din2, (char *)&d2, sizeof(d2))) +- ufst = 2; +- } +- } +-# endif /* defined(HAS_UFS1_2) */ +- +-#if defined(HAS_V_LOCKF) +- if (v->v_lockf) +- (void) get_lock_state((KA_T)v->v_lockf); +-#else /* !defined(HAS_V_LOCKF) */ +- if (i->i_lockf) +- (void) get_lock_state((KA_T)i->i_lockf); +-#endif /* defined(HAS_V_LOCKF) */ +- +- break; +- +-#if defined(HAS_ZFS) +- case VT_ZFS: +- memset((void *)&zi, 0, sizeof(zfs_info_t)); +- if (!v->v_data +- || (zm = readzfsnode((KA_T)v->v_data, &zi, +- ((v->v_vflag & VV_ROOT) ? 1 : 0))) +- ) { +- (void) snpf(Namech, Namechl, "%s: %s", zm, +- print_kptr((KA_T)v->v_data, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- z = &zi; +- +-#if defined(HAS_V_LOCKF) +- if (v->v_lockf) +- (void) get_lock_state((KA_T)v->v_lockf); +-#else /* !defined(HAS_V_LOCKF) */ +- if (z->lockf) +- (void) get_lock_state((KA_T)z->lockf); +-#endif /* defined(HAS_V_LOCKF) */ +- +- break; +-#endif /* defined(HAS_ZFS) */ +- +- default: +- if (v->v_type == VBAD || v->v_type == VNON) +- break; +- +- (void) snpf(Namech, Namechl, "unknown file system type: %s", vtbp); +- +- enter_nm(Namech); +- return; + } ++ + /* + * Get device and type for printing. + */ +- type = v->v_type; +- if (n) { +- dev = n->n_vattr.va_fsid; ++ if (fsid != VNOVAL) { ++ dev = fsid; + devs = 1; +- if ((type == VCHR) || (type == VBLK)) { +- rdev = n->n_vattr.va_rdev; +- rdevs = 1; +- } +- } else if (i) { +- +-# if defined(HAS_NO_IDEV) +- if (ums) { +- dev = Dev2Udev((KA_T)um.um_dev); +- devs = 1; +- } +-# else /* !defined(HAS_NO_IDEV) */ +- if (i->i_dev +- +-# if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) +- && !kread((KA_T)i->i_dev, (char *)&si, sizeof(si)) +-# endif/* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +- +- ) { +- +-# if defined(HAS_NO_SI_UDEV) +-# if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) +- dev = Dev2Udev((KA_T)i->i_dev); +-# else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +- dev = Dev2Udev(&si); +-# endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ +-# else /* !defined(HAS_NO_SI_UDEV) */ +- dev = si.si_udev; +-# endif /* defined(HAS_NO_SI_UDEV) */ +- +- devs = 1; +- } +-# endif /* defined(HAS_NO_IDEV) */ +- +- if ((type == VCHR) || (type == VBLK)) { +- +-# if defined(HAS_UFS1_2) +- if (ufst == 1) { +- rdev = d1.di_rdev; +- rdevs = 1; +- } else if (ufst == 2) { +- rdev = d2.di_rdev; +- rdevs = 1; +- } else +-# endif /* defined(HAS_UFS1_2) */ +- +- if (cds) { +- +-# if defined(HAS_NO_SI_UDEV) +-# if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) +- rdev = Dev2Udev((KA_T)v->v_rdev); +-# else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +- rdev = Dev2Udev(&cd); +-# endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ +-# else /* !defined(HAS_NO_SI_UDEV) */ +- rdev = cd.si_udev; +-# endif /* defined(HAS_NO_SI_UDEV) */ +- +- rdevs = 1; +- } +- } + } +- +-#if defined(HAS_ZFS) +- else if (z) { +- +- /* +- * Record information returned by readzfsnode(). +- */ +- if (vfs) { +- union { +- int32_t val[2]; +- dev_t dev; +- } vfs_fsid; +- +- vfs_fsid.val[0] = vfs->fsid.val[0]; +- vfs_fsid.val[1] = vfs->fsid.val[1]; +- dev = vfs_fsid.dev; +- devs = 1; +- } +- if ((type == VCHR) || (type == VBLK)) { +- if (z->rdev_def) { +- rdev = z->rdev; +- rdevs = 1; +- } +- } ++ if (kf_vtype == KF_VTYPE_VCHR || kf_vtype == KF_VTYPE_VBLK) { ++ rdev = kf->kf_un.kf_file.kf_file_rdev; ++ rdevs = 1; + } +-#endif /* defined(HAS_ZFS) */ + +-#if defined(HASFDESCFS) && (defined(HASFDLINK) || HASFDESCFS==1) +- else if (f) { +- +-# if defined(HASFDLINK) +- if (f->fd_link +- && kread((KA_T)f->fd_link, Namech, Namechl - 1) == 0) +- Namech[Namechl - 1] = '\0'; +- +-# if HASFDESCFS==1 +- else +-# endif /* HASFDESCFS==1 */ +-# endif /* defined(HASFDLINK) */ +- +-# if HASFDESCFS==1 +- if (f->fd_type == Fctty) { +- if (f_tty_s == 0) +- f_tty_s = lkup_dev_tty(&f_tty_dev, &f_tty_ino); +- if (f_tty_s == 1) { +- dev = f_tty_dev; +- Lf->inode = f_tty_ino; +- devs = Lf->inp_ty = 1; +- } +- } +-# endif /* HASFDESCFS==1 */ +- +- } +-#endif /* defined(HASFDESCFS) && (defined(HASFDLINK) || HASFDESCFS==1) */ +- +-#if defined(HAS9660FS) +- else if (iso_stat && iso_dev_def) { +- dev = iso_dev; +- devs = Lf->inp_ty = 1; +- } +-#endif /* defined(HAS9660FS) */ +- +-#if defined(HASFUSEFS) +- else if (fuse_stat && fuse_dev_def) { +- dev = fuse_dev; +- devs = Lf->inp_ty = 1; +- } +-#endif /* defined(HASFUSEFS) */ +- +-#if defined(HASMSDOSFS) +- else if (msdos_stat && msdos_dev_def) { +- dev = msdos_dev; +- devs = Lf->inp_ty = 1; +- } +-#endif /* defined(HASMSDOSFS) */ +- +- else if (d) { +- if (vfs) { +- dev = vfs->fsid.val[0]; +- devs = 1; +- } else { +- dev = DevDev; +- devs = 1; +- } +- if (type == VCHR) { +- +-# if defined(HAS_UFS1_2) +- if (ufst == 1) { +- rdev = d1.di_rdev; +- rdevs = 1; +- } else if (ufst == 2) { +- rdev = d2.di_rdev; +- rdevs = 1; +- } else +-# endif /* defined(HAS_UFS1_2) */ +- +- if (cds) { +- +-# if defined(HAS_NO_SI_UDEV) +-# if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) +- rdev = Dev2Udev((KA_T)v->v_rdev); +-# else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +- rdev = Dev2Udev(&cd); +-# endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ +-# else /* !defined(HAS_NO_SI_UDEV) */ +- rdev = cd.si_udev; +-# endif /* defined(HAS_NO_SI_UDEV) */ +- +- rdevs = 1; +- } +- } +- } +- +-#if defined(HASPSEUDOFS) +- else if (pnp) { +- if (vfs) { +- dev = vfs->fsid.val[0]; +- devs = 1; +- } +- } +-#endif /* defined(HASPSEUDOFS) */ +- +-# if defined(HAS_TMPFS) +- else if (tnp) { +- if (vfs) { +- dev = vfs->fsid.val[0]; +- devs = 1; +- } +- if (tnp->tn_type == VBLK || tnp->tn_type == VCHR) { +- rdev = tnp->tn_rdev; +- rdevs = 1; +- } +- } +-# endif /* defined(HAS_TMPFS) */ +- + /* + * Obtain the inode number. + */ +- if (i) { +- Lf->inode = (INODETYPE)i->i_number; ++ if (kf->kf_un.kf_file.kf_file_fileid != VNOVAL) { ++ Lf->inode = kf->kf_un.kf_file.kf_file_fileid; + Lf->inp_ty = 1; + } + +-#if defined(HAS_ZFS) +- else if (z) { +- if (z->ino_def) { +- Lf->inode = z->ino; +- Lf->inp_ty = 1; +- } +- } +-#endif /* defined(HAS_ZFS) */ +- +- else if (n) { +- Lf->inode = (INODETYPE)n->n_vattr.va_fileid; +- Lf->inp_ty = 1; +- } +- +-#if defined(HAS9660FS) +- else if (iso_stat) { +- Lf->inode = iso_ino; +- Lf->inp_ty = 1; +- } +-#endif /* defined(HAS9660FS) */ +- +-#if defined(HASFUSEFS) +- else if (fuse_stat) { +- Lf->inode = fuse_ino; +- Lf->inp_ty = 1; +- } +-#endif /* defined(HASFUSEFS) */ +- +-#if defined(HASMSDOSFS) +- else if (msdos_stat) { +- Lf->inode = msdos_ino; +- Lf->inp_ty = 1; +- } +-#endif /* defined(HASMSDOSFS) */ +- +-#if defined(HASPROCFS) +- else if (p) { +- Lf->inode = (INODETYPE)p->pfs_fileno; +- Lf->inp_ty = 1; +- } +-#endif /* defined(HASPROCFS) */ +- +-#if defined(HASPSEUDOFS) +- else if (pnp) { +- Lf->inode = (INODETYPE)pnp->pn_fileno; +- Lf->inp_ty = 1; +- } +-#endif /* defined(HASPSEUDOFS) */ +- +- else if (d) { +- Lf->inode = (INODETYPE)d->de_inode; +- Lf->inp_ty = 1; +- } +- +-# if defined(HAS_TMPFS) +- else if (tnp) { +- Lf->inode = (INODETYPE)tnp->tn_id; +- Lf->inp_ty = 1; +- } +-# endif /* defined(HAS_TMPFS) */ +- + /* + * Obtain the file size. + */ +@@ -1132,189 +528,40 @@ process_overlaid_node: + if (!Fsize) + Lf->off_def = 1; + break; +- case N_NFS: +- if (n) { +- Lf->sz = (SZOFFTYPE)n->n_vattr.va_size; +- Lf->sz_def = 1; +- } +- break; +- +-#if defined(HASPROCFS) + case N_PROC: +- +- if (p) { +- switch(p->pfs_type) { +- case Proot: +- case Pproc: +- Lf->sz = (SZOFFTYPE)DEV_BSIZE; +- Lf->sz_def = 1; +- break; +- case Pmem: +- (void) getmemsz(p->pfs_pid); +- break; +- case Pregs: +- Lf->sz = (SZOFFTYPE)sizeof(struct reg); +- Lf->sz_def = 1; +- break; +- case Pfpregs: +- Lf->sz = (SZOFFTYPE)sizeof(struct fpreg); +- Lf->sz_def = 1; +- break; +- } +- } +-#endif /* defined(HASPROCFS) */ +- ++ Lf->sz = kf->kf_un.kf_file.kf_file_size; ++ Lf->sz_def = 1; ++ break; + #if defined(HASPSEUDOFS) + case N_PSEU: + Lf->sz = 0; + Lf->sz_def = 1; + break; + #endif /* defined(PSEUDOFS) */ +- + case N_REGLR: +- if (type == VREG || type == VDIR) { +- if (i) { +- +-#if defined(HAS_UFS1_2) +- if (ufst == 1) +- Lf->sz = (SZOFFTYPE)d1.di_size; +- else if (ufst == 2) +- Lf->sz = (SZOFFTYPE)d2.di_size; +- else +-#endif /* defined(HAS_UFS1_2) */ +- +- Lf->sz = (SZOFFTYPE)i->i_size; +- Lf->sz_def = 1; +- } +- +- +-#if defined(HAS_ZFS) +- else if (z) { +- if (z->sz_def) { +- Lf->sz = z->sz; +- Lf->sz_def = 1; +- } +- } +-#endif /* defined(HAS_ZFS) */ +- +-#if defined(HAS9660FS) +- else if (iso_stat) { +- Lf->sz = (SZOFFTYPE)iso_sz; +- Lf->sz_def = 1; +- } +- +-#endif /* defined(HAS9660FS) */ +- +-#if defined(HASFUSEFS) +- else if (fuse_stat) { +- Lf->sz = (SZOFFTYPE)fuse_sz; +- Lf->sz_def = 1; +- } +-#endif /* defined(HASFUSEFS) */ +- +-#if defined(HASMSDOSFS) +- else if (msdos_stat) { +- Lf->sz = (SZOFFTYPE)msdos_sz; +- Lf->sz_def = 1; +- } +-#endif /* defined(HASMSDOSFS) */ +- } +- else if ((type == VCHR || type == VBLK) && !Fsize) +- Lf->off_def = 1; +- break; +- + # if defined(HAS_TMPFS) +- case N_TMP: +- if ((tnp->tn_type == VBLK || tnp->tn_type == VCHR) +- && !Fsize) { +- Lf->off_def = 1; +- } else { +- Lf->sz = (SZOFFTYPE)tnp->tn_size; +- Lf->sz_def = 1; +- } +- break; ++ case N_TMP: + # endif /* defined(HAS_TMPFS) */ +- ++ if (kf_vtype == KF_VTYPE_VREG || kf_vtype == KF_VTYPE_VDIR) { ++ Lf->sz = kf->kf_un.kf_file.kf_file_size; ++ Lf->sz_def = 1; ++ } else if ((kf_vtype == KF_VTYPE_VCHR || kf_vtype == KF_VTYPE_VBLK) && !Fsize) { ++ Lf->off_def = 1; ++ } ++ break; ++ default: ++ Lf->sz = kf->kf_un.kf_file.kf_file_size; ++ Lf->sz_def = 1; + } + } + /* + * Record the link count. + */ + if (Fnlink) { +- switch(Ntype) { +- case N_NFS: +- if (n) { +- Lf->nlink = (long)n->n_vattr.va_nlink; +- Lf->nlink_def = 1; +- } +- break; +- case N_REGLR: +- if (i) { +- +-#if defined(HASEFFNLINK) +- Lf->nlink = (long)i->HASEFFNLINK; +-#else /* !defined(HASEFFNLINK) */ +- Lf->nlink = (long)i->i_nlink; +-#endif /* defined(HASEFFNLINK) */ +- +- Lf->nlink_def = 1; +- } +- +-#if defined(HAS_ZFS) +- else if (z) { +- if (z->nl_def) { +- Lf->nlink = z->nl; +- Lf->nlink_def = 1; +- } +- } +-#endif /* defined(HAS_ZFS) */ +- +-#if defined(HAS9660FS) +- else if (iso_stat) { +- Lf->nlink = iso_links; +- Lf->nlink_def = 1; +- } +-#endif /* defined(HAS9660FS) */ +- +-#if defined(HASFUSEFS) +- else if (fuse_stat) { +- Lf->nlink = fuse_links; +- Lf->nlink_def = 1; +- } +-#endif /* defined(HASFUSEFS) */ +- +-#if defined(HASMSDOSFS) +- else if (msdos_stat) { +- Lf->nlink = msdos_links; +- Lf->nlink_def = 1; +- } +-#endif /* defined(HASMSDOSFS) */ +- +- else if (d) { +- Lf->nlink = d->de_links; +- Lf->nlink_def = 1; +- } +- +- break; +- +-#if defined(HASPSEUODOFS) +- case N_PSEU: +- if (pnp) { +- Lf->nlink = 1L; +- Lf->nlink_def = 1; +- } +- break; +-#endif /* defined(HASPSEUODOFS) */ +- +-# if defined(HAS_TMPFS) +- case N_TMP: +- if (tnp) { +- Lf->nlink = (long)tnp->tn_links; +- Lf->nlink_def = 1; +- } +- break; +-# endif /* defined(HAS_TMPFS) */ +- ++ /* FIXME: the kernel could provide this from the inode, without us needing a separate stat call */ ++ if (kf->kf_path[0] && stat(kf->kf_path, &st) == 0) { ++ Lf->nlink = st.st_nlink; ++ Lf->nlink_def = 1; + } + if (Lf->nlink_def && Nlink && (Lf->nlink < Nlink)) + Lf->sf |= SELNLINK; +@@ -1340,40 +587,36 @@ process_overlaid_node: + Lf->dev_def = devs; + Lf->rdev = rdev; + Lf->rdev_def = rdevs; +- switch (type) { +- case VNON: ++ switch (kf_vtype) { ++ case KF_VTYPE_VNON: + ty ="VNON"; + break; +- case VREG: +- case VDIR: +- ty = (type == VREG) ? "VREG" : "VDIR"; ++ case KF_VTYPE_VREG: ++ case KF_VTYPE_VDIR: ++ ty = (kf_vtype == KF_VTYPE_VREG) ? "VREG" : "VDIR"; + break; +- case VBLK: ++ case KF_VTYPE_VBLK: + ty = "VBLK"; + Ntype = N_BLK; + break; +- case VCHR: ++ case KF_VTYPE_VCHR: + ty = "VCHR"; + Ntype = N_CHR; + break; +- case VLNK: ++ case KF_VTYPE_VLNK: + ty = "VLNK"; + break; +- +-#if defined(VSOCK) +- case VSOCK: ++ case KF_VTYPE_VSOCK: + ty = "SOCK"; + break; +-#endif /* defined(VSOCK) */ +- +- case VBAD: ++ case KF_VTYPE_VBAD: + ty = "VBAD"; + break; +- case VFIFO: ++ case KF_VTYPE_VFIFO: + ty = "FIFO"; + break; + default: +- (void) snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff)); ++ (void) snpf(Lf->type, sizeof(Lf->type), "%04o", (kf_vtype & 0xfff)); + ty = (char *)NULL; + } + if (ty) +@@ -1387,90 +630,21 @@ process_overlaid_node: + * /proc files. + */ + +- if (type == VBAD) ++ if (kf_vtype == KF_VTYPE_VBAD) + (void) snpf(Namech, Namechl, "(revoked)"); + +-#if defined(HASPROCFS) +- else if (p) { +- Lf->dev_def = Lf->rdev_def = 0; +- +- ty = (char *)NULL; +- (void) snpf(Namech, Namechl, "/%s", HASPROCFS); +- switch (p->pfs_type) { +- case Proot: +- ty = "PDIR"; +- break; +- case Pproc: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d", p->pfs_pid); +- ty = "PDIR"; +- break; +- case Pfile: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/file", p->pfs_pid); +- ty = "PFIL"; +- break; +- case Pmem: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/mem", p->pfs_pid); +- ty = "PMEM"; +- break; +- case Pregs: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/regs", p->pfs_pid); +- ty = "PREG"; +- break; +- case Pfpregs: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/fpregs", p->pfs_pid); +- ty = "PFPR"; +- break; +- case Pctl: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/ctl", p->pfs_pid); +- ty = "PCTL"; +- break; +- case Pstatus: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/status", p->pfs_pid); +- ty = "PSTA"; +- break; +- case Pnote: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/note", p->pfs_pid); +- ty = "PNTF"; +- break; +- case Pnotepg: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/notepg", p->pfs_pid); +- ty = "PGID"; +- break; +- +- case Pmap: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/map", p->pfs_pid); +- ty = "PMAP"; +- break; +- case Ptype: +- ep = endnm(&sz); +- (void) snpf(ep, sz, "/%d/etype", p->pfs_pid); +- ty = "PETY"; +- break; +- +- } ++ else if (Ntype == N_PROC) { ++ ty = parse_proc_path(kf, &proc_pid); + if (ty) + (void) snpf(Lf->type, sizeof(Lf->type), "%s", ty); +- enter_nm(Namech); +- + } +-#endif /* defined(HASPROCFS) */ + + #if defined(HASBLKDEV) + /* + * If this is a VBLK file and it's missing an inode number, try to + * supply one. + */ +- if ((Lf->inp_ty == 0) && (type == VBLK)) ++ if ((Lf->inp_ty == 0) && (kf_vtype == KF_VTYPE_VBLK)) + find_bl_ino(); + #endif /* defined(HASBLKDEV) */ + +@@ -1478,20 +652,19 @@ process_overlaid_node: + * If this is a VCHR file and it's missing an inode number, try to + * supply one. + */ +- if ((Lf->inp_ty == 0) && (type == VCHR)) ++ if ((Lf->inp_ty == 0) && (kf_vtype == KF_VTYPE_VCHR)) + find_ch_ino(); + /* + * Test for specified file. + */ + +-#if defined(HASPROCFS) +- if (Ntype == N_PROC) { ++ if (Ntype == N_PROC && (Procsrch || Procfsid)) { + if (Procsrch) { + Procfind = 1; + Lf->sf |= SELNM; + } else { + for (pfi = Procfsid; pfi; pfi = pfi->next) { +- if ((pfi->pid && pfi->pid == p->pfs_pid) ++ if ((pfi->pid && proc_pid && pfi->pid == proc_pid) + + # if defined(HASPINODEN) + || (Lf->inp_ty == 1 && Lf->inode == pfi->inode) +@@ -1508,12 +681,9 @@ process_overlaid_node: + } + } + } +- } else +-#endif /* defined(HASPROCFS) */ +- +- { ++ } else { + if (Sfile && is_file_named((char *)NULL, +- ((type == VCHR) || (type == VBLK)) ? 1 ++ ((kf_vtype == KF_VTYPE_VCHR) || (kf_vtype == KF_VTYPE_VBLK)) ? 1 + : 0)) + Lf->sf |= SELNM; + } +@@ -1522,6 +692,16 @@ process_overlaid_node: + */ + if (Namech[0]) + enter_nm(Namech); ++ else if (kf->kf_path[0]) { ++ snpf(Namech, Namechl, "%s", kf->kf_path); ++ if (vfs && vfs->fsname) { ++ char *cp; ++ size_t sz; ++ cp = endnm(&sz); ++ snpf(cp, sz, " (%s)", vfs->fsname); ++ } ++ enter_nm(Namech); ++ } + } + + +@@ -1530,47 +710,61 @@ void + */ + + void +-process_pipe(pa) +- KA_T pa; /* pipe structure address */ ++process_pipe(struct kinfo_file *kf, KA_T pa) + { + char dev_ch[32], *ep; +- struct pipe p; + size_t sz; + +- if (!pa || kread(pa, (char *)&p, sizeof(p))) { +- (void) snpf(Namech, Namechl, +- "can't read DTYPE_PIPE pipe struct: %s", +- print_kptr((KA_T)pa, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } ++#if __FreeBSD_version < 1400052 ++ struct pipe p; ++ int have_kpipe = (pa && kread(pa, (char *)&p, sizeof(p)) == 0); ++#endif ++ + (void) snpf(Lf->type, sizeof(Lf->type), "PIPE"); + (void) snpf(dev_ch, sizeof(dev_ch), "%s", +- print_kptr(pa, (char *)NULL, 0)); ++ print_kptr(kf->kf_un.kf_pipe.kf_pipe_addr, (char *)NULL, 0)); + enter_dev_ch(dev_ch); + if (Foffset) + Lf->off_def = 1; + else { +- Lf->sz = (SZOFFTYPE)p.pipe_buffer.size; ++#if __FreeBSD_version >= 1400052 ++ Lf->sz = (SZOFFTYPE)kf->kf_un.kf_pipe.kf_pipe_buffer_size; + Lf->sz_def = 1; ++#else /* __FreeBSD_version < 1400052 */ ++ if (have_kpipe) { ++ Lf->sz = (SZOFFTYPE)p.pipe_buffer.size; ++ Lf->sz_def = 1; ++ } ++#endif /* __FreeBSD_version >= 1400052 */ + } +- if (p.pipe_peer) ++ if (kf->kf_un.kf_pipe.kf_pipe_peer) + (void) snpf(Namech, Namechl, "->%s", +- print_kptr((KA_T)p.pipe_peer, (char *)NULL, 0)); ++ print_kptr((KA_T)kf->kf_un.kf_pipe.kf_pipe_peer, (char *)NULL, 0)); + else + Namech[0] = '\0'; +- if (p.pipe_buffer.cnt) { ++ if (kf->kf_un.kf_pipe.kf_pipe_buffer_cnt) { + ep = endnm(&sz); +- (void) snpf(ep, sz, ", cnt=%d", p.pipe_buffer.cnt); ++ (void) snpf(ep, sz, ", cnt=%d", kf->kf_un.kf_pipe.kf_pipe_buffer_cnt); + } +- if (p.pipe_buffer.in) { ++#if __FreeBSD_version >= 1400052 ++ if (kf->kf_un.kf_pipe.kf_pipe_buffer_in) { + ep = endnm(&sz); ++ (void) snpf(ep, sz, ", in=%d", kf->kf_un.kf_pipe.kf_pipe_buffer_in); ++ } ++ if (kf->kf_un.kf_pipe.kf_pipe_buffer_out) { ++ ep = endnm(&sz); ++ (void) snpf(ep, sz, ", out=%d", kf->kf_un.kf_pipe.kf_pipe_buffer_out); ++ } ++#else /* __FreeBSD_version < 1400052 */ ++ if (have_kpipe && p.pipe_buffer.in) { ++ ep = endnm(&sz); + (void) snpf(ep, sz, ", in=%d", p.pipe_buffer.in); + } +- if (p.pipe_buffer.out) { ++ if (have_kpipe && p.pipe_buffer.out) { + ep = endnm(&sz); + (void) snpf(ep, sz, ", out=%d", p.pipe_buffer.out); + } ++#endif /* __FreeBSD_version >= 1400052 */ + /* + * Enter name characters. + */ +@@ -1579,30 +773,17 @@ process_pipe(pa) + } + + +-#if defined(HASPTSFN) && defined(DTYPE_PTS) ++#if defined(DTYPE_PTS) + /* + * process_pts - process a file structure whose type is DTYPE_PTS + */ + +-void process_pts(tp) +- KA_T tp; /* f_data pointer to tty structure */ ++void process_pts(struct kinfo_file *kf) + { +- dev_t dev; /* IFCHR device number */ +- struct tty t; /* tty structure */ +- + (void) snpf(Lf->type, sizeof(Lf->type), "PTS"); + /* +- * Read the tty structure. Quit if it can't be read. +- */ +- if (!tp || kread(tp, (char *)&t, sizeof(t))) { +- (void) snpf(Namech, Namechl, +- "can't read DTYPE_PTS tty struct: %s", +- print_kptr((KA_T)tp, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +-/* + * Convert the tty's cdev from kernel to user form. ++ * -- already done in the kernel, file sys/kern/tty_pts.c, function ptsdev_fill_kinfo(). + * + * Set the device number to DevDev, the device number of /dev. + * +@@ -1616,19 +797,12 @@ void process_pts(tp) + * + * Force the reloading of the device cache. + */ +- if ((dev = Dev2Udev((KA_T)t.t_dev)) == NODEV) { +- (void) snpf(Namech, Namechl, +- "can't convert device in DTYPE_PTS tty struct: %s", +- print_kptr((KA_T)tp, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } + Lf->dev = DevDev; +- Lf->inode = (INODETYPE)dev; ++ Lf->inode = (INODETYPE)kf->kf_un.kf_pts.kf_pts_dev; + Lf->inp_ty = Lf->dev_def = Lf->rdev_def = 1; + Lf->ntype = N_CHR; + Lf->off_def = 1; +- Lf->rdev = dev; ++ Lf->rdev = kf->kf_un.kf_pts.kf_pts_dev; + DCunsafe = 1; + } +-#endif /* defined(HASPTSFN) && defined(DTYPE_PTS) */ ++#endif /* defined(DTYPE_PTS) */ diff --git a/sysutils/lsof/files/patch-dialects_freebsd_dnode1.c b/sysutils/lsof/files/patch-dialects_freebsd_dnode1.c new file mode 100644 index 000000000000..8ed35828e5e2 --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_dnode1.c @@ -0,0 +1,234 @@ +--- dialects/freebsd/dnode1.c.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/dnode1.c +@@ -1,231 +0,0 @@ +-/* +- * dnode1.c - FreeBSD node functions for lsof +- * +- * This module must be separate to keep separate the multiple kernel inode +- * structure definitions. +- */ +- +- +-/* +- * Copyright 1995 Purdue Research Foundation, West Lafayette, Indiana +- * 47907. All rights reserved. +- * +- * Written by Victor A. Abell +- * +- * This software is not subject to any license of the American Telephone +- * and Telegraph Company or the Regents of the University of California. +- * +- * Permission is granted to anyone to use this software for any purpose on +- * any computer system, and to alter it and redistribute it freely, subject +- * to the following restrictions: +- * +- * 1. Neither the authors nor Purdue University are responsible for any +- * consequences of the use of this software. +- * +- * 2. The origin of this software must not be misrepresented, either by +- * explicit claim or by omission. Credit to the authors and Purdue +- * University must appear in documentation and sources. +- * +- * 3. Altered versions must be plainly marked as such, and must not be +- * misrepresented as being the original software. +- * +- * 4. This notice may not be removed or altered. +- */ +- +-#ifndef lint +-static char copyright[] = +-"@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n"; +-#endif +- +- +-#include "lsof.h" +- +-#if defined(HAS9660FS) +- +-/* +- * Do a little preparation for #include'ing cd9660_node.h, then #include it. +- */ +- +-#undef i_size +-#undef doff_t +-#undef IN_ACCESS +- +-# if defined(__alpha__) +-#define dev_t void * +-# endif /* defined(__alpha__) */ +- +-# if defined(HAS_NO_ISO_DEV) +-#define _KERNEL +-#include +-#undef _KERNEL +-# endif /* defined(HAS_NO_ISO_DEV) */ +- +-#include "cd9660_node.h" +- +-# if defined(__alpha__) +-#undef dev_t +-# endif /* defined(__alpha__) */ +- +- +-/* +- * read_iso_node() -- read CD 9660 iso_node +- */ +- +-int +-read_iso_node(v, d, dd, ino, nl, sz) +- struct vnode *v; /* containing vnode */ +- dev_t *d; /* returned device number */ +- int *dd; /* returned device-defined flag */ +- INODETYPE *ino; /* returned inode number */ +- long *nl; /* returned number of links */ +- SZOFFTYPE *sz; /* returned size */ +-{ +- +- struct iso_node i; +- +- struct cdev udev; +-# if defined(HAS_NO_ISO_DEV) +- struct iso_mnt im; +-# endif /* defined(HAS_NO_ISO_DEV) */ +- +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&i, sizeof(i))) +- return(1); +- +-# if defined(HAS_NO_ISO_DEV) +- if (i.i_mnt && !kread((KA_T)i.i_mnt, (char *)&im, sizeof(im)) +- && im.im_dev && !kread((KA_T)im.im_dev, (char *)&udev, sizeof(udev))) +-# else /* !defined(HAS_NO_ISO_DEV) */ +- if (i.i_dev && !kread((KA_T)i.i_dev, (char *)&udev, sizeof(udev))) +-# endif /* defined(HAS_NO_ISO_DEV) */ +- +- { +- +-# if defined(HAS_NO_SI_UDEV) +-# if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) +- *d = Dev2Udev((KA_T)im.im_dev); +-# else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +- *d = Dev2Udev(&udev); +-# endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ +-# else /* !defined(HAS_NO_SI_UDEV) */ +- *d = udev.si_udev; +-# endif /* defined(HAS_NO_SI_UDEV) */ +- +- *dd = 1; +- } +- +- *ino = (INODETYPE)i.i_number; +- *nl = (long)i.inode.iso_links; +- *sz = (SZOFFTYPE)i.i_size; +- +- return(0); +-} +-#endif /* defined(HAS9660FS) */ +- +- +-#if defined(HASFUSEFS) +-#undef VTOI +-#include +-/* +- * read_fuse_node() -- read FUSE file system fuse_node +- */ +- +-int +-read_fuse_node(v, d, dd, ino, nl, sz) +- struct vnode *v; /* containing vnode */ +- dev_t *d; /* returned device number */ +- int *dd; /* returned device-defined flag */ +- INODETYPE *ino; /* returned inode number */ +- long *nl; /* returned number of links */ +- SZOFFTYPE *sz; /* returned size */ +-{ +- struct fuse_vnode_data fn; /* FUSE node */ +- +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&fn, sizeof(fn))) +- return(1); +- *d = fn.cached_attrs.va_fsid; +- *dd = 1; +- *ino = (INODETYPE)fn.cached_attrs.va_fileid; +- *nl = (long)fn.cached_attrs.va_nlink; +- *sz = (SZOFFTYPE)fn.cached_attrs.va_size; +- return(0); +-} +-#endif /* defined(HASFUSEFS) */ +- +- +-#if defined(HASMSDOSFS) +-#include +-#include +-#include +-#include +-#define _KERNEL +-#include +-#undef _KERNEL +-/* +- * read_msdosfs_node() -- read msdos file system denode +- */ +- +-int +-read_msdos_node(v, d, dd, ino, nl, sz) +- struct vnode *v; /* containing vnode */ +- dev_t *d; /* returned device number */ +- int *dd; /* returned device-defined flag */ +- INODETYPE *ino; /* returned inode number */ +- long *nl; /* returned number of links */ +- SZOFFTYPE *sz; /* returned size */ +-{ +- struct denode dep; /* MSDOSFS node */ +- struct msdosfsmount pmp; +- struct cdev udev; +- typedef __uint64_t uoff_t; +- uint64_t fileid; +- u_long dirsperblk; +- +- if (!v->v_data +- || kread((KA_T)v->v_data, (char *)&dep, sizeof(dep))) +- return(1); +- if (!dep.de_pmp || kread((KA_T)dep.de_pmp, (char *)&pmp, sizeof(pmp))) +- return(1); +- +-# if defined(HAS_NO_SI_UDEV) +-# if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) +- *d = Dev2Udev((KA_T)pmp.pm_dev); +-# else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +- if (!pmp.pm_dev || kread((KA_T)pmp.pm_dev, (char *)&udev, sizeof(udev))) +- return(1); +- *d = Dev2Udev(&udev); +-# endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ +-# else /* !defined(HAS_NO_SI_UDEV) */ +- if (!pmp.pm_dev || kread((KA_T)pmp.pm_dev, (char *)&udev, sizeof(udev))) +- return(1); +- *d = udev.si_udev; +-# endif /* defined(HAS_NO_SI_UDEV) */ +- +- +- dirsperblk = pmp.pm_BytesPerSec / sizeof(struct direntry); +- /* +- * The following computation of the fileid must be the same as that +- * used in msdosfs_readdir() to compute d_fileno. If not, pwd +- * doesn't work. +- */ +- if (dep.de_Attributes & ATTR_DIRECTORY) { +- fileid = (uint64_t)cntobn(&pmp, dep.de_StartCluster) * +- dirsperblk; +- if (dep.de_StartCluster == MSDOSFSROOT) +- fileid = 1; +- } else { +- fileid = (uint64_t)cntobn(&pmp, dep.de_dirclust) * +- dirsperblk; +- if (dep.de_dirclust == MSDOSFSROOT) +- fileid = (uint64_t)roottobn(&pmp, 0) * dirsperblk; +- fileid += (uoff_t)dep.de_diroffset / sizeof(struct direntry); +- } +- +- *dd = 1; +- *ino = (INODETYPE)fileid; +- *nl = 1; +- *sz = dep.de_FileSize; +- return(0); +-} +-#endif /* defined(HASMSDOSFS) */ diff --git a/sysutils/lsof/files/patch-dialects_freebsd_dnode2.c b/sysutils/lsof/files/patch-dialects_freebsd_dnode2.c new file mode 100644 index 000000000000..988336590c0b --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_dnode2.c @@ -0,0 +1,161 @@ +--- dialects/freebsd/dnode2.c.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/dnode2.c +@@ -1,158 +0,0 @@ +-/* +- * dnode2.c - FreeBSD ZFS node functions for lsof +- * +- * This module must be separate to permit use of the OpenSolaris ZFS header +- * files. +- */ +- +- +-/* +- * Copyright 2008 Purdue Research Foundation, West Lafayette, Indiana +- * 47907. All rights reserved. +- * +- * Written by Victor A. Abell +- * +- * This software is not subject to any license of the American Telephone +- * and Telegraph Company or the Regents of the University of California. +- * +- * Permission is granted to anyone to use this software for any purpose on +- * any computer system, and to alter it and redistribute it freely, subject +- * to the following restrictions: +- * +- * 1. Neither the authors nor Purdue University are responsible for any +- * consequences of the use of this software. +- * +- * 2. The origin of this software must not be misrepresented, either by +- * explicit claim or by omission. Credit to the authors and Purdue +- * University must appear in documentation and sources. +- * +- * 3. Altered versions must be plainly marked as such, and must not be +- * misrepresented as being the original software. +- * +- * 4. This notice may not be removed or altered. +- */ +- +-#ifndef lint +-static char copyright[] = +-"@(#) Copyright 2008 Purdue Research Foundation.\nAll rights reserved.\n"; +-#endif +- +- +-#if defined(HAS_ZFS) +- +-#define _KERNEL +- +-# if defined(__clang__) +-/* +- * A clang workaround... +- * +- * Note: clang's complaint about VOP_FSYNC can't be avoided. +- */ +-#include +-#if __FreeBSD_version >= 1300074 +-#define VOP_UNLOCK_FLAGS(vp, f) ((void)0) +-#define VOP_UNLOCK(vp) ((void)0) +-#else +-#define VOP_UNLOCK(vp, f) ((void)0) +-#endif +-# endif /* defined(__clang__) */ +- +-#define KLD_MODULE /* for ARM: prevent "ARM_NARCH is 0 " error */ +-#include +-#undef _KERNEL +- +-#include "dzfs.h" +- +- +-/* +- * readzfsnode() -- read the ZFS node +- */ +- +-char * +-readzfsnode(za, zi, vr) +- KA_T za; /* ZFS node address */ +- zfs_info_t *zi; /* return ZFS info structure pointer */ +- int vr; /* vnode's (v_flag & VROOT) */ +-{ +- struct znode zn; /* ZFS node */ +- +-# if defined(HAS_Z_PHYS) +- znode_phys_t zp; /* ZFS physical node */ +-# else /* !defined(HAS_Z_PHYS) */ +- KA_T ka; /* temporary kernel address */ +- zfsvfs_t zv; /* znode's zfsvfs structure */ +-# endif /* defined(HAS_Z_PHYS) */ +- +- if (!za +- || kread(za, (char *)&zn, sizeof(zn)) +- ) { +- if (!za) +- return("No ZFS node address"); +- return("Can't read znode"); +- } +-/* +- * Return items contained in the znode. +- */ +- zi->ino = (INODETYPE)zn.z_id; +- zi->ino_def = 1; +- +-# if !defined(HAS_V_LOCKF) +- zi->lockf = (KA_T)zn.z_lockf; +-# endif /* !defined(HAS_V_LOCKF) */ +- +-# if defined(HAS_Z_PHYS) +-/* +- * If the physical znode exists in this ZFS implementation, read it. +- */ +- if (!zn.z_phys +- || kread((KA_T)zn.z_phys, (char *)&zp, sizeof(zp)) +- ) { +- if (!zn.z_phys) +- return("No physical znode address"); +- return("Can't read physical znode"); +- } +-/* +- * Return items contained in the physical znode. +- */ +- zi->nl = (long)zp.zp_links; +- zi->rdev = zp.zp_rdev; +- zi->sz = (SZOFFTYPE)zp.zp_size; +- zi->nl_def = zi->rdev_def = zi->sz_def = 1; +-# else /* !defined(HAS_Z_PHYS) */ +-/* +- * If this implementation has no physical znode, return items now contained +- * in the znode. +- */ +- zi->nl = (long)zn.z_links; +- if (vr && (ka = (KA_T)zn.z_zfsvfs)) { +- if (!kread(ka, (char *)&zv, sizeof(zv))) { +- if ((zn.z_id == zv.z_root) +- && (zv.z_ctldir != NULL) +- && (zv.z_show_ctldir) +- ) { +- zi->nl++; +- } +- } +- } +- zi->sz = (SZOFFTYPE)zn.z_size; +- zi->nl_def = zi->sz_def = 1; +-# endif /* defined(HAS_Z_PHYS) */ +- +- return((char *)NULL); +-} +- +- +- +- +-# if defined(__GNUC__) && defined(HAS_CV_TIMEDWAIT_SBT) +-/* +- * A gcc work-around +- */ +- +-int _cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock, +- sbintime_t sbt, sbintime_t pr, int flags) +-{ +- return(0); +-} +-# endif /* defined(__GNUC__) && HAS_CV_TIMEDWAIT_SBT */ +-#endif /* defined(HAS_ZFS) */ diff --git a/sysutils/lsof/files/patch-dialects_freebsd_dproc.c b/sysutils/lsof/files/patch-dialects_freebsd_dproc.c new file mode 100644 index 000000000000..44d2a6f96ae7 --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_dproc.c @@ -0,0 +1,713 @@ +--- dialects/freebsd/dproc.c.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/dproc.c +@@ -45,65 +45,227 @@ static char copyright[] = + #define HAS_PWD + #endif + +-_PROTOTYPE(static void enter_vn_text,(KA_T va, int *n)); + _PROTOTYPE(static void get_kernel_access,(void)); +-_PROTOTYPE(static void process_text,(KA_T vm)); + + + /* + * Local static values + */ + +-static MALLOC_S Nv = 0; /* allocated Vp[] entries */ +-static KA_T *Vp = NULL; /* vnode address cache */ ++static int ++cmp_xfiles_pid_fd(const void *a, const void *b) ++{ ++ const struct xfile *aa, *bb; + ++ aa = (struct xfile *)a; ++ bb = (struct xfile *)b; ++ if (aa->xf_pid < bb->xf_pid) { ++ return -1; ++ } else if (aa->xf_pid > bb->xf_pid) { ++ return 1; ++ } else { ++ if (aa->xf_fd < bb->xf_fd) { ++ return -1; ++ } else if (aa->xf_fd > bb->xf_fd) { ++ return 1; ++ } else { ++ return 0; ++ } ++ } ++} + +-/* +- * enter_vn_text() - enter a vnode text reference +- */ ++static int ++read_xfiles(struct xfile **xfiles, size_t *count) ++{ ++ int mib[2]; ++ size_t len; + +-static void +-enter_vn_text(va, n) +- KA_T va; /* vnode address */ +- int *n; /* Vp[] entries in use */ ++ mib[0] = CTL_KERN; ++ mib[1] = KERN_FILE; ++ *xfiles = NULL; ++ if (!sysctl(mib, 2, NULL, &len, NULL, 0)) { ++ *xfiles = malloc(len); ++ if (*xfiles) { ++ if (!sysctl(mib, 2, *xfiles, &len, NULL, 0)) { ++ *count = len / sizeof(struct xfile); ++ return 0; ++ } ++ } ++ } ++ free(*xfiles); ++ *xfiles = NULL; ++ *count = 0; ++ return 1; ++} ++ ++static int ++kf_flags_to_fflags(int kf_flags) + { ++ static const struct { ++ int fflag; ++ int kf_flag; ++ } fflags_table[] = { ++ { FAPPEND, KF_FLAG_APPEND }, ++ { FASYNC, KF_FLAG_ASYNC }, ++ { FFSYNC, KF_FLAG_FSYNC }, ++ { FHASLOCK, KF_FLAG_HASLOCK }, ++ { FNONBLOCK, KF_FLAG_NONBLOCK }, ++ { FREAD, KF_FLAG_READ }, ++ { FWRITE, KF_FLAG_WRITE }, ++ { O_CREAT, KF_FLAG_CREAT }, ++ { O_DIRECT, KF_FLAG_DIRECT }, ++ { O_EXCL, KF_FLAG_EXCL }, ++ { O_EXEC, KF_FLAG_EXEC }, ++ { O_EXLOCK, KF_FLAG_EXLOCK }, ++ { O_NOFOLLOW, KF_FLAG_NOFOLLOW }, ++ { O_SHLOCK, KF_FLAG_SHLOCK }, ++ { O_TRUNC, KF_FLAG_TRUNC } ++ }; + int i; +-/* +- * Ignore the request if the vnode has already been entered. +- */ +- for (i = 0; i < *n; i++) { +- if (va == Vp[i]) +- return; ++ int fflags; ++ ++ fflags = 0; ++ for (i = 0; i < sizeof(fflags_table)/sizeof(fflags_table[0]); i++) ++ if (kf_flags & fflags_table[i].kf_flag) ++ fflags |= fflags_table[i].fflag; ++ return fflags; ++} ++ ++ ++/* Based on process_file() in lib/prfd.c */ ++static void ++process_kinfo_file(struct kinfo_file *kf, struct xfile *xfile, struct pcb_lists *pcbs) ++{ ++ Lf->off = kf->kf_offset; ++ if (kf->kf_ref_count) { ++ if ((kf->kf_flags & (KF_FLAG_READ | KF_FLAG_WRITE)) == KF_FLAG_READ) ++ Lf->access = 'r'; ++ else if ((kf->kf_flags & (KF_FLAG_READ | KF_FLAG_WRITE)) == KF_FLAG_WRITE) ++ Lf->access = 'w'; ++ else if ((kf->kf_flags & (KF_FLAG_READ | KF_FLAG_WRITE)) == (KF_FLAG_READ | KF_FLAG_WRITE)) ++ Lf->access = 'u'; + } +-/* +- * Save the text file information. +- */ +- alloc_lfile(" txt", -1); +- Cfp = (struct file *)NULL; +- process_node(va); +- if (Lf->sf) +- link_lfile(); +- if (i >= Nv) { + +- /* +- * Allocate space for remembering the vnode. +- */ +- Nv += 10; +- if (!Vp) +- Vp=(KA_T *)malloc((MALLOC_S)(sizeof(struct vnode *)*10)); ++ if (Fsv & FSV_CT) { ++ Lf->fct = (long)kf->kf_ref_count; ++ Lf->fsv |= FSV_CT; ++ } ++ if (xfile) { ++ if (Fsv & FSV_FA) { ++ Lf->fsa = xfile->xf_file; ++ Lf->fsv |= FSV_FA; ++ } ++ if (Fsv & FSV_NI) { ++ Lf->fna = (KA_T)xfile->xf_data; ++ Lf->fsv |= FSV_NI; ++ } ++ } ++ if (Fsv & FSV_FG) { ++ if (xfile) ++ Lf->ffg = (long)xfile->xf_flag; + else +- Vp=(KA_T *)realloc((MALLOC_P *)Vp,(MALLOC_S)(Nv*sizeof(KA_T))); +- if (!Vp) { +- (void) fprintf(stderr, "%s: no txt ptr space, PID %d\n", +- Pn, Lp->pid); +- Error(); ++ Lf->ffg = kf_flags_to_fflags(kf->kf_flags); ++ Lf->fsv |= FSV_FG; ++ } ++ ++ switch (kf->kf_type) { ++ case KF_TYPE_FIFO: ++ case KF_TYPE_VNODE: ++ process_vnode(kf, xfile); ++ break; ++ case KF_TYPE_SOCKET: ++ process_socket(kf, pcbs); ++ break; ++ case KF_TYPE_KQUEUE: ++ process_kf_kqueue(kf, xfile ? xfile->xf_data : 0UL); ++ break; ++ case KF_TYPE_PIPE: ++ if (!Selinet) ++ process_pipe(kf, xfile ? xfile->xf_data : 0UL); ++ break; ++ case KF_TYPE_PTS: ++ process_pts(kf); ++ break; ++#if defined(KF_TYPE_EVENTFD) ++ case KF_TYPE_EVENTFD: ++ process_eventfd(kf); ++ break; ++#endif /* defined(KF_TYPE_EVENTFD) */ ++ case KF_TYPE_SHM: ++ process_shm(kf); ++ break; ++ case KF_TYPE_PROCDESC: ++ process_procdesc(kf); ++ break; ++ default: ++ /* FIXME: unlike struct file, xfile doesn't have f_ops which should be printed here */ ++ snpf(Namech, Namechl, ++ "%p file struct, ty=%d", ++ xfile ? (void*)xfile->xf_file : NULL, ++ kf->kf_type); ++ enter_nm(Namech); ++ } ++} ++ ++ ++static void ++process_file_descriptors( ++ struct kinfo_proc *p, short ckscko, ++ struct xfile *xfiles, size_t n_xfiles, ++ struct pcb_lists *pcbs) ++{ ++ struct kinfo_file *kfiles; ++ int n_kfiles = 0; ++ int i; ++ ++ kfiles = kinfo_getfile(p->P_PID, &n_kfiles); ++ /* Pre-cache the mount info, as files w/o paths may need it from other files with paths on the same fs */ ++ for (i = 0; i < n_kfiles; i++) { ++ if (kfiles[i].kf_fd < 0 || kfiles[i].kf_type == KF_TYPE_FIFO || kfiles[i].kf_type == KF_TYPE_VNODE) ++ readvfs(kfiles[i].kf_un.kf_file.kf_file_fsid, kfiles[i].kf_path); ++ } ++ for (i = 0; i < n_kfiles; i++) { ++ struct xfile key, *xfile; ++ ++ key.xf_pid = p->P_PID; ++ key.xf_fd = kfiles[i].kf_fd; ++ xfile = bsearch(&key, xfiles, n_xfiles, sizeof(*xfiles), cmp_xfiles_pid_fd); ++ ++ if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_CWD) { ++ alloc_lfile(CWD, -1); ++ process_vnode(&kfiles[i], xfile); ++ if (Lf->sf) ++ link_lfile(); ++ } else if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_ROOT) { ++ alloc_lfile(RTD, -1); ++ process_vnode(&kfiles[i], xfile); ++ if (Lf->sf) ++ link_lfile(); ++ } else if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_JAIL) { ++ alloc_lfile(" jld", -1); ++ process_vnode(&kfiles[i], xfile); ++ if (Lf->sf) ++ link_lfile(); ++ } else if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_TEXT) { ++ alloc_lfile(" txt", -1); ++ process_vnode(&kfiles[i], xfile); ++ if (Lf->sf) ++ link_lfile(); ++ } else if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_CTTY) { ++ alloc_lfile("ctty", -1); ++ process_vnode(&kfiles[i], xfile); ++ if (Lf->sf) ++ link_lfile(); ++ } else if (!ckscko && kfiles[i].kf_fd < 0) { ++ if (!Fwarn) ++ fprintf(stderr, "%s: WARNING -- unsupported fd type %d\n", Pn, kfiles[i].kf_fd); ++ } else { ++ alloc_lfile(NULL, kfiles[i].kf_fd); ++ process_kinfo_file(&kfiles[i], xfile, pcbs); ++ if (Lf->sf) ++ link_lfile(); + } + } +-/* +- * Remember the vnode. +- */ +- Vp[*n] = va; +- (*n)++; + } + + +@@ -114,6 +276,9 @@ gather_proc_info() + void + gather_proc_info() + { ++ ++ int mib[3]; ++ size_t len; + short cckreg; /* conditional status of regular file + * checking: + * 0 = unconditionally check +@@ -124,36 +289,8 @@ gather_proc_info() + * including TCP and UDP + * streams with eXPORT data, + * where supported */ +- struct filedesc fd; +-#if defined(PWDDESC_KVM_LOAD_PWD) +- struct pwddesc pd; +-#endif /* defined(PWDDESC_KVM_LOAD_PWD) */ +- int i, nf; +- MALLOC_S nb; + +-#if defined(HAS_FILEDESCENT) +- typedef struct filedescent ofb_t; +-#else /* !defined(HAS_FILEDESCENT) */ +- typedef struct file* ofb_t; +-#endif /* defined(HAS_FILEDESCENT) */ +- +-#if defined(HAS_FDESCENTTBL) +- struct fdescenttbl fdt; +- KA_T fa; +-#endif /* defined(HAS_FDESCENTTBL) */ +- +-#if defined(HAS_PWD) +- struct pwd pwd; +- KA_T pwd_addr; +-#endif /* defined(HAS_FDESCENTTBL) */ +- +- struct vnode *cdir; +- struct vnode *rdir; +- struct vnode *jdir; +- +- static ofb_t *ofb = NULL; +- static int ofbb = 0; +- int pgid, pid; ++ int pgid; + int ppid = 0; + short pss, sf; + int px; +@@ -161,6 +298,9 @@ gather_proc_info() + uid_t uid; + + struct kinfo_proc *p; ++ struct xfile *xfiles; ++ size_t n_xfiles; ++ struct pcb_lists *pcbs; + + #if defined(HASFSTRUCT) && !defined(HAS_FILEDESCENT) + static char *pof = (char *)NULL; +@@ -224,19 +364,36 @@ gather_proc_info() + #define KERN_PROC_PROC KERN_PROC_ALL + # endif /* !defined(KERN_PROC_PROC) */ + +- if ((P = kvm_getprocs(Kd, Ftask ? KERN_PROC_ALL : KERN_PROC_PROC, +- 0, &Np)) +- == NULL) +- +- { ++ mib[0] = CTL_KERN; ++ mib[1] = KERN_PROC; ++ mib[2] = Ftask ? KERN_PROC_ALL : KERN_PROC_PROC; ++ len = 0; ++ if (sysctl(mib, 3, NULL, &len, NULL, 0) == 0) { ++ P = malloc(len); ++ if (P) { ++ if (sysctl(mib, 3, P, &len, NULL, 0) < 0) { ++ free(P); ++ P = NULL; ++ } ++ } ++ } ++ if (P == NULL) { + (void) fprintf(stderr, "%s: can't read process table: %s\n", + Pn, +- +- kvm_geterr(Kd) +- ++ strerror(errno) + ); +- Error(); ++ Exit(1); + } ++ Np = len / sizeof(struct kinfo_proc); ++ if (read_xfiles(&xfiles, &n_xfiles) && !Fwarn) ++ fprintf(stderr, "%s: WARNING -- reading xfile list failed: %s\n", ++ Pn, strerror(errno)); ++ qsort(xfiles, n_xfiles, sizeof(*xfiles), cmp_xfiles_pid_fd); ++ pcbs = read_pcb_lists(); ++ if (!pcbs && !Fwarn) ++ fprintf(stderr, "%s: WARNING -- reading PCBs failed: %s\n", ++ Pn, strerror(errno)); ++ + /* + * Examine proc structures and their associated information. + */ +@@ -270,44 +427,6 @@ gather_proc_info() + #endif /* defined(HASTASKS) */ + + /* +- * Read file structure pointers. +- */ +- if (!p->P_FD +- || kread((KA_T)p->P_FD, (char *)&fd, sizeof(fd))) +- continue; +- +-#if defined(HAS_FDESCENTTBL) +- if (!fd.fd_files +- || kread((KA_T)fd.fd_files, (char *)&fdt, sizeof(fdt))) +- continue; +- if (!fd.fd_refcnt) +- continue; +-#else /* !defined(HAS_FDESCENTTBL) */ +- if (!fd.fd_refcnt || fd.fd_lastfile > fd.fd_nfiles) +- continue; +-#endif /* defined(HAS_FDESCENTTBL) */ +- +-#if defined(HAS_PWD) +- cdir = rdir = jdir = NULL; +-#if defined(PWDDESC_KVM_LOAD_PWD) +- pwd_addr = (KA_T)PWDDESC_KVM_LOAD_PWD(&pd); +-#else /* defined(PWDDESC_KVM_LOAD_PWD) */ +- pwd_addr = (KA_T)FILEDESC_KVM_LOAD_PWD(&fd); +-#endif /* defined(PWDDESC_KVM_LOAD_PWD) */ +- if (pwd_addr != 0) { +- if (!kread(pwd_addr, (char *)&pwd, sizeof(pwd))) { +- cdir = pwd.pwd_cdir; +- rdir = pwd.pwd_rdir; +- jdir = pwd.pwd_jdir; +- } +- } +-#else +- cdir = fd.fd_cdir; +- rdir = fd.fd_rdir; +- jdir = fd.fd_jdir; +-#endif +- +- /* + * Allocate a local process structure. + */ + if (is_cmd_excl(p->P_COMM, &pss, &sf)) +@@ -339,137 +458,19 @@ gather_proc_info() + Kpa = (KA_T)p->P_ADDR; + #endif /* defined(P_ADDR) */ + +- /* +- * Save current working directory information. +- */ +- if (!ckscko && cdir) { +- alloc_lfile(CWD, -1); +- Cfp = (struct file *)NULL; +- process_node((KA_T)cdir); +- if (Lf->sf) +- link_lfile(); +- } +- /* +- * Save root directory information. +- */ +- if (!ckscko && rdir) { +- alloc_lfile(RTD, -1); +- Cfp = (struct file *)NULL; +- process_node((KA_T)rdir); +- if (Lf->sf) +- link_lfile(); +- } ++ process_file_descriptors(p, ckscko, xfiles, n_xfiles, pcbs); + + /* +- * Save jail directory information. +- */ +- if (!ckscko && jdir) { +- alloc_lfile("jld", -1); +- Cfp = (struct file *)NULL; +- process_node((KA_T)jdir); +- if (Lf->sf) +- link_lfile(); +- } +- +- /* +- * Save information on the text file. +- */ +- if (!ckscko && p->P_VMSPACE) +- process_text((KA_T)p->P_VMSPACE); +- /* +- * Read open file structure pointers. +- */ +- +-#if defined(HAS_FDESCENTTBL) +- if ((nf = fdt.fdt_nfiles) <= 0) +- continue; +-#else /* !defined(HAS_FDESCENTTBL) */ +- if (!fd.fd_ofiles || (nf = fd.fd_nfiles) <= 0) +- continue; +-#endif /* defined(HAS_FDESCENTTBL) */ +- +- nb = (MALLOC_S)(sizeof(ofb_t) * nf); +- if (nb > ofbb) { +- if (!ofb) +- ofb = (ofb_t *)malloc(nb); +- else +- ofb = (ofb_t *)realloc((MALLOC_P *)ofb, nb); +- if (!ofb) { +- (void) fprintf(stderr, "%s: PID %d, no file * space\n", +- Pn, p->P_PID); +- Error(); +- } +- ofbb = nb; +- } +- +-#if defined(HAS_FDESCENTTBL) +- fa = (KA_T)fd.fd_files +- + (KA_T)offsetof(struct fdescenttbl, fdt_ofiles); +- if (kread(fa, (char *)ofb, nb)) +- continue; +-#else /* !defined(HAS_FDESCENTTBL) */ +- if (kread((KA_T)fd.fd_ofiles, (char *)ofb, nb)) +- continue; +-#endif /* defined(HAS_FDESCENTTBL) */ +- +- +-#if defined(HASFSTRUCT) && !defined(HAS_FILEDESCENT) +- if (Fsv & FSV_FG) { +- nb = (MALLOC_S)(sizeof(char) * nf); +- if (nb > pofb) { +- if (!pof) +- pof = (char *)malloc(nb); +- else +- pof = (char *)realloc((MALLOC_P *)pof, nb); +- if (!pof) { +- (void) fprintf(stderr, +- "%s: PID %d, no file flag space\n", Pn, p->P_PID); +- Error(); +- } +- pofb = nb; +- } +- if (!fd.fd_ofileflags || kread((KA_T)fd.fd_ofileflags, pof, nb)) +- zeromem(pof, nb); +- } +-#endif /* defined(HASFSTRUCT) && !defined(HAS_FILEDESCENT) */ +- +- /* +- * Save information on file descriptors. +- */ +- for (i = 0; i < nf; i++) { +- +-#if defined(HAS_FILEDESCENT) +- if ((Cfp = ofb[i].fde_file)) +-#else /* !defined(HAS_FILEDESCENT) */ +- if ((Cfp = ofb[i])) +-#endif /* defined(HAS_FILEDESCENT) */ +- +- { +- alloc_lfile(NULL, i); +- process_file((KA_T)Cfp); +- if (Lf->sf) { +- +-#if defined(HASFSTRUCT) +- if (Fsv & FSV_FG) +-# if defined(HAS_FILEDESCENT) +- Lf->pof = (long)ofb[i].fde_flags; +-# else /* !defined(HAS_FILEDESCENT) */ +- Lf->pof = (long)pof[i]; +-# endif /* defined(HAS_FILEDESCENT) */ +-#endif /* defined(HASFSTRUCT) */ +- +- link_lfile(); +- } +- } +- } +- /* + * Unless threads (tasks) are being processed, examine results. + */ + if (!Ftask) { + if (examine_lproc()) +- return; ++ break; + } + } ++ ++ free(xfiles); ++ free_pcb_lists(pcbs); + } + + +@@ -497,7 +498,7 @@ get_kernel_access() + if (!(Nmlst = get_nlist_path(1))) { + (void) fprintf(stderr, + "%s: can't get kernel name list path\n", Pn); +- Error(); ++ Exit(1); + } + } + #endif /* defined(N_UNIX) */ +@@ -515,7 +516,7 @@ get_kernel_access() + */ + if ((Memory && !is_readable(Memory, 1)) + || (Nmlst && !is_readable(Nmlst, 1))) +- Error(); ++ Exit(1); + #endif /* defined(WILLDROPGID) */ + + /* +@@ -541,13 +542,13 @@ get_kernel_access() + #endif /* defined(_PATH_MEM) */ + + strerror(errno)); +- Error(); ++ return; + } + (void) build_Nl(Drive_Nl); + if (kvm_nlist(Kd, Nl) < 0) { + (void) fprintf(stderr, "%s: can't read namelist from %s\n", + Pn, Nmlst); +- Error(); ++ Exit(1); + } + + #if defined(X_BADFILEOPS) +@@ -598,7 +599,7 @@ get_nlist_path(ap) + (void) fprintf(stderr, + "%s: can't allocate %d bytes for boot file path: %s\n", + Pn, (int)bfl, bf); +- Error(); ++ Exit(1); + } + (void) snpf(bfc, bfl, "%s", bf); + return(bfc); +@@ -615,7 +616,9 @@ initialize() + void + initialize() + { ++#if __FreeBSD_version < 1400053 + get_kernel_access(); ++#endif /* __FreeBSD_version < 1400053 */ + } + + +@@ -631,93 +634,10 @@ kread(addr, buf, len) + { + int br; + ++ if (!Kd) ++ return 1; + br = kvm_read(Kd, (u_long)addr, buf, len); + + return((br == len) ? 0 : 1); + } + +-static int +-vm_map_reader(void *token, vm_map_entry_t addr, vm_map_entry_t dest) +-{ +- return (kread((KA_T)addr, (char *)dest, sizeof(*dest))); +-} +- +-#if __FreeBSD_version < 1300060 +-typedef int vm_map_entry_reader(void *token, vm_map_entry_t addr, +- vm_map_entry_t dest); +- +-static inline vm_map_entry_t +-vm_map_entry_read_succ(void *token, struct vm_map_entry *const clone, +- vm_map_entry_reader reader) +-{ +- vm_map_entry_t next; +- +- next = clone->next; +- if (!reader(token, next, clone)) +- return (NULL); +- return (next); +-} +-#endif /* __FreeBSD_version < 1300060 */ +- +-/* +- * process_text() - process text information +- */ +-void +-process_text(vm) +- KA_T vm; /* vm space pointer */ +-{ +- int i, j; +- KA_T ka; +- int n = 0; +- struct vm_map_entry vmme, *e; +- struct vm_object vmo; +- struct vmspace vmsp; +- +-/* +- * Read the vmspace structure for the process. +- */ +- if (kread(vm, (char *)&vmsp, sizeof(vmsp))) +- return; +-/* +- * Read the vm_map structure. Search its vm_map_entry structure list. +- */ +- vmme = vmsp.vm_map.header; +- e = &vmme; +- for (i = 0; i < vmsp.vm_map.nentries; i++) { +- +- /* +- * Read the next vm_map_entry. +- */ +- if (!vm_map_entry_read_succ(NULL, e, vm_map_reader)) +- return; +- +-#if defined(MAP_ENTRY_IS_A_MAP) +- if (e->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) +-#else /* !defined(MAP_ENTRY_IS_A_MAP) */ +- if (e->is_a_map || e->is_sub_map) +-#endif /* defined(MAP_ENTRY_IS_A_MAP) */ +- +- continue; +- /* +- * Read the map entry's object and the object's shadow. +- * Look for: a PG_VNODE pager handle (FreeBSD < 2.2); +- * an OBJT_VNODE object type (FreeBSD >= 2.2). +- */ +- for (j = 0, ka = (KA_T)e->object.vm_object; +- j < 2 && ka; +- j++, +- +- ka = (KA_T)vmo.backing_object +- ) +- { +- if (kread(ka, (char *)&vmo, sizeof(vmo))) +- break; +- +- if (vmo.type != OBJT_VNODE +- || vmo.handle == (void *)NULL) +- continue; +- (void) (enter_vn_text((KA_T)vmo.handle, &n)); +- +- } +- } +-} diff --git a/sysutils/lsof/files/patch-dialects_freebsd_dproto.h b/sysutils/lsof/files/patch-dialects_freebsd_dproto.h new file mode 100644 index 000000000000..9806c257060e --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_dproto.h @@ -0,0 +1,48 @@ +--- dialects/freebsd/dproto.h.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/dproto.h +@@ -37,31 +37,30 @@ + */ + + +-#if defined(HAS_NO_SI_UDEV) +-# if defined(HAS_CONF_MINOR)|| defined(HAS_CDEV2PRIV) +-_PROTOTYPE(extern dev_t Dev2Udev,(KA_T c)); +-# else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ +-_PROTOTYPE(extern dev_t Dev2Udev,(struct cdev *c)); +-# endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ +-#endif /* defined(HAS_NO_SI_UDEV) */ +- + #if !defined(N_UNIX) + _PROTOTYPE(extern char *get_nlist_path,(int ap)); + #endif /* !defined(N_UNIX) */ + + _PROTOTYPE(extern int is_file_named,(char *p, int cd)); +-_PROTOTYPE(extern void process_socket,(KA_T sa)); +-_PROTOTYPE(extern struct l_vfs *readvfs,(KA_T vm)); ++_PROTOTYPE(extern void process_vnode,(struct kinfo_file *kf, struct xfile *xfile)); ++_PROTOTYPE(extern void process_socket,(struct kinfo_file *kf, struct pcb_lists *pcbs)); ++_PROTOTYPE(extern struct l_vfs *readvfs,(uint64_t fsid, const char *path)); ++_PROTOTYPE(extern struct pcb_lists *read_pcb_lists,(void)); ++_PROTOTYPE(extern void free_pcb_lists,(struct pcb_lists *pcb_lists)); + +-#if defined(HASPTSFN) +-_PROTOTYPE(extern void process_pts,(KA_T ta)); +-#endif /* defined(HASPTSFN) */ ++_PROTOTYPE(extern void process_pts,(struct kinfo_file *kf)); + ++#if defined(KF_TYPE_EVENTFD) ++_PROTOTYPE(extern void process_eventfd,(struct kinfo_file *kf)); ++#endif /* defined(KF_TYPE_EVENTFD) */ ++ + #if defined(HASKQUEUE) +-_PROTOTYPE(extern void process_kqueue,(KA_T ka)); ++_PROTOTYPE(extern void process_kf_kqueue,(struct kinfo_file *kf, KA_T ka)); + #endif /* defined(HASKQUEUE) */ + +-_PROTOTYPE(extern void process_pipe,(KA_T pa)); ++_PROTOTYPE(extern void process_pipe,(struct kinfo_file *kf, KA_T pa)); ++_PROTOTYPE(extern void process_shm,(struct kinfo_file *kf)); ++_PROTOTYPE(extern void process_procdesc,(struct kinfo_file *kf)); + + #if defined(HASFUSEFS) + _PROTOTYPE(extern int read_fuse_node,(struct vnode *v, dev_t *d, int *dd, INODETYPE *ino, long *nl, SZOFFTYPE *sz)); diff --git a/sysutils/lsof/files/patch-dialects_freebsd_dsock.c b/sysutils/lsof/files/patch-dialects_freebsd_dsock.c new file mode 100644 index 000000000000..fff16c72df73 --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_dsock.c @@ -0,0 +1,797 @@ +--- dialects/freebsd/dsock.c.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/dsock.c +@@ -73,14 +73,211 @@ static char copyright[] = + #define SOCK_CC sb_cc + #endif /* defined(HAS_SB_CCC) */ + ++#if __FreeBSD_version >= 1200026 ++#define XTCPCB_SO xt_inp.xi_socket ++#define XTCPCB_SO_PCB xt_inp.xi_socket.so_pcb ++#else /* __FreeBSD_version < 1200026 */ ++#define XTCPCB_SO xt_socket ++#define XTCPCB_SO_PCB xt_socket.so_pcb ++#endif /* __FreeBSD_version >= 1200026 */ + ++ + /* + * Local function prototypes + */ + +-_PROTOTYPE(static int ckstate,(KA_T pcb, KA_T ta, struct tcpcb *t, int fam)); ++_PROTOTYPE(static int ckstate,(struct xtcpcb *pcb, int fam)); + + ++static int ++cmp_xunpcb_sock_pcb(const void *a, const void *b) { ++ const struct xunpcb *pcb1 = (const struct xunpcb *)a; ++ const struct xunpcb *pcb2 = (const struct xunpcb *)b; ++ ++ if (pcb1->xu_socket.so_pcb < pcb2->xu_socket.so_pcb) ++ return -1; ++ else if (pcb1->xu_socket.so_pcb > pcb2->xu_socket.so_pcb) ++ return 1; ++ else ++ return 0; ++} ++ ++ ++static int ++cmp_xtcpcb_sock_pcb(const void *a, const void *b) { ++ const struct xtcpcb *pcb1 = (const struct xtcpcb *)a; ++ const struct xtcpcb *pcb2 = (const struct xtcpcb *)b; ++ ++ if (pcb1->XTCPCB_SO_PCB < pcb2->XTCPCB_SO_PCB) ++ return -1; ++ else if (pcb1->XTCPCB_SO_PCB > pcb2->XTCPCB_SO_PCB) ++ return 1; ++ else ++ return 0; ++} ++ ++ ++static int ++cmp_xinpcb_sock_pcb(const void *a, const void *b) { ++ const struct xinpcb *pcb1 = (const struct xinpcb *)a; ++ const struct xinpcb *pcb2 = (const struct xinpcb *)b; ++ ++ if (pcb1->xi_socket.so_pcb < pcb2->xi_socket.so_pcb) ++ return -1; ++ else if (pcb1->xi_socket.so_pcb > pcb2->xi_socket.so_pcb) ++ return 1; ++ else ++ return 0; ++} ++ ++ ++static int ++get_unix_pcbs(const char *name, struct xunpcb **pcbs, size_t *n_pcbs) ++{ ++ size_t len; ++ char *buffer = NULL; ++ struct xunpgen *ug = (struct xunpgen *)buffer; ++ int count = 0; ++ int ret = 1; ++ ++ if (sysctlbyname(name, NULL, &len, NULL, 0)) ++ goto end; ++ if ((buffer = malloc(len)) == NULL) ++ goto end; ++ if (sysctlbyname(name, buffer, &len, NULL, 0)) ++ goto end; ++ ug = (struct xunpgen *)buffer; ++ for (ug = (struct xunpgen *)((char *)ug + ug->xug_len); ++ ug->xug_len == sizeof(struct xunpcb); ++ ug = (struct xunpgen *)((char *)ug + ug->xug_len)) { ++ ++count; ++ } ++ memmove(buffer, buffer + ((struct xunpgen *)buffer)->xug_len, count * sizeof(struct xunpcb)); ++ qsort(buffer, count, sizeof(struct xunpcb), cmp_xunpcb_sock_pcb); ++ ret = 0; ++ ++end: ++ *pcbs = (struct xunpcb *)buffer; ++ *n_pcbs = count; ++ if (ret) ++ free(buffer); ++ return ret; ++} ++ ++ ++static int ++get_tcp_pcbs(struct xtcpcb **pcbs, size_t *n_pcbs) ++{ ++ size_t len; ++ char *buffer = NULL; ++ struct xinpgen *ig = (struct xinpgen *)buffer; ++ int count = 0; ++ int ret = 1; ++ ++ if (sysctlbyname("net.inet.tcp.pcblist", NULL, &len, NULL, 0)) ++ goto end; ++ if ((buffer = malloc(len)) == NULL) ++ goto end; ++ if (sysctlbyname("net.inet.tcp.pcblist", buffer, &len, NULL, 0)) ++ goto end; ++ ig = (struct xinpgen *)buffer; ++ for (ig = (struct xinpgen *)((char *)ig + ig->xig_len); ++ ig->xig_len == sizeof(struct xtcpcb); ++ ig = (struct xinpgen *)((char *)ig + ig->xig_len)) { ++ ++count; ++ } ++ memmove(buffer, buffer + ((struct xinpgen *)buffer)->xig_len, count * sizeof(struct xtcpcb)); ++ qsort(buffer, count, sizeof(struct xtcpcb), cmp_xtcpcb_sock_pcb); ++ ret = 0; ++ ++end: ++ *pcbs = (struct xtcpcb *)buffer; ++ *n_pcbs = count; ++ if (ret) ++ free(buffer); ++ return ret; ++} ++ ++ ++static int ++get_udp_pcbs(struct xinpcb **pcbs, size_t *n_pcbs) ++{ ++ size_t len; ++ char *buffer = NULL; ++ struct xinpgen *ig = (struct xinpgen *)buffer; ++ int count = 0; ++ int ret = 1; ++ ++ if (sysctlbyname("net.inet.udp.pcblist", NULL, &len, NULL, 0)) ++ goto end; ++ if ((buffer = malloc(len)) == NULL) ++ goto end; ++ if (sysctlbyname("net.inet.udp.pcblist", buffer, &len, NULL, 0)) ++ goto end; ++ ig = (struct xinpgen *)buffer; ++ for (ig = (struct xinpgen *)((char *)ig + ig->xig_len); ++ ig->xig_len == sizeof(struct xinpcb); ++ ig = (struct xinpgen *)((char *)ig + ig->xig_len)) { ++ ++count; ++ } ++ memmove(buffer, buffer + ((struct xinpgen *)buffer)->xig_len, count * sizeof(struct xinpcb)); ++ qsort(buffer, count, sizeof(struct xinpcb), cmp_xinpcb_sock_pcb); ++ ret = 0; ++ ++end: ++ *pcbs = (struct xinpcb *)buffer; ++ *n_pcbs = count; ++ if (ret) ++ free(buffer); ++ return 0; ++} ++ ++ ++struct pcb_lists* ++read_pcb_lists(void) ++{ ++ struct pcb_lists *pcbs; ++ int succeeded = 0; ++ ++ pcbs = calloc(1, sizeof(struct pcb_lists)); ++ if (!pcbs) ++ goto end; ++ ++ if (get_unix_pcbs("net.local.stream.pcblist", &pcbs->un_stream_pcbs, &pcbs->n_un_stream_pcbs)) ++ goto end; ++ if (get_unix_pcbs("net.local.dgram.pcblist", &pcbs->un_dgram_pcbs, &pcbs->n_un_dgram_pcbs)) ++ goto end; ++ if (get_unix_pcbs("net.local.seqpacket.pcblist", &pcbs->un_seqpacket_pcbs, &pcbs->n_un_seqpacket_pcbs)) ++ goto end; ++ if (get_tcp_pcbs(&pcbs->tcp_pcbs, &pcbs->n_tcp_pcbs)) ++ goto end; ++ if (get_udp_pcbs(&pcbs->udp_pcbs, &pcbs->n_udp_pcbs)) ++ goto end; ++ succeeded = 1; ++ ++end: ++ if (!succeeded) { ++ free_pcb_lists(pcbs); ++ return NULL; ++ } ++ return pcbs; ++} ++ ++ ++void ++free_pcb_lists(struct pcb_lists *pcbs) ++{ ++ if (pcbs) { ++ free(pcbs->un_stream_pcbs); ++ free(pcbs->un_dgram_pcbs); ++ free(pcbs->un_seqpacket_pcbs); ++ free(pcbs->tcp_pcbs); ++ free(pcbs->udp_pcbs); ++ } ++ free(pcbs); ++} ++ ++ + /* + * ckstate() -- read TCP control block and check TCP state for inclusion + * or exclusion +@@ -90,27 +287,17 @@ static int + */ + + static int +-ckstate(pcb, ta, t, fam) +- KA_T pcb; /* PCB address */ +- KA_T ta; /* TCP control block address */ +- struct tcpcb *t; /* TCP control block receptor */ +- int fam; /* protocol family */ ++ckstate(struct xtcpcb *pcb, int fam) + { ++#if __FreeBSD_version >= 1200026 + int tsnx; +-/* +- * Read TCP control block. +- */ +- if (kread(ta, (char *)t, sizeof(struct tcpcb)) +- || (KA_T)t->t_inpcb != pcb) +- { +- return(-1); +- } ++ + if (TcpStXn || TcpStIn) { + + /* + * If there are TCP state inclusions or exclusions, check them. + */ +- if ((tsnx = (int)t->t_state + TcpStOff) >= TcpNstates) ++ if ((tsnx = (int)pcb->t_state + TcpStOff) >= TcpNstates) + return(0); + if (TcpStXn) { + if (TcpStX[tsnx]) { +@@ -138,10 +325,7 @@ ckstate(pcb, ta, t, fam) + if (Fnet) { + if (!FnetTy + || ((FnetTy == 4) && (fam == AF_INET)) +- +-#if defined(HASIPv6) + || ((FnetTy == 6) && (fam == AF_INET6)) +-#endif /* defined(HASIPv6) */ + + ) { + Lf->sf |= SELNET; +@@ -149,277 +333,219 @@ ckstate(pcb, ta, t, fam) + } + } + return(0); ++#else /* __FreeBSD_version < 1200026 */ ++ return(-1); ++#endif /* __FreeBSD_version >= 1200026 */ + } + + ++static void ++find_pcb_and_xsocket(struct pcb_lists *pcbs, int domain, int type, uint64_t pcb_addr, ++ void **pcb, struct xsocket **xsocket) ++{ ++ if (!pcbs) ++ return; ++ if (domain == PF_INET || domain == PF_INET6) { ++ if (type == SOCK_STREAM) { ++ struct xtcpcb key, *result; ++ key.XTCPCB_SO_PCB = pcb_addr; ++ result = bsearch(&key, pcbs->tcp_pcbs, pcbs->n_tcp_pcbs, sizeof(*pcbs->tcp_pcbs), cmp_xtcpcb_sock_pcb); ++ if (result) { ++ *xsocket = &result->XTCPCB_SO; ++ *pcb = result; ++ } ++ } else if (type == SOCK_DGRAM) { ++ struct xinpcb key, *result; ++ key.xi_socket.so_pcb = pcb_addr; ++ result = bsearch(&key, pcbs->udp_pcbs, pcbs->n_udp_pcbs, sizeof(*pcbs->udp_pcbs), cmp_xinpcb_sock_pcb); ++ if (result) { ++ *xsocket = &result->xi_socket; ++ *pcb = result; ++ } ++ } ++ } else if (domain == PF_UNIX) { ++ struct xunpcb key, *result = NULL; ++ key.xu_socket.so_pcb = pcb_addr; ++ if (type == SOCK_STREAM) { ++ result = bsearch(&key, pcbs->un_stream_pcbs, pcbs->n_un_stream_pcbs, sizeof(*pcbs->un_stream_pcbs), cmp_xunpcb_sock_pcb); ++ } else if (type == SOCK_DGRAM) { ++ result = bsearch(&key, pcbs->un_dgram_pcbs, pcbs->n_un_dgram_pcbs, sizeof(*pcbs->un_dgram_pcbs), cmp_xunpcb_sock_pcb); ++ } else if (type == SOCK_SEQPACKET) { ++ result = bsearch(&key, pcbs->un_seqpacket_pcbs, pcbs->n_un_seqpacket_pcbs, sizeof(*pcbs->un_seqpacket_pcbs), cmp_xunpcb_sock_pcb); ++ } ++ if (result) { ++ *xsocket = &result->xu_socket; ++ *pcb = result; ++ } ++ } ++} ++ ++ + /* + * process_socket() - process socket + */ + + void +-process_socket(sa) +- KA_T sa; /* socket address in kernel */ ++process_socket(struct kinfo_file *kf, struct pcb_lists *pcbs) + { +- struct domain d; + unsigned char *fa = (unsigned char *)NULL; + int fam; + int fp, lp; +- struct inpcb inp; + unsigned char *la = (unsigned char *)NULL; +- struct protosw p; +- struct socket s; +- struct tcpcb t; ++ void *pcb = NULL; ++ struct xsocket *s = NULL; + int ts = -1; +- struct unpcb uc, unp; + struct sockaddr_un *ua = NULL; +- struct sockaddr_un un; + + int unl; + +-#if defined(HASIPv6) && !defined(HASINRIAIPv6) +- struct inpcb in6p; +-#endif /* defined(HASIPv6) && !defined(HASINRIAIPv6) */ +- + (void) snpf(Lf->type, sizeof(Lf->type), "sock"); + Lf->inp_ty = 2; + /* + * Read the socket, protocol, and domain structures. + */ +- if (!sa) { +- enter_nm("no socket address"); +- return; +- } +- if (kread(sa, (char *) &s, sizeof(s))) { +- (void) snpf(Namech, Namechl, "can't read socket struct from %s", +- print_kptr(sa, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- if (!s.so_type) { +- enter_nm("no socket type"); +- return; +- } +- if (!s.so_proto +- || kread((KA_T)s.so_proto, (char *)&p, sizeof(p))) { +- (void) snpf(Namech, Namechl, "can't read protocol switch from %s", +- print_kptr((KA_T)s.so_proto, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } +- if (!p.pr_domain +- || kread((KA_T)p.pr_domain, (char *)&d, sizeof(d))) { +- (void) snpf(Namech, Namechl, "can't read domain struct from %s", +- print_kptr((KA_T)p.pr_domain, (char *)NULL, 0)); +- enter_nm(Namech); +- return; +- } ++ find_pcb_and_xsocket(pcbs, ++ kf->kf_sock_domain, ++ kf->kf_sock_type, ++ kf->kf_un.kf_sock.kf_sock_pcb, ++ &pcb, ++ &s); + /* + * Save size information. + */ ++#if defined(HAS_KF_SOCK_SENDQ) + if (Fsize) { + if (Lf->access == 'r') +- Lf->sz = (SZOFFTYPE)s.so_rcv.SOCK_CC; ++ Lf->sz = (SZOFFTYPE)kf->kf_un.kf_sock.kf_sock_recvq; + else if (Lf->access == 'w') +- Lf->sz = (SZOFFTYPE)s.so_snd.SOCK_CC; ++ Lf->sz = (SZOFFTYPE)kf->kf_un.kf_sock.kf_sock_sendq; + else +- Lf->sz = (SZOFFTYPE)(s.so_rcv.SOCK_CC + s.so_snd.SOCK_CC); ++ Lf->sz = (SZOFFTYPE)kf->kf_un.kf_sock.kf_sock_recvq ++ + (SZOFFTYPE)kf->kf_un.kf_sock.kf_sock_sendq; + Lf->sz_def = 1; + } else + Lf->off_def = 1; + + #if defined(HASTCPTPIQ) +- Lf->lts.rq = s.so_rcv.SOCK_CC; +- Lf->lts.sq = s.so_snd.SOCK_CC; ++ Lf->lts.rq = kf->kf_un.kf_sock.kf_sock_recvq; ++ Lf->lts.sq = kf->kf_un.kf_sock.kf_sock_sendq; + Lf->lts.rqs = Lf->lts.sqs = 1; + #endif /* defined(HASTCPTPIQ) */ ++#endif /* defined(HAS_KF_SOCK_SENDQ) */ + +-#if defined(HASSOOPT) +- Lf->lts.ltm = (unsigned int)s.so_linger; +- Lf->lts.opt = (unsigned int)s.so_options; ++ if (s) { ++ Lf->lts.ltm = (unsigned int)s->so_linger; ++ Lf->lts.opt = (unsigned int)s->so_options; + +-# if __FreeBSD_version>=1200027 +- if (s.so_options & SO_ACCEPTCONN) { +- Lf->lts.pqlen = (unsigned int)s.sol_incqlen; +- Lf->lts.qlen = (unsigned int)s.sol_qlen; +- Lf->lts.qlim = (unsigned int)s.sol_qlimit; +- } else { +- Lf->lts.rbsz = (unsigned long)s.so_rcv.sb_mbmax; +- Lf->lts.sbsz = (unsigned long)s.so_snd.sb_mbmax; ++ if (s->so_options & SO_ACCEPTCONN) { ++ Lf->lts.pqlen = (unsigned int)s->so_incqlen; ++ Lf->lts.qlen = (unsigned int)s->so_qlen; ++ Lf->lts.qlim = (unsigned int)s->so_qlimit; ++ } else { ++ Lf->lts.rbsz = (unsigned long)s->so_rcv.sb_mbmax; ++ Lf->lts.sbsz = (unsigned long)s->so_snd.sb_mbmax; ++ } ++ Lf->lts.pqlens = Lf->lts.qlens = Lf->lts.qlims = Lf->lts.rbszs ++ = Lf->lts.sbszs = (unsigned char)1; + +-# if defined(HASSBSTATE) +- Lf->lts.sbs_rcv = s.so_rcv.sb_state; +- Lf->lts.sbs_snd = s.so_snd.sb_state; +-# endif /* defined(HASSBSTATE) */ +- ++ Lf->lts.ss = (unsigned int)s->so_state; + } ++ Lf->lts.sbs_rcv = kf->kf_un.kf_sock.kf_sock_rcv_sb_state; ++ Lf->lts.sbs_snd = kf->kf_un.kf_sock.kf_sock_snd_sb_state; + +-# else /* __FreeBSD_version<1200027 */ +- Lf->lts.pqlen = (unsigned int)s.so_incqlen; +- Lf->lts.qlen = (unsigned int)s.so_qlen; +- Lf->lts.qlim = (unsigned int)s.so_qlimit; +- Lf->lts.rbsz = (unsigned long)s.so_rcv.sb_mbmax; +- Lf->lts.sbsz = (unsigned long)s.so_snd.sb_mbmax; +- +-# if defined(HASSBSTATE) +- Lf->lts.sbs_rcv = s.so_rcv.sb_state; +- Lf->lts.sbs_snd = s.so_snd.sb_state; +-# endif /* defined(HASSBSTATE) */ +-# endif /*__FreeBSD_version>=1200027 */ +- +- Lf->lts.pqlens = Lf->lts.qlens = Lf->lts.qlims = Lf->lts.rbszs +- = Lf->lts.sbszs = (unsigned char)1; +- +-# if defined(HASSOSTATE) +- Lf->lts.ss = (unsigned int)s.so_state; +-# endif /* defined(HASSOSTATE) */ +-#endif /* defined(HASSOPT) */ +- + /* + * Process socket by the associated domain family. + */ +- switch ((fam = d.dom_family)) { ++ switch ((fam = kf->kf_sock_domain)) { + /* + * Process an Internet domain socket. + */ + case AF_INET: +- +-#if defined(HASIPv6) + case AF_INET6: +-#endif /* defined(HASIPv6) */ + + if (Fnet) { + if (!FnetTy + || ((FnetTy == 4) && (fam == AF_INET)) +- +-#if defined(HASIPv6) + || ((FnetTy == 6) && (fam == AF_INET6)) +-#endif /* defined(HASIPv6) */ +- + ) { + if (!TcpStIn && !UdpStIn) + Lf->sf |= SELNET; + } + } +- printiproto(p.pr_protocol); ++ printiproto(kf->kf_sock_protocol); + +-#if defined(HASIPv6) + (void) snpf(Lf->type, sizeof(Lf->type), + (fam == AF_INET) ? "IPv4" : "IPv6"); +-#else /* !defined(HASIPv6) */ +- (void) snpf(Lf->type, sizeof(Lf->type), "inet"); +-#endif /* defined(HASIPv6) */ + +-#if defined(HASIPv6) && !defined(HASINRIAIPv6) + if (fam == AF_INET6) { +- ++ struct sockaddr_in6 *local_addr6, *foreign_addr6; ++ local_addr6 = (struct sockaddr_in6 *)&kf->kf_sa_local; ++ foreign_addr6 = (struct sockaddr_in6 *)&kf->kf_sa_peer; + /* + * Read IPv6 protocol control block. + */ +- if (!s.so_pcb +- || kread((KA_T)s.so_pcb, (char *)&in6p, sizeof(in6p))) { ++ if (!pcb) { + (void) snpf(Namech, Namechl, "can't read in6pcb at %s", +- print_kptr((KA_T)s.so_pcb, (char *)NULL, 0)); ++ print_kptr((KA_T)kf->kf_un.kf_sock.kf_sock_pcb, (char *)NULL, 0)); + enter_nm(Namech); + return; + } + /* + * Save IPv6 address information. + */ +- if (p.pr_protocol == IPPROTO_TCP) { +- if (in6p.in6p_ppcb) { +- if ((ts = ckstate((KA_T)s.so_pcb, (KA_T)in6p.in6p_ppcb, +- &t, fam)) == 1) +- { +- return; +- } ++ if (kf->kf_sock_protocol == IPPROTO_TCP) { ++ if ((ts = ckstate((struct xtcpcb *)pcb, fam)) == 1) { ++ return; + } + } +- enter_dev_ch(print_kptr((KA_T)(in6p.in6p_ppcb ? in6p.in6p_ppcb +- : s.so_pcb), ++ enter_dev_ch(print_kptr((KA_T)(kf->kf_un.kf_sock.kf_sock_inpcb ? kf->kf_un.kf_sock.kf_sock_inpcb ++ : kf->kf_un.kf_sock.kf_sock_pcb), + (char *)NULL, 0)); +- la = (unsigned char *)&in6p.in6p_laddr; +- lp = (int)ntohs(in6p.in6p_lport); +- if (!IN6_IS_ADDR_UNSPECIFIED(&in6p.in6p_faddr) +- || in6p.in6p_fport) ++ la = (unsigned char *)&local_addr6->sin6_addr; ++ lp = (int)ntohs(local_addr6->sin6_port); ++ if (!IN6_IS_ADDR_UNSPECIFIED(&foreign_addr6->sin6_addr) ++ || foreign_addr6->sin6_port) + { +- fa = (unsigned char *)&in6p.in6p_faddr; +- fp = (int)ntohs(in6p.in6p_fport); ++ fa = (unsigned char *)&foreign_addr6->sin6_addr; ++ fp = (int)ntohs(foreign_addr6->sin6_port); + } +- } else +-#endif /* defined(HASIPv6) && !defined(HASINRIAIPv6) */ ++ } else { + +- { +- + /* +- * Read Ipv4 or IPv6 (INRIA) protocol control block. ++ * Read Ipv4 protocol control block. + */ +- if (!s.so_pcb +- || kread((KA_T) s.so_pcb, (char *) &inp, sizeof(inp))) { +- if (!s.so_pcb) { +- (void) snpf(Namech, Namechl, "no PCB%s%s", +- +-#if defined(HASSBSTATE) +- (s.so_snd.sb_state & SBS_CANTSENDMORE) ? +-#else /* !defined(HASSBSTATE) */ +- (s.so_state & SS_CANTSENDMORE) ? +-#endif /* defined(HASSBSTATE) */ +- +- ", CANTSENDMORE" : "", +-#if defined(HASSBSTATE) +- (s.so_rcv.sb_state & SBS_CANTRCVMORE) ? +-#else /* !defined(HASSBSTATE) */ +- (s.so_state & SS_CANTRCVMORE) ? +-#endif /* defined(HASSBSTATE) */ +- +- ", CANTRCVMORE" : ""); +- } else { +- (void) snpf(Namech, Namechl, "can't read inpcb at %s", +- print_kptr((KA_T)s.so_pcb, (char *)NULL, 0)); +- } ++ struct sockaddr_in *local_addr = (struct sockaddr_in*)&kf->kf_sa_local; ++ struct sockaddr_in *foreign_addr = (struct sockaddr_in*)&kf->kf_sa_peer; ++ if (!pcb) { ++ (void) snpf(Namech, Namechl, "no PCB%s%s", ++ (kf->kf_un.kf_sock.kf_sock_snd_sb_state & SBS_CANTSENDMORE) ? ++ ", CANTSENDMORE" : "", ++ (kf->kf_un.kf_sock.kf_sock_rcv_sb_state & SBS_CANTRCVMORE) ? ++ ", CANTRCVMORE" : ""); + enter_nm(Namech); + return; + } +- if (p.pr_protocol == IPPROTO_TCP) { +- if (inp.inp_ppcb) { +- if ((ts = ckstate((KA_T)s.so_pcb, (KA_T)inp.inp_ppcb, +- &t, fam)) == 1) +- { ++ if (kf->kf_sock_protocol == IPPROTO_TCP) { ++ if ((ts = ckstate((struct xtcpcb *)pcb, fam)) == 1) + return; +- } +- } + } +- enter_dev_ch(print_kptr((KA_T)(inp.inp_ppcb ? inp.inp_ppcb +- : s.so_pcb), ++ enter_dev_ch(print_kptr((KA_T)(kf->kf_un.kf_sock.kf_sock_inpcb ? kf->kf_un.kf_sock.kf_sock_inpcb ++ : kf->kf_un.kf_sock.kf_sock_pcb), + (char *)NULL, 0)); +- lp = (int)ntohs(inp.inp_lport); +- if (fam == AF_INET) { ++ lp = (int)ntohs(local_addr->sin_port); ++ la = (unsigned char *)&local_addr->sin_addr; + +- /* +- * Save IPv4 address information. +- */ +- la = (unsigned char *)&inp.inp_laddr; +- if (inp.inp_faddr.s_addr != INADDR_ANY || inp.inp_fport) { +- fa = (unsigned char *)&inp.inp_faddr; +- fp = (int)ntohs(inp.inp_fport); +- } ++ /* ++ * Save IPv4 address information. ++ */ ++ if (foreign_addr->sin_addr.s_addr != INADDR_ANY || foreign_addr->sin_port) { ++ fp = (int)ntohs(foreign_addr->sin_port); ++ fa = (unsigned char *)&foreign_addr->sin_addr; + } + +-#if defined(HASIPv6) && defined(HASINRIAIPv6) +- else { +- la = (unsigned char *)&inp.inp_laddr6; +- if (!IN6_IS_ADDR_UNSPECIFIED(&inp.inp_faddr6) +- || inp.inp_fport) +- { +- fa = (unsigned char *)&inp.inp_faddr6; +- fp = (int)ntohs(inp.inp_fport); +- } +- } +-#endif /* defined(HASIPv6) && defined(HASINRIAIPv6) */ +- + } + + +-#if defined(HASIPv6) + if ((fam == AF_INET6) + && ((la && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)la)) + || ((fa && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)fa))))) { +@@ -433,7 +559,6 @@ process_socket(sa) + fa = (unsigned char *)IPv6_2_IPv4(fa); + fam = AF_INET; + } +-#endif /* defined(HASIPv6) */ + + /* + * Enter local and remote addresses by address family. +@@ -441,13 +566,20 @@ process_socket(sa) + if (fa || la) + (void) ent_inaddr(la, lp, fa, fp, fam); + if (ts == 0) { ++ struct xtcpcb *tcp_pcb = (struct xtcpcb *)pcb; + Lf->lts.type = 0; +- Lf->lts.state.i = (int)t.t_state; ++#if __FreeBSD_version >= 1200026 ++ Lf->lts.state.i = (int)tcp_pcb->t_state; ++#endif + + #if defined(HASTCPOPT) +- Lf->lts.mss = (unsigned long)t.t_maxseg; ++#if defined(HAS_XTCPCB_TMAXSEG) ++ Lf->lts.mss = (unsigned long)tcp_pcb->t_maxseg; + Lf->lts.msss = (unsigned char)1; +- Lf->lts.topt = (unsigned int)t.t_flags; ++#endif /* defined(HAS_XTCPCB_TMAXSEG) */ ++#if __FreeBSD_version >= 1200026 ++ Lf->lts.topt = (unsigned int)tcp_pcb->t_flags; ++#endif + #endif /* defined(HASTCPOPT) */ + + } +@@ -457,8 +589,8 @@ process_socket(sa) + */ + case AF_ROUTE: + (void) snpf(Lf->type, sizeof(Lf->type), "rte"); +- if (s.so_pcb) +- enter_dev_ch(print_kptr((KA_T)(s.so_pcb), (char *)NULL, 0)); ++ if (s && s->so_pcb) ++ enter_dev_ch(print_kptr((KA_T)(s->so_pcb), (char *)NULL, 0)); + else + (void) snpf(Namech, Namechl, "no protocol control block"); + if (!Fsize) +@@ -468,6 +600,8 @@ process_socket(sa) + * Process a Unix domain socket. + */ + case AF_UNIX: ++ { ++ struct xunpcb *unix_pcb = (struct xunpcb *)pcb; + if (Funix) + Lf->sf |= SELUNX; + (void) snpf(Lf->type, sizeof(Lf->type), "unix"); +@@ -475,57 +609,15 @@ process_socket(sa) + * Read Unix protocol control block and the Unix address structure. + */ + +- enter_dev_ch(print_kptr(sa, (char *)NULL, 0)); +- if (kread((KA_T) s.so_pcb, (char *) &unp, sizeof(unp))) { ++ if (unix_pcb) ++ enter_dev_ch(print_kptr(unix_pcb->xu_socket.xso_so, (char *)NULL, 0)); ++ else { + (void) snpf(Namech, Namechl, "can't read unpcb at %s", +- print_kptr((KA_T)s.so_pcb, (char *)NULL, 0)); ++ print_kptr(kf->kf_un.kf_sock.kf_sock_pcb, (char *)NULL, 0)); + break; + } +- if ((struct socket *)sa != unp.unp_socket) { +- (void) snpf(Namech, Namechl, "unp_socket (%s) mismatch", +- print_kptr((KA_T)unp.unp_socket, (char *)NULL, 0)); +- break; +- } +- if (unp.unp_addr) { ++ ua = (struct sockaddr_un *)&kf->kf_sa_local; + +- if (kread((KA_T)unp.unp_addr, (char *)&un, sizeof(un))) +- +- { +- (void) snpf(Namech, Namechl, "can't read unp_addr at %s", +- print_kptr((KA_T)unp.unp_addr, (char *)NULL, 0)); +- break; +- } +- +- ua = &un; +- +- } +- if (!ua) { +- ua = &un; +- (void) bzero((char *)ua, sizeof(un)); +- ua->sun_family = AF_UNSPEC; +- } +- /* +- * Print information on Unix socket that has no address bound +- * to it, although it may be connected to another Unix domain +- * socket as a pipe. +- */ +- if (ua->sun_family != AF_UNIX) { +- if (ua->sun_family == AF_UNSPEC) { +- if (unp.unp_conn) { +- if (kread((KA_T)unp.unp_conn, (char *)&uc, sizeof(uc))) +- (void) snpf(Namech, Namechl, +- "can't read unp_conn at %s", +- print_kptr((KA_T)unp.unp_conn,(char *)NULL,0)); +- else +- (void) snpf(Namech, Namechl, "->%s", +- print_kptr((KA_T)uc.unp_socket,(char *)NULL,0)); +- } else +- (void) snpf(Namech, Namechl, "->(none)"); +- } else +- (void) snpf(Namech, Namechl, "unknown sun_family (%d)", +- ua->sun_family); +- break; +- } + if (ua->sun_path[0]) { + + unl = ua->sun_len - offsetof(struct sockaddr_un, sun_path); +@@ -537,9 +629,26 @@ process_socket(sa) + Lf->sf |= SELNM; + if (ua->sun_path[0] && !Namech[0]) + (void) snpf(Namech, Namechl, "%s", ua->sun_path); ++ } else if (kf->kf_un.kf_sock.kf_sock_unpconn) { ++ struct xsocket *peer_socket = NULL; ++ void *peer_pcb; ++ find_pcb_and_xsocket(pcbs, ++ kf->kf_sock_domain, ++ kf->kf_sock_type, ++ kf->kf_un.kf_sock.kf_sock_unpconn, ++ &peer_pcb, ++ &peer_socket); ++ if (!peer_socket) ++ (void) snpf(Namech, Namechl, ++ "can't read unp_conn at %s", ++ print_kptr((KA_T)kf->kf_un.kf_sock.kf_sock_unpconn,(char *)NULL,0)); ++ else ++ (void) snpf(Namech, Namechl, "->%s", ++ print_kptr((KA_T)peer_socket->xso_so,(char *)NULL,0)); + } else +- (void) snpf(Namech, Namechl, "no address"); ++ (void) snpf(Namech, Namechl, "->(none)"); + break; ++ } + default: + printunkaf(fam, 1); + } diff --git a/sysutils/lsof/files/patch-dialects_freebsd_dzfs.h b/sysutils/lsof/files/patch-dialects_freebsd_dzfs.h new file mode 100644 index 000000000000..0babbe715fd4 --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_dzfs.h @@ -0,0 +1,111 @@ +--- dialects/freebsd/dzfs.h.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/dzfs.h +@@ -1,108 +0,0 @@ +-/* +- * dzfs.h - FreeBSD header file for ZFS +- */ +- +- +-/* +- * Copyright 2008 Purdue Research Foundation, West Lafayette, Indiana +- * 47907. All rights reserved. +- * +- * Written by Victor A. Abell +- * +- * This software is not subject to any license of the American Telephone +- * and Telegraph Company or the Regents of the University of California. +- * +- * Permission is granted to anyone to use this software for any purpose on +- * any computer system, and to alter it and redistribute it freely, subject +- * to the following restrictions: +- * +- * 1. Neither the authors nor Purdue University are responsible for any +- * consequences of the use of this software. +- * +- * 2. The origin of this software must not be misrepresented, either by +- * explicit claim or by omission. Credit to the authors and Purdue +- * University must appear in documentation and sources. +- * +- * 3. Altered versions must be plainly marked as such, and must not be +- * misrepresented as being the original software. +- * +- * 4. This notice may not be removed or altered. +- */ +- +- +-/* +- * $Id: dzfs.h,v 1.3 2011/08/07 22:51:28 abe Exp $ +- */ +- +- +-#if !defined(FREEBSD_ZFS_H) +-#define FREEBSD_ZFS_H 1 +-# if defined(HAS_ZFS) +- +- +-/* +- * The _PROTOTYPE macro provides strict ANSI C prototypes if __STDC__ +- * is defined, and old-style K&R prototypes otherwise. +- * +- * (With thanks to Andy Tanenbaum) +- */ +- +-# if defined(__STDC__) +-#define _PROTOTYPE(function, params) function params +-# else /* !defined(__STDC__) */ +-#define _PROTOTYPE(function, params) function() +-# endif /* defined(__STDC__) */ +- +- +-/* +- * The following define keeps gcc>=2.7 from complaining about the failure +- * of the Exit() function to return. +- * +- * Paul Eggert supplied it. +- */ +- +-# if defined(__GNUC__) && !(__GNUC__<2 || (__GNUC__==2 && __GNUC_MINOR__<7)) +-#define exiting __attribute__((__noreturn__)) +-# else /* !gcc || gcc<2.7 */ +-#define exiting +-# endif /* gcc && gcc>=2.7 */ +- +-# if !defined(INODETYPE) +-#define INODETYPE unsigned long long +-# endif /* !defined(INODETYPE) */ +- +-# if !defined(FREEBSD_KA_T) +-typedef u_long KA_T; +-#define FREEBSD_KA_T 1 /* for dlsof.h */ +-# endif /* !defined(FREEBSD_KA_T) */ +- +-# if !defined(READLEN_T) +-#define READLEN_T int +-# endif /* !defined(READLEN_T) */ +- +-# if !defined(SZOFFTYPE) +-#define SZOFFTYPE unsigned long long +-# endif /* !defined(SZOFFTYPE) */ +- +- +-/* +- * Structure for passing znode info +- */ +- +-typedef struct zfs_info { +- INODETYPE ino; /* inode number */ +- KA_T lockf; /* znode's z_lockf pointer */ +- long nl; /* number of links */ +- dev_t rdev; /* "raw" device number */ +- SZOFFTYPE sz; /* size */ +- unsigned char ino_def; /* ino defined status */ +- unsigned char nl_def; /* nl defined status */ +- unsigned char rdev_def; /* rdev defined status */ +- unsigned char sz_def; /* sz defined status */ +-} zfs_info_t; +- +-_PROTOTYPE(extern int kread,(KA_T addr, char *buf, READLEN_T len)); +-_PROTOTYPE(extern char *readzfsnode,(KA_T va, zfs_info_t *zi, int vr)); +- +-# endif /* defined(HAS_ZFS) */ +-#endif /* defined(FREEBSD_DZFS_H) */ diff --git a/sysutils/lsof/files/patch-dialects_freebsd_machine.h b/sysutils/lsof/files/patch-dialects_freebsd_machine.h new file mode 100644 index 000000000000..8041937ac90c --- /dev/null +++ b/sysutils/lsof/files/patch-dialects_freebsd_machine.h @@ -0,0 +1,38 @@ +--- dialects/freebsd/machine.h.orig 2022-04-27 22:38:44 UTC ++++ dialects/freebsd/machine.h +@@ -295,7 +295,7 @@ typedef _Bool bool; + * NCACHELDSFX is a set of C commands to execute after calling ncache_load(). + */ + +-#define HASNCACHE 1 ++/* #define HASNCACHE 1 */ + /* #define NCACHELDPFX ??? */ + /* #define NCACHELDSFX ??? */ + +@@ -316,7 +316,7 @@ typedef _Bool bool; + * NOTE: don't forget to define a prototype for this function in dproto.h. + */ + +-#define HASPIPEFN process_pipe ++/* #define HASPIPEFN process_pipe */ + + + /* +@@ -437,7 +437,7 @@ typedef _Bool bool; + * NOTE: don't forget to define a prototype for this function in dproto.h. + */ + +-#define HASPTSFN process_pts ++/* #define HASPTSFN process_pts */ + + + /* +@@ -622,7 +622,7 @@ typedef _Bool bool; + #define USE_LIB_IS_FILE_NAMED 1 /* isfn.c */ + #define USE_LIB_LKUPDEV 1 /* lkud.c */ + #define USE_LIB_PRINTDEVNAME 1 /* pdvn.c */ +-#define USE_LIB_PROCESS_FILE 1 /* prfp.c */ ++/* #define USE_LIB_PROCESS_FILE 1 */ /* prfp.c */ + #define USE_LIB_PRINT_TCPTPI 1 /* ptti.c */ + #define USE_LIB_READDEV 1 /* rdev.c */ + /* #define USE_LIB_READMNT 1 rmnt.c */