summaryrefslogtreecommitdiff
path: root/00PORTING
diff options
context:
space:
mode:
authorPatrick McCarty <patrick.mccarty@linux.intel.com>2013-02-08 13:26:27 -0800
committerPatrick McCarty <patrick.mccarty@linux.intel.com>2013-02-08 13:26:27 -0800
commit9bb81f8a90ecc8b70c955bff72ec59dd3d9e5ae7 (patch)
tree881eebfa461e4f8aa6b6f44b96ac0decd3bc887a /00PORTING
downloadlsof-9bb81f8a90ecc8b70c955bff72ec59dd3d9e5ae7.tar.gz
lsof-9bb81f8a90ecc8b70c955bff72ec59dd3d9e5ae7.tar.bz2
lsof-9bb81f8a90ecc8b70c955bff72ec59dd3d9e5ae7.zip
Imported Upstream version 4.87upstream/4.87
Diffstat (limited to '00PORTING')
-rw-r--r--00PORTING1838
1 files changed, 1838 insertions, 0 deletions
diff --git a/00PORTING b/00PORTING
new file mode 100644
index 0000000..2683946
--- /dev/null
+++ b/00PORTING
@@ -0,0 +1,1838 @@
+
+ Guide to Porting lsof 4 to Unix OS Dialects
+
+**********************************************************************
+| The latest release of lsof is always available via anonymous ftp |
+| from lsof.itap.purdue.edu. Look in pub/lsof.README for its |
+| location. |
+**********************************************************************
+
+ Contents
+
+ How Lsof Works
+ /proc-based Linux Lsof -- a Different Approach
+ General Guidelines
+ Organization
+ Source File Naming Conventions
+ Coding Philosophies
+ Data Requirements
+ Dlsof.h and #include's
+ Definitions That Affect Compilation
+ Options: Common and Special
+ Defining Dialect-Specific Symbols and Global Storage
+ Coding Dialect-specific Functions
+ Function Prototype Definitions and the _PROTOTYPE Macro
+ The Makefile
+ The Mksrc Shell Script
+ The MkKernOpts Shell Script
+ Testing and the lsof Test Suite
+ Where Next?
+
+
+How Lsof Works
+--------------
+
+Before getting on with porting guidelines, just a word or two about
+how lsof works.
+
+Lsof obtains data about open UNIX dialect files by reading the
+kernel's proc structure information, following it to the related
+user structure, then reading the open file structures stored
+(usually) in the user structure. Typically lsof uses the kernel
+memory devices, /dev/kmem, /dev/mem, etc. to read kernel data.
+
+Lsof stores information from the proc and user structures in an
+internal, local proc structure table. It then processes the open
+file structures by reading the file system nodes that lie behind
+them, extracting and storing relevant data in internal local file
+structures that are linked to the internal local process structure.
+
+Once all data has been gathered, lsof reports it from its internal,
+local tables.
+
+There are a few variants on this subject. Some systems don't have
+just proc structures, but have task structures, too, (e.g., NeXTSTEP
+and OSF/1 derivatives). For some dialects lsof gets proc structures
+or process information (See "/proc-based Linux Lsof -- a Different
+Approach) from files of the /proc file system. It's not necessary
+for lsof to read user structures on some systems (recent versions
+of HP-UX), because the data lsof needs can be found in the task or
+proc structures. In the end lsof gathers the same data, just from
+slightly different sources.
+
+
+/proc-based Linux Lsof -- a Different Approach
+==============================================
+
+For a completely different approach to lsof construction, take a
+look at the /proc-based Linux sources in .../dialects/linux/proc.
+(The sources in .../dialects/linux/kmem are for a traditional lsof
+that uses /dev/kmem to read information from kernel structures.)
+
+The /proc-based lsof obtains all its information from the Linux
+/proc file system. Consequently, it is relatively immune to changes
+in Linux kernel structures and doesn't need to be re-compiled each
+time the Linux kernel version changes.
+
+There are some down-sides to the Linux /proc-based lsof:
+
+ * It must run setuid-root in order to be able to read the
+ /proc file system branches for all processes. In contrast,
+ the /dev/kmem-based Linux lsof usually needs only setgid
+ permission.
+
+ * It depends on the exact character format of /proc files, so
+ it is sensitive to changes in /proc file composition.
+
+ * It is limited to the information a /proc file system
+ implementor decides to provide. For example, if a
+ /proc/net/<protocol> file lacks an inode number, the
+ /proc-based lsof can't connect open socket files to that
+ protocol. Another deficiency is that the /proc-based may
+ not be able to report file offset (position) information,
+ when it isn't available in the /proc/<PID>/fd/ entry for a
+ file.
+
+ In contrast the /dev/kmem-based lsof has full access to
+ kernel structures and "sees" new data as soon as it appears.
+ Of course, that new data requires that lsof be recompiled
+ and usually also requires changes to lsof.
+
+Overall the switch from a /dev/kmem base to a /proc one is an
+advantage to Linux lsof. The switch was made at lsof revision 4.23
+for Linux kernel versions 2.1.72 (approximately) and higher. The
+reason I'm not certain at which Linux kernel version a /proc-based
+lsof becomes possible is that the /proc additions needed to implement
+it have been added gradually to Linux 2.1.x in ways that I cannot
+measure.
+
+/proc-based lsof functions in many ways the same as /dev/kmem-based
+lsof. It scans the /proc directory, looking for <PID>/ subdirectories.
+Inside each one it collects process-related data from the cwd, exe,
+maps, root, and stat information files.
+
+It collects open file information from the fd/ subdirectory of each
+<PID>/ subdirectory. The lstat(2), readlink(2), and stat(2) system
+calls gather information about the files from the kernel.
+
+Lock information comes from /proc/locks. It is matched to open
+files by inode number. Mount information comes from /proc/mounts.
+Per domain protocol information comes from the files of /proc/net;
+it's matched to open socket files by inode number.
+
+The Linux /proc file system implementors have done an amazing job
+of providing the information lsof needs. The /proc-based lsof
+project has so far generated only two kernel modification:
+
+ * A modification to /usr/src/linux/net/ipx/af_ipx.c adds the
+ inode number to the entries of /proc/net/ipx.
+
+ Jonathan Sergent did this kernel modification.
+
+ It may be found in the .../dialects/linux/proc/patches
+ subdirectory of the lsof distribution.
+
+ * An experimental modification to /usr/src/linux/fs/stat.c
+ allows lstat(2) to return file position information for
+ /proc/<PID>/fd/<FD> files.
+
+ Contact me for this modification.
+
+
+One final note about the /proc-based Linux lsof: it doesn't need
+any functions from the lsof library in the lib/ subdirectory.
+
+
+General Guidelines
+------------------
+
+These are the general guidelines for porting lsof 4 to a new Unix
+dialect:
+
+ * Understand the organization of the lsof sources and the
+ philosophies that guide their coding.
+
+ * Understand the data requirements and determine the methods
+ of locating the necessary data in the new dialect's kernel.
+
+ * Pick a name for the subdirectory in lsof4/dialects for your
+ dialect. Generally I use a vendor operating system name
+ abbreviation.
+
+ * Locate the necessary header files and #include them in the
+ dialect's dlsof.h file. (You may not be able to complete
+ this step until you have coded all dialect-specific functions.)
+
+ * Determine the optional library functions of lsof to be used
+ and set their definitions in the dialect's machine.h file.
+
+ * Define the dialect's specific symbols and global storage
+ in the dialect's dlsof.h and dstore.c files.
+
+ * Code the dialect-specific functions in the appropriate
+ source files of the dialect's subdirectory.
+
+ Include the necessary prototype definitions of the dialect-
+ specific functions in the dproto.h file in the dialect's
+ subdirectory.
+
+ * Define the dialect's Makefile and source construction shell
+ script, Mksrc.
+
+ * If there are #define's that affect how kernel structures
+ are organized, and those #define's are needed when compiling
+ lsof, build a MkKernOpts shell script to locate the #define's
+ and supply them to the Configure shell script.
+
+
+Organization
+------------
+
+The code in a dialect-specific version of lsof comes from three
+sources:
+
+ 1) functions common to all versions, located in the top level
+ directory, lsof4;
+
+ 2) functions specific to the dialect, located in the dialect's
+ subdirectory -- e.g., lsof4/dialects/sun;
+
+ 3) functions that are common to several dialects, although
+ not to all, organized in a library, liblsof.a. The functions
+ in the library source can be selected and customized with
+ definitions in the dialect machine.h header files.
+
+The tree looks like this:
+
+ lsof4 ----------------------+ 3) library --
+ | \ lsof4/lib
+ 1) fully common functions + \
+ e.g., lsof4/main.c + lsof4/dialects/
+ / / / / \
+ + + + + +
+ 2) dialect-specific subdirectories -- e.g., lsof4/dialects/sun
+
+The code for a dialect-specific version is constructed from these
+three sources by the Configure shell script in the top level lsof4
+directory and definitions in the dialect machine.h header files.
+Configure uses the Mksrc shell script in each dialect's subdirectory,
+and may use an optional MkKernOpts shell script in selected dialect
+subdirectories.
+
+Configure calls the Mksrc shell script in each dialect's subdirectory
+to assemble the dialect-specific sources in the main lsof directory.
+Configure may call MkKernOpts to determine kernel compile-time
+options that are needed for compiling kernel structures correctly
+for use by lsof. Configure puts the options in a dialect-specific
+Makefile it build, using a template in the dialect subdirectory.
+
+The assembly of dialect-specific sources in the main lsof directory
+is usually done by creating symbolic links from the top level to
+the dialect's subdirectory. The LSOF_MKC environment variable may
+be defined prior to using Configure to change the technique used
+to assemble the sources -- most commonly to use cp instead of ln -s.
+
+The Configure script completes the dialect's Makefile by adding
+string definitions, including the necessary kernel compile-time
+options, to a dialect skeleton Makefile while copying it from the
+dialect subdirectory to the top level lsof4 directory. Optionally
+Makefile may call the dialect's MkKernOpts script to add string
+definitions.
+
+When the lsof library, lsof4/lib/liblsof.a, is compiled its
+functions are selected and customized by #define's in the dialect
+machine.h header file.
+
+
+Source File Naming Conventions
+------------------------------
+
+With one exception, dialect-specific source files begin with a
+lower case `d' character -- ddev.c, dfile.c, dlsof.h. The one
+exception is the header file that contains dialect-specific
+definitions for the optional features of the common functions.
+It's called machine.h for historical reasons.
+
+Currently all dialects use almost the same source file names. One
+exception to the rule happens in dialects where there must be
+different source files -- e.g., dnode[123].c -- to eliminate node
+header file structure element name conflicts. The source modules
+in a few subdirectories are organized that way.
+
+Unusual situations occur for NetBSD and OpenBSD, and for NEXTSTEP
+and OPENSTEP. Each pair of dialects is so close in design that
+the same dialect sources from the n+obsd subdirectory serves NetBSD
+and OpenBSD; from n+os, NEXTSTEP and OPENSTEP.
+
+These are common files in lsof4/:
+
+ Configure the configuration script
+
+ Customize does some customization of the selected lsof
+ dialect
+
+ Inventory takes an inventory of the files in an lsof
+ distribution
+
+ version the version number
+
+ dialects/ the dialects subdirectory
+
+These are the common function source files in lsof4/:
+
+ arg.c common argument processing functions
+
+ lsof.h common header file that #include's the dialect-specific
+ header files
+
+ main.c common main function for lsof 4
+
+ misc.c common miscellaneous functions -- e.g., special versions
+ of stat() and readlink()
+
+ node.c common node reading functions -- readinode(), readvnode()
+
+ print.c common print support functions
+
+ proc.c common process and file structure functions
+
+ proto.h common prototype definitions, including the definition of
+ the _PROTOTYPE() macro
+
+ store.c common global storage version.h the current lsof version
+ number, derived from the file version by the Makefile
+
+ usage.c functions to display lsof usage panel
+
+These are the dialect-specific files:
+
+ Makefile the Makefile skeleton
+
+ Mksrc a shell script that assists the Configure script
+ in configuring dialect sources
+
+ MkKernOpts an optional shell script that identifies kernel
+ compile-time options for selected dialects -- e.g.,
+ Pyramid DC/OSx and Reliant UNIX
+
+ ddev.c device support functions -- readdev() -- may be
+ eliminated by functions from lsof4/lib/
+
+ dfile.c file processing functions -- may be eliminated by
+ functions from lsof4/lib/
+
+ dlsof.h dialect-specific header file -- contains #include's
+ for system header files and dialect-specific global
+ storage declarations
+
+ dmnt.c mount support functions -- may be eliminated by
+ functions from lsof4/lib/
+
+ dnode.c node processing functions -- e.g., for gnode or vnode
+
+ dnode?.c additional node processing functions, used when node
+ header files have duplicate and conflicting element
+ names.
+
+ dproc.c functions to access, read, examine and cache data about
+ dialect-specific process structures -- this file contains
+ the dialect-specific "main" function, gather_proc_info()
+
+ dproto.h dialect-specific prototype declarations
+
+ dsock.c dialect-specific socket processing functions
+
+ dstore.c dialect-specific global storage -- e.g., the nlist()
+ structure
+
+ machine.h dialect specific definitions of common function options --
+ e.g., a HASINODE definition to activate the readinode()
+ function in lsof4/node.c
+
+ The machine.h header file also selects and customizes
+ the functions of lsof4/lib/.
+
+These are the lib/ files. Definitions in the dialect machine.h
+header files select and customize the contained functions that are
+to be compiled and archived to liblsof.a.
+
+ Makefile.skel is a skeleton Makefile, used by Configure
+ to construct the Makefile for the lsof
+ library.
+
+ cvfs.c completevfs() function
+
+ USE_LIB_COMPLETEVFS selects it.
+
+ CVFS_DEVSAVE, CVFS_NLKSAVE, CVFS_SZSAVE,
+ and HASFSINO customize it.
+
+ dvch.c device cache functions
+
+ HASDCACHE selects them.
+
+ DCACHE_CLONE, DCACHE_CLR, DCACHE_PSEUDO,
+ DVCH_CHOWN, DVCH_DEVPATH, DVCH_EXPDEV,
+ HASBLKDEV, HASENVDC, HASSYSDC, HASPERSDC,
+ HASPERSDCPATH, and NOWARNBLKDEV customize
+ them.
+
+ fino.c find block and character device inode functions
+
+ HASBLKDEV and USE_LIB_FIND_CH_INO select them.
+
+ isfn.c hashSfile() and is_file_named() functions
+
+ USE_LIB_IS_FILE_NAMED selects it.
+
+ lkud.c device lookup functions
+
+ HASBLKDEV and USE_LIB_LKUPDEV select them.
+
+ pdvn.c print device name functions
+
+ HASBLKDEV and USE_LIB_PRINTDEVNAME select them.
+
+ prfp.c process_file() function
+
+ USE_LIB_PROCESS_FILE selects it.
+
+ FILEPTR, DTYPE_PIPE, HASPIPEFN, DTYPE_GNODE,
+ DTYPE_INODE, DTYPE_PORT, DTYPE_VNODE,
+ HASF_VNODE, HASKQUEUE, HASPRIVFILETYPE,
+ HASPSXSHM and HASPSXSEM customize it.
+
+ ptti.c print_tcptpi() function
+
+ USE_LIB_PRINT_TCPTPI selects it.
+
+ HASSOOPT, HASSBSTATE, HASSOSTATE, AHSTCPOPT,
+ HASTCPTPIQ and HASTCPTPIW customize it.
+
+ rdev.c readdev() function
+
+ USE_LIB_READDEV selects it.
+
+ DIRTYPE, HASBLKDEV, HASDCACHE, HASDNAMLEN,
+ RDEV_EXPDEV, RDEV_STATFN, USE_STAT, and
+ WARNDEVACCESS customize it.
+
+ rmnt.c readmnt() function
+
+ USE_LIB_READMNT selects it.
+
+ HASFSTYPE, MNTSKIP, RMNT_EXPDEV, RMNT_FSTYPE,
+ and MOUNTS_FSTYPE customize it.
+
+ rnam.c BSD format name cache functions
+
+ HASNCACHE and USE_LIB_RNAM select them.
+
+ HASFSINO, NCACHE, NCACHE_NC_CAST, NCACHE_NM,
+ NCACHE_NMLEN, NCACHE_NODEADDR, NCACHE_NODEID,
+ NCACHE_NO_ROOT, NCACHE_NXT, NCACHE_PARADDR,
+ NCACHE_PARID, NCACHE_SZ_CAST, NCHNAMLEN,
+ X_NCACHE, and X_NCSIZE, customize them.
+
+ rnch.c Sun format name cache functions
+
+ HASNCACHE and USE_LIB_RNCH select them.
+
+ ADDR_NCACHE, HASDNLCPTR, HASFSINO, NCACHE_DP,
+ NCACHE_NAME, NCACHE_NAMLEN, NCACHE_NEGVN,
+ NCACHE_NODEID, NCACHE_NXT, NCACHE_PARID,
+ NCACHE_VP, X_NCACHE, and X_NCSIZE, customize
+ them.
+
+ snpf.c Source for the snprintf() family of functions
+
+ USE_LIB_SNPF selects it.
+
+
+The comments and the source code in these library files give more
+information on customization.
+
+
+Coding Philosophies
+-------------------
+
+A few basic philosophies govern the coding of lsof 4 functions:
+
+ * Use as few #if/#else/#endif constructs as possible, even at
+ the cost of nearly-duplicate code.
+
+ When #if/#else/#endif constructs are necessary:
+
+ o Use the form
+
+ #if defined(s<symbol>)
+
+ in preference to
+
+ #ifdef <symbol>
+
+ to allow easier addition of tests to the #if.
+
+ o Indent them to signify their level -- e.g.,
+
+ #if /* level one */
+ # if /* level two */
+ # endif /* level two */
+ #else /* level one */
+ #endif /* level one */
+
+ o Use ANSI standard comments on #else and #endif statements.
+
+ * Document copiously.
+
+ * Aim for ANSI-C compatibility:
+
+ o Use function prototypes for all functions, hiding them
+ from compilers that cannot handle them with the _PROTOTYPE()
+ macro.
+
+ o Use the compiler's ANSI conformance checking wherever
+ possible -- e.g., gcc's -ansi option.
+
+
+Data Requirements
+-----------------
+
+Lsof's strategy in obtaining open file information is to access
+the process table via its proc structures, then obtain the associated
+user area and open file structures. The open file structures then
+lead lsof to file type specific structures -- cdrnodes, fifonodes,
+inodes, gnodes, hsfsnodes, pipenodes, pcnodes, rnodes, snodes,
+sockets, tmpnodes, and vnodes.
+
+The specific node structures must yield data about the open files. The
+most important items and device number (raw and cooked) and node
+number. (Lsof uses them to identify files and file systems named as
+arguments.) Link counts and file sizes are important, too, as are the
+special characteristics of sockets, pipes, FIFOs, etc.
+
+This means that to begin an lsof port to a new Unix dialect you
+must understand how to obtain these structures from the dialect's
+kernel. Look for kernel access functions -- e.g., the AIX readx()
+function, Sun and Sun-like kvm_*() functions, or SGI's syssgi()
+function. Look for clues in header files -- e.g. external declarations
+and macros.
+
+If you have access to them, look at sources to programs like ps(1),
+or the freely available monitor and top programs. They may give
+you important clues on reading proc and user area structures. An
+appeal to readers of dialect-specific news groups may uncover
+correspondents who can help.
+
+Careful reading of system header files -- e.g., <sys/proc.h> --
+may give hints about how kernel storage is organized. Look for
+global variables declared under a KERNEL or _KERNEL #if. Run nm(1)
+across the kernel image (/vmunix, /unix, etc.) and look for references
+to structures of interest.
+
+Even if there are support functions for reading structures, like the
+kvm_*() functions, you must still understand how to read data from
+kernel memory. Typically this requires an understanding of the
+nlist() function, and how to use /dev/kmem, /dev/mem, and /dev/swap.
+
+Don't overlook the possibility that you may have to use the process
+file system -- e.g., /proc. I try to avoid using /proc when I can,
+since it usually requires that lsof have setuid(root) permission
+to read the individual /proc "files".
+
+Once you can access kernel structures, you must understand how
+they're connected. You must answer questions like:
+
+ * How big are kernel addresses? How are they type cast?
+
+ * How are kernel variable names converted to addresses?
+ Nlist()?
+
+ * How are the proc structures organized? Is it a static
+ table? Are the proc structures linked? Is there a
+ kernel pointer to the first proc structure? Is there a
+ proc structure count?
+
+ * How does one obtain copies of the proc structures? Via
+ /dev/kmem? Via a vendor API?
+
+ * If this is a Mach derivative, is it necessary to obtain the
+ task and thread structures? How?
+
+ * How does one obtain the user area (or the utask area in Mach
+ systems) that corresponds to a process?
+
+ * Where are the file structures located for open file
+ descriptors and how are they located? Are all file
+ structures in the user area? Is the file structure space
+ extensible?
+
+ * Where do the private data pointers in file structures lead?
+ To gnodes? To inodes? To sockets? To vnodes? Hint: look
+ in <sys/file.h> for DTYPE_* instances and further pointers.
+
+ * How are the nodes organized? To what other nodes do they
+ lead and how? Where are the common bits of information in
+ nodes -- device, node number, size -- stored? Hint: look
+ in the header files for nodes for macros that may be used
+ to obtain the address of one node from another -- e.g., the
+ VTOI() macro that leads from a vnode to an inode.
+
+ * Are text reference nodes identified and how? Is it
+ necessary to examine the virtual memory map of a process or
+ a task to locate text references? Some kernels have text
+ node pointers in the proc structures; some, in the user
+ area; Mach kernels may have text information in the task
+ structure, reached in various ways from the proc, user area,
+ or user task structure.
+
+ * How is the device table -- e.g., /dev or /devices --
+ organized? How is it read? Using direct or dirent structures?
+
+ How are major/minor device numbers represented? How are
+ device numbers assembled and disassembled?
+
+ Are there clone devices? How are they identified?
+
+ * How is mount information obtained? Getmntinfo()? Getmntent()?
+ Some special kernel call?
+
+ * How are sockets identified and organized? BSD-style? As
+ streams? Are there streams?
+
+ * Are there special nodes -- CD-ROM nodes, FIFO nodes, etc.?
+
+ * How is the kernel's name cache organized? Can lsof access
+ it to get partial name components?
+
+
+Dlsof.h and #include's
+----------------------
+
+Once you have identified the kernel's data organization and know
+what structures it provides, you must add #include's to dlsof.h to
+access their definitions. Sometimes it is difficult to locate the
+header files -- you may need to introduce -I specifications in the
+Makefile via the DINC shell variable in the Configure script.
+
+Sometimes it is necessary to define special symbols -- e.g., KERNEL,
+_KERNEL, _KMEMUSER -- to induce system header files to yield kernel
+structure definitions. Sometimes making those symbol definitions
+cause other header file and definition conflicts. There's no good
+general rule on how to proceed when conflicts occur.
+
+Rarely it may be necessary to extract structure definitions from
+system header files and move them to dlsof.h, create special versions
+of system header files, or obtain special copies of system header
+files from "friendly" (e.g., vendor) sources. The dlsof.h header
+file in lsof4/dialects/sun shows examples of the first case; the
+second, no examples; the third, the irix5hdr subdirectory in
+lsof4/dialects/irix (a mixture of the first and third).
+
+Building up the necessary #includes in dlsof.h is an iterative
+process that requires attention as you build the dialect-specific
+functions that references kernel structures. Be prepared to revisit
+dlsof.h frequently.
+
+
+Definitions That Affect Compilation
+-----------------------------------
+
+The source files at the top level and in the lib/ subdirectory
+contain optional functions that may be activated with definitions
+in a dialect's machine.h header file. Some are functions for
+reading node structures that may not apply to all dialects -- e.g.
+CD-ROM nodes (cdrnode), or `G' nodes (gnode) -- and others are
+common functions that may occasionally be replaced by dialect-specific
+ones. Once you understand your kernel's data organization, you'll
+be able to decide the optional common node functions to activate.
+
+Definitions in machine.h and dlsof.h also enable or disable other
+optional common features. The following is an attempt to list all
+the definitions that affect lsof code, but CAUTION, it is only
+attempt and may be incomplete. Always check lsof4 source code in
+lib/ and dialects/, and dialect machine.h header files for other
+possibilities
+
+ AFS_VICE See 00XCONFIG.
+
+ AIX_KERNBITS specifies the kernel bit size, 32 or 64, of the Power
+ architecture AIX 5.x kernel for which lsof was built.
+
+ CAN_USE_CLNT_CREATE is defined for dialects where the more modern
+ RPC function clnt_create() can be used in
+ place of the deprecated clnttcp_create().
+
+ CLONEMAJ defines the name of the variable that
+ contains the clone major device number.
+ (Also see HAS_STD_CLONE and HAVECLONEMAJ.)
+
+ DEVDEV_PATH defines the path to the directory where device
+ nodes are stored, usually /dev. Solaris 10
+ uses /devices.
+
+ DIALECT_WARNING may be defined by a dialect to provide a
+ warning message that will be displayed with
+ help (-h) and version (-v) output.
+
+ FSV_DEFAULT defines the default file structure values to
+ list. It may be composed of or'd FSV_*
+ (See lsof.h) values. The default is none (0).
+
+ GET_MAJ_DEV is a macro to get major portion from device
+ number instead of via the standard major()
+ macro.
+
+ GET_MIN_DEV is a macro to get minor portion from device
+ number instead of via the standard minor()
+ macro.
+
+ GET_MAX_FD the name of the function that returns an
+ int for the maximum open file descriptor
+ plus one. If not defined, defaults to
+ getdtablesize.
+
+ HAS9660FS enables CD9660 file system support in a
+ BSD dialect.
+
+ HAS_ADVLOCK_ARGS is defined for NetBSD and OpenBSD dialects
+ whose <sys/lockf.h> references vop_advlock_args.
+
+ HAS_AFS enables AFS support code for the dialect.
+
+ HAS_ATOMIC_T indicates the Linux version has an
+ <asm/atomic.h> header file and it contains
+ "typedef struct .* atomic_t;"
+
+ HASAOPT indicates the dialect supports the AFS -A
+ option when HAS_AFS is also defined.
+
+ HAS_ASM_TERMIOBITS indicates for Linux Alpha that the
+ <asm/termiobits.h> header file exists.
+
+ HASAX25CBPTR indicates that the Linux sock struct has an
+ ax25_db pointer.
+
+ HASBLKDEV indicates the dialect has block device support.
+
+ HASBUFQ_H indicates the *NSD dialect has the <sys/bufq.h>
+ header file.
+
+ HASCACHEFS enables cache file system support for the
+ dialect.
+
+ HAS_CDFS enables CDFS file system support for the
+ dialect.
+
+ HASCDRNODE enables/disables readcdrnode() in node.c.
+
+ HAS_CONN_NEW indicates the Solaris version has the new form
+ of the conn_s structure, introduced in b134 of
+ Solaris 11. This will always accompany the
+ HAS_IPCLASSIFIER_H definition.
+
+ HAS_CONST indicates that the compiler supports the
+ const keyword.
+
+ HASCPUMASK_T indicates the FreeBSD 5.2 or higher dialect
+ has cpumask_t typedef's.
+
+ HAS_CRED_IMPL_H indicates the Solaris 10 dialect has the
+ <sys/cred_impl.h> header file available.
+
+ HASCWDINFO indicates the cwdinfo structure is defined
+ in the NetBSD <sys/filedesc.h>.
+
+ HASDCACHE enables device file cache file support.
+ The device cache file contains information
+ about the names, device numbers and inode
+ numbers of entries in the /dev (or /device)
+ node subtree that lsof saves from call to
+ call. See the 00DCACHE file of the lsof
+ distribution for more information on this
+ feature.
+
+ HASDENTRY indicates the Linux version has a dentry
+ struct defined in <linux/dcache.h>.
+
+ HASDEVKNC indicates the Linux version has a kernel
+ name cached keyed on device number.
+
+ HAS_DINODE_U indicates the OpenBSD version has a dinode_u
+ union in its inode structure.
+
+ HASDNLCPTR is defined when the name cache entry of
+ <sys/dnlc.h> has a name character pointer
+ rather than a name character array.
+
+ HASEFFNLINK indicates the *BSD system has the i_effnlink
+ member in the inode structure.
+
+ HASENVDC enables the use of an environment-defined
+ device cache file path and defines the name
+ of the environment variable from which lsof
+ may take it. (See the 00DCACHE file of
+ the lsof distribution for information on
+ when HASENVDC is used or ignored.)
+
+ HASEOPT indicates the dialect supports the -e option to
+ eliminate kernel blocks on a named file system.
+
+ HASEXT2FS is defined for BSD dialects for which ext2fs
+ file system support can be provided. A value
+ of 1 indicates that the i_e2din member does not
+ exist; 2, it exists.
+
+ HASF_VNODE indicates the dialect's file structure has an
+ f_vnode member in it.
+
+ HASFDESCFS enables file descriptor file system support
+ for the dialect. A value of 1 indicates
+ <miscfs/fdesc.h> has a Fctty definition; 2,
+ it does not.
+
+ HASFDLINK indicates the file descriptor file system
+ node has the fd_link member.
+
+ HASFIFONODE enables/disables readfifonode() in node.c.
+
+ HAS_FL_FD indicates the Linux version has an fl_fd
+ element in the lock structure of <linux/fs.h>.
+
+ HAS_FL_FILE indicates the Linux version has an fl_file
+ element in the lock structure of <linux/fs.h>.
+
+ HAS_FL_WHENCE indicates the Linux version has an fl_whence
+ element in the lock structure of <linux/fs.h>.
+
+ HAS_F_OPEN indicates the UnixWare 7.x dialect has the
+ f_open member in its file struct.
+
+ HASFSINO enables the inclusion of the fs_ino element
+ in the lfile structure definition in lsof.h.
+ This contains the file system's inode number
+ and may be needed when searching the kernel
+ name cache. See dialects/osr/dproc.c for
+ an example.
+
+ HAS_JFS2 The AIX >= 5.0 dialect has jfs2 support.
+
+ HASFSTRUCT indicates the dialect has a file structure
+ the listing of whose element values can be
+ enabled with +f[cfn]. FSV_DEFAULT defines
+ the default listing values.
+
+ HASFSTYPE enables/disables the use of the file system's
+ stat(2) st_fstype member.
+
+ If the HASFSTYPE value is 1, st_fstype is
+ treated as a character array; 2, it is
+ treated as an integer.
+
+ See also the RMNT_EXPDEV and RMNT_FSTYPE
+ documentation in lib/rmnt.c
+
+ HASGETBOOTFILE indicates the NetBSD or OpenBSD dialect has
+ a getbootfile() function.
+
+ HASGNODE enables/disables readgnode() in node.c.
+
+ HASHASHPID is defined when the Linux version (probably
+ above 2.1.35) has a pidhash_next member in
+ its task structure.
+
+ HASHSNODE enables/disables readhsnode() in node.c.
+
+ HASI_E2FS_PTR indicates the BSD dialect has a pointer in
+ its inode to the EXTFS dinode.
+
+ HASI_FFS indicates the BSD dialect has i_ffs_size
+ in <ufs/ufs/inode.h>.
+
+ HASI_FFS1 indicates the BSD dialect supports the fast
+ UFS1 and UFS2 file systems.
+
+ HAS_INKERNEL indicates the SCO OSR 6.0.0 or higher, or
+ UnixWare 7.1.4 or higher system uses the
+ INKERNEL symbol in <netinet/in_pcb.h> or
+ <netinet/tcp_var.h>.
+
+ HASINODE enables/disables readinode() in node.c.
+
+ HASINOKNC indicates the Linux version has a kernel
+ name cache keyed on inode address.
+
+ HASINADDRSTR is defined when the inp_[fl]addr members
+ of the inpcb structure are structures.
+
+ HASINRIAIPv6 is defined if the dialect has the INRIA IPv6
+ support. (HASIPv6 will also be defined.)
+
+ HASINT16TYPE is defined when the dialect has a typedef
+ for int16 that may conflict with some other
+ header file's redefinition (e.g., <afs/std.h>).
+
+ HASINT32TYPE is defined when the dialect has a typedef
+ for int32 that may conflict with some other
+ header file's redefinition (e.g., <afs/std.h>).
+
+ HASINTSIGNAL is defined when signal() returns an int.
+
+ HAS_IPCLASSIFIER_H is defined for Solaris dialects that have the
+ <inet/ipclassifier.h> header file.
+
+ HAS_IPC_S_PATCH is defined when the HP-UX 11 dialect has the
+ ipc_s patch installed. It has a value of
+ 1 if the ipc_s structure has an ipc_ipis
+ member, but the ipis_s structure lacks the
+ ipis_msgsqueued member; 2, if ipc_s has
+ ipc_ipis, but ipis_s lacks ipis_msgsqueued.
+
+ HASIPv6 indicates the dialect supports the IPv6
+ Internet address family.
+
+ HASKERNELKEYT indicates the Linux version has a
+ __kernel_key_t typedef in <linux/types.h>.
+
+ HASKERNFS is defined for BSD dialects for which
+ /kern file system support can be provided.
+
+ HASKERNFS_KFS_KT indicates *kfs_kt is in the BSD dialect's
+ <miscfs/kernfs/kernfs.h>.
+
+ HASKOPT enables/disables the ability to read the
+ kernel's name list from a file -- e.g., from
+ a crash dump file.
+
+ HASKQUEUE indicates the dialect supports the kqueue
+ file type.
+
+ HASKVMGETPROC2 The *BSD dialect has the kvm_gettproc2()
+ function.
+
+ HAS_KVM_VNODE indicates the FreeBSD 5.3 or higher dialect has
+ "defined(_KVM_VNODE)" in <sys/vnode.h>.
+
+ HASLFILEADD defines additional, dialect-specific elements
+ SETLFILEADD in the lfile structure (defined in lsof.h).
+ HASLFILEADD is a macro. The accompanying SETFILEADD
+ macro is used in the alloc_lfile() function of
+ proc.c to preset the additional elements.
+
+ HAS_LF_LWP is defined for BSD dialects where the lockf
+ structure has an lf_lwp member.
+
+ HASLFS indicates the *BSD dialect has log-structured
+ file system support.
+
+ HAS_LGRP_ROOT_CONFLICT
+ indicates the Solaris 9 or Solaris 10 system has
+ a conflict over the lgrp_root symbol in the
+ <sys/lgrp.h> and <sys/lgrp_user.h> header files.
+
+ HAS_LIBCTF indicates the Solaris 10 and above system has
+ the CTF library.
+
+ HAS_LOCKF_ENTRY indicates the FreeBSD version has a lockf_entry
+ structure in its <sys/lockf.h> header file.
+
+ HAS_LWP_H is defined for BSD dialects that have the
+ <sys/lwp.h> header file.
+
+ HASMOPT enables/disables the ability to read kernel
+ memory from a file -- e.g., from a crash
+ dump file.
+
+ HASMSDOSFS enables MS-DOS file system support in a
+ BSD dialect.
+
+ HASMNTSTAT indicates the dialect has a stat(2) status
+ element in its mounts structure.
+
+ HASMNTSUP indicates the dialect supports the mount supplement
+ option.
+
+ HASNAMECACHE indicates the FreeBSD dialect has a namecache
+ structure definition in <sys/namei.h>.
+
+ HASNCACHE enables the probing of the kernel's name cache
+ to obtain path name components. A value
+ of 1 directs printname() to prefix the
+ cache value with the file system directory
+ name; 2, avoid the prefix.
+
+ HASNCVPID The *BSD dialect namecache struct has an
+ nc_vpid member.
+
+ HASNETDEVICE_H indicates the Linux version has a netdevice.h
+ header file.
+
+ HAS_NFS enables NFS support for the dialect.
+
+ HASNFSKNC indicates the LINUX version has a separate
+ NFS name cache.
+
+ HASNFSPROTO indicates the NetBSD or OpenBSD version
+ has the nfsproto.h header file.
+
+ HASNFSVATTRP indicates the n_vattr member of the nfsnode of
+ the *BSD dialect is a pointer.
+
+ HASNLIST enables/disables nlist() function support.
+ (See NLIST_TYPE.)
+
+ HASNOFSADDR is defined if the dialect has no file structure
+ addresses. (HASFSTRUCT must be defined.)
+
+ HASNOFSCOUNT is defined if the dialect has no file structure counts.
+ (HASFSTRUCT must be defined.)
+
+ HASNOFSFLAGS is defined if the dialect has no file structure flags.
+ (HASFSTRUCT must be defined.)
+
+ HASNOFSNADDR is defined if the dialect has no file structure node
+ addresses. (HASFSTRUCT must be defined.)
+
+ HAS_NO_6PORT is defined if the FreeBSD in_pcb.h has no in6p_.port
+ definitions.
+
+ HAS_NO_6PPCB is defined if the FreeBSD in_pcb.h has no in6p_ppcb
+ definition.
+
+ HAS_NO_ISO_DEV indicates the FreeBSD 6 and higher system has
+ no i_dev member in its iso_node structure.
+
+ HAS_NO_LONG_LONG indicates the dialect has no support for the C
+ long long type. This definition is used by
+ the built-in snprintf() support of lib/snpf.c.
+
+ HASNORPC_H indicates the dialect has no /usr/include/rpc/rpc.h
+ header file.
+
+ HAS_NO_SI_UDEV indicates the FreeBSD 6 and higher system has
+ no si_udev member in its cdev structure.
+
+ HASNOSOCKSECURITY enables the listing of open socket files,
+ even when HASSECURITY restricts listing of
+ open files to the UID of the user who is
+ running lsof, provided socket file listing
+ is selected with the "-i" option. This
+ definition is only effective when HASSECURITY
+ is also defined.
+
+ HASNULLFS indicates the dialect (usually *BSD) has a
+ null file system.
+
+ HASOBJFS indicates the Pyramid version has OBJFS
+ support.
+
+ HASONLINEJFS indicates the HP-UX 11 dialect has the optional
+ OnlineJFS package installed.
+
+ HAS_PC_DIRENTPERSEC
+ indicates the Solaris 10 system's <sys/fs/pc_node.h>
+ header file has the pc_direntpersec() macro.
+
+ HAS_PAD_MUTEX indicates the Solaris 11 system has the pad_mutex_t
+ typedef in its <sys/mutex.h> header file.
+
+ HASPERSDC enables the use of a personal device cache
+ file path and specifies a format by which
+ it is constructed. See the 00DCACHE file
+ of the lsof distribution for more information
+ on the format.
+
+ HASPERSDCPATH enables the use of a modified personal
+ device cache file path and specifies the
+ name of the environment variable from which
+ its component may be taken. See the 00DCACHE
+ file of the lsof distribution for more
+ information on the modified personal device
+ cache file path.
+
+ HASPINODEN declares that the inode number of a /proc file
+ should be stored in its procfsid structure.
+
+ HASPIPEFN defines the function that processes DTYPE_PIPE
+ file structures. It's used in the prfp.c
+ library source file. See the FreeBSD
+ dialect source for an example.
+
+ HASPIPENODE enables/disables readpipenode() in node.c.
+
+ HASPMAPENABLED enables the automatic reporting of portmapper
+ registration information for TCP and UDP
+ ports that have been registered.
+
+ HASPPID indicates the dialect has parent PID support.
+
+ HASPR_LDT indicates the Solaris dialect has a pr_ldt
+ member in the pronodetype enum.
+
+ HASPR_GWINDOWS indicates the Solaris dialect has a pr_windows
+ member in the pronodetype enum.
+
+ HASPRINTDEV this value defines a private function for
+ printing the dialect's device number. Used
+ by print.c/print_file(). Takes one argument:
+
+ char *HASPRINTDEV(struct lfile *)
+
+ HASPRINTINO this value names a private function for
+ printing the dialect's inode number. Used
+ by print.c/print_file(). Takes one argument:
+
+ char *HASPRINTINO(struct lfile *)
+
+ HASPRINTNM this value names a private function for
+ printing the dialect's file name. Used by
+ print.c/print_file(). Takes one argument:
+
+ void HASPRINTNM(struct lfile *)
+
+ HASPRINTOFF this value names a private function for
+ printing the dialect's file offset. Used
+ by print.c/print_file(). Takes two arguments:
+
+ char *HASPRINTOFF(struct lfile *, int ty)
+
+ Where ty == 0 if the offset is to be printed
+ in 0t<decimal> format; 1, 0x<hexadecimal>.
+
+ HASPRINTSZ this value names a private function for
+ printing the dialect's file size. Used
+ by print.c/print_file(). Takes one argument:
+
+ char *HASPRINTSZ(struct lfile *)
+
+ void HASPRINTNM(struct lfile *)
+
+ HASPRIVFILETYPE enables processing of the private file
+ type, whose number (from f_type of the file
+ struct) is defined by PRIVFILETYPE.
+ HASPRIVFILETYPE defines the function that
+ processes the file struct's f_data member.
+ Processing is initiated from the process_file()
+ function of the prfp.c library source file
+ or from the dialect's own process_file()
+ function.
+
+ HASPRIVNMCACHE enables printing of a file path from a
+ private name cache. HASPRIVNMCACHE defines
+ the name of the printing function. The
+ function takes one argument, a struct lfile
+ pointer to the file, and returns non-zero
+ if it prints a cached name to stdout.
+
+ HASPRIVPRIPP is defined for dialects that have a private
+ function for printing the IP protocol name.
+ When this is not defined, the function to
+ do that defaults to printiproto().
+
+ HASPROCFS defines the name (if any) of the process file
+ system -- e.g., /proc.
+
+ HASPROCFS_PFSROOT indicates PFSroot is in the BSD dialect's
+ <miscfs/procfs/procfs.h>.
+
+ HASPSEUDOFS indicates the FreeBSD dialect has pseudofs
+ file system support.
+
+ HASPSXSEM indicates the dialect has support for the POSIX
+ semaphore file type.
+
+ HASPSXSHM indicates the dialect has support for the POSIX
+ shared memory file type.
+
+ HASPTYFS indicates the *BSD dialect has a ptyfs file system.
+
+ HASRNODE enables/disables readrnode() in node.c.
+
+ HASRNODE3 indicates the HPUX 10.20 or lower dialect has NFS3
+ support with a modified rnode structure.
+
+ HASRPCV2H The FreeBSD dialect has <nfs/rpcv2.h>.
+
+ HAS_SANFS indicates the AIX system has SANFS file system
+ support.
+
+ HASSBSTATE indicates the dialect has socket buffer state
+ information (e.g., SBS_* symbols) available.
+
+ HASSECURITY enables/disables restricting open file
+ information access. (Also see HASNOSOCKSECURITY.)
+
+ HASSELINUX indicates the Linux dialect has SELinux security
+ context support available.
+
+ HASSETLOCALE is defined if the dialect has <locale.h> and
+ setlocale().
+
+ HAS_SI_PRIV indicates the FreeBSD 6.0 and higher cdev
+ structure has an si_priv member.
+
+ HAS_SOCKET_PROTO_H indicates the Solaris 10 system has the header file
+ <sys/socket_proto.h>.
+
+ HASSOUXSOUA indicates that the Solaris <sys/socketvar.h> has
+ soua_* members in its so_ux_addr structure.
+
+ HASSPECDEVD indicates the dialect has a special device
+ directory and defines the name of a function
+ that processes the results of a successful
+ stat(2) of a file in that directory.
+
+ HASSPECNODE indicates the DEC OSF/1, or Digital UNIX,
+ or Tru64 UNIX <sys/specdev.h> has a spec_node
+ structure definition.
+
+ HASSNODE indicates the dialect has snode support.
+
+ HAS_SOCKET_SK indicates that the Linux socket structure
+ has the ``struct sock *sk'' member.
+
+ HASSOOPT indicates the dialect has socket option
+ information (e.g., SO_* symbols) available.
+
+ HASSOSTATE indicates the dialect has socket state
+ information (e.g., SS_* symbols) available.
+
+ HASSTATVFS indicates the NetBSD dialect has a statvfs
+ struct definition.
+
+ HASSTAT64 indicates the dialect's <sys/stat.h> contains
+ stat64.
+
+ HAS_STD_CLONE indicates the dialect uses a standard clone
+ device structure that can be used in common
+ library function clone processing. If the
+ value is 1, the clone table will be built
+ by readdev() and cached when HASDCACHE is
+ defined; if the value is 2, it is assumed
+ the clone table is built independently.
+ (Also see CLONEMAJ and HAVECLONEMAJ.)
+
+ HASSTREAMS enables/disables streams. CAUTION, requires
+ specific support code in the dialect sources.
+
+ HAS_STRFTIME indicates the dialect has the gmtime() and
+ strftime() C library functions that support
+ the -r marker format option. Configure tests
+ for the functions and defines this symbol.
+
+ HASSYSDC enables the use of a system-wide device
+ cache file and defines its path. See the
+ 00DCACHE file of the lsof distribution for
+ more information on the system-wide device
+ cache file path option.
+
+ HAS_SYS_PIPEH indicates the dialect has a <sys/pipe.h>
+ header file.
+
+ HAS_SYS_SX_H indicates the FreeBSD 7.0 and higher system has
+ a <sys/sx.h> header file.
+
+ HASTAGTOPATH indicates the DEC OSF/1, Digital UNIX, or
+ Tru64 UNIX dialect has a libmsfs.so,
+ containing tag_to_path().
+
+ HASTMPNODE enables/disables readtnode() in node.c.
+
+ HASTCPOPT indicates the dialect has TCP option
+ information (i.e., from TF_* symbols)
+ available.
+
+ HASTCPTPIQ is defined when the dialect can duplicate
+ the receive and send queue sizes reported
+ by netstat.
+
+ HASTCPTPIW is defined when the dialect can duplicate
+ the receive and send window sizes reported
+ by netstat.
+
+ HASTCPUDPSTATE is defined when the dialect has support for
+ TCP and UDP state, including the "-s p:s"
+ option and associated speed ehancements.
+
+ HASTFS indicates that the Pyramid dialect has TFS
+ file system support.
+
+ HAS_UFS1_2 indicates the FreeBSD 6 and higher system has
+ UFS1 and UFS2 members in its inode structure.
+
+ HAS_UM_UFS indicates the OpenBSD version has UM_UFS[12]
+ definitions.
+
+ HASUNMINSOCK indicates the Linux version has a user name
+ element in the socket structure; a value of
+ 0 says there is no unix_address member; 1,
+ there is.
+
+ HASUINT16TYPE is defined when the dialect has a typedef
+ for u_int16 that may conflict with some other
+ header file's redefinition (e.g., <afs/std.h>).
+
+ HASUTMPX indicates the dialect has a <utmpx.h> header
+ file.
+
+ HAS_UVM_INCL indicates the NetBSD or OpenBSD dialect has
+ a <uvm> include directory.
+
+ HAS_UW_CFS indicates the UnixWare 7.1.1 or above dialect
+ has CFS file system support.
+
+ HAS_UW_NSC indicates the UnixWare 7.1.1 or above dialect
+ has a NonStop Cluster (NSC) kernel.
+
+ HAS_V_LOCKF indicates the FreeBSD version has a v_lockf
+ member in the vode structure, defined in
+ <sys/vnode.h>.
+
+ HAS_VM_MEMATTR_T indicates the FreeBSD <sys/conf.h> uses the
+ vm_memattr_t typedef.
+
+ HASVMLOCKH indicates the FreeBSD dialect has <vm/lock.h>.
+
+ HASVNODE enables/disables readvnode() function in node.c.
+
+ HAS_V_PATH indicates the dialect's vnode structure has a
+ v_path member.
+
+ HAS_VSOCK indicates that the Solaris version has a VSOCK
+ member in the vtype enum
+
+ HASVXFS enables Veritas VxFS file system support for
+ the dialect. CAUTION, the dialect sources
+ must have the necessary support code.
+
+ HASVXFSDNLC indicates the VxFS file system has its own
+ name cache.
+
+ HASVXFS_FS_H indicates <sys/fs/vx_fs.h> exists.
+
+ HASVXFS_MACHDEP_H indicates <sys/fs/vx_machdep.h> exists.
+
+ HASVXFS_OFF64_T indicates <sys/fs/vx_solaris.h> exists and
+ has an off64_t typedef.
+
+ HASXVFSRNL indicates the dialect has VxFS Reverse Name
+ Lookup (RNL) support.
+
+ HASVXFS_SOL_H indicates <sys/fs/vx_sol.h> exists.
+
+ HASVXFS_SOLARIS_H indicates <sys/fs/vx_solaris.h> exists.
+
+ HASVXFS_U64_T if HASVXFS_SOLARIS_H is defined, this
+ variable indicates that <sys/fs/vx_solaris.h>
+ has a vx_u64_t typedef.
+
+ HASVXFSUTIL indicates the Solaris dialect has VxFS 3.4
+ or higher and has the utility libraries,
+ libvxfsutil.a (32 bit) and libvxfsutil64.a
+ (64 bit).
+
+ HASVXFS_VX_INODE indicates that <sys/fs/vx_inode.h> contains
+ a vx_inode structure.
+
+ HASWCTYPE_H indicates the FreeBSD version has wide-character
+ support and the <wctype.h> header file. Note:
+ the HASWIDECHAR #define will also be set.
+
+ HASWIDECHAR indicates the dialect has the wide-character
+ support functions iswprint(), mblen() and mbtowc().
+
+ HASXNAMNODE indicates the OSR dialect has <sys/fs/xnamnode.h>.
+
+ HASXOPT defines help text for dialect-specific X option
+ and enables X option processing in usage.c and
+ main.c.
+
+ HASXOPT_ROOT when defined, restricts the dialect-specific
+ X option to processes whose real user ID
+ is root.
+
+ HAS_ZFS indicates the dialect has support for the ZFS file
+ system.
+
+ HASXOPT_VALUE defines the default binary value for the X option
+ in store.c.
+
+ HASZONES the Solaris dialect has zones.
+
+ HAVECLONEMAJ defines the name of the status variable
+ that indicates a clone major device number
+ is available in CLONEMAJ. (Also see CLONEMAJ
+ and HAS_STD_CLONE.)
+
+ HPUX_KERNBITS defines the number of bits in the HP-UX 10.30
+ and above kernel "basic" word: 32 or 64.
+
+ KA_T defines the type cast required to assign
+ space to kernel pointers. When not defined
+ by a dialect header file, KA_T defaults to
+ unsigned long.
+
+ KA_T_FMT_X defines the printf format for printing a
+ KA_T -- the default is "%#lx" for the
+ default unsigned long KA_T cast.
+
+ LSOF_ARCH See 00XCONFIG.
+
+ LSOF_BLDCMT See 00XCONFIG.
+
+ LSOF_CC See 00XCONFIG.
+
+ LSOF_CCV See 00XCONFIG.
+
+ LSOF_HOST See 00XCONFIG.
+
+ LSOF_INCLUDE See 00XCONFIG.
+
+ LSOF_LOGNAME See 00XCONFIG.
+
+ LSOF_MKC See the "The Mksrc Shell Script" section of
+ this file.
+
+ LSOF_SYSINFO See 00XCONFIG.
+
+ LSOF_USER See 00XCONFIG.
+
+ LSOF_VERS See 00XCONFIG.
+
+ LSOF_VSTR See 00XCONFIG.
+
+ MACH defines a MACH system.
+
+ N_UNIXV defines an alternate value for the N_UNIV symbol.
+
+ NCACHELDPFX defines C code to be executed before calling
+ ncache_load().
+
+ NCACHELDSFX defines C code to be executed after calling
+ ncache_load().
+
+ NEEDS_BOOLEAN_T indicates the FreeBSD 9 and above system needs a
+ boolean_t definition for <sys/conf.h>.
+
+ NEEDS_MACH_PORT_T is defined for Darwin versions that need the inclusion
+ of the header file <device/device_types.h>.
+
+ NEVER_HASDCACHE keeps the Customize script from offering to
+ change HASDCACHE by its presence anywhere
+ in a dialect's machine.h header file --
+ e.g., in a comment. See the Customize
+ script or machine.h in dialects/linux/proc.
+
+ NEVER_WARNDEVACCESS keeps the Customize script from offering to
+ change WARNDEVACCESS by its presence anywhere
+ in a dialect's machine.h header file --
+ including in a comment. See the Customize
+ script or machine.h in dialects/linux/proc.
+
+ NLIST_TYPE is the type of the nlist table, Nl[], if it is
+ not nlist. HASNLIST must be set for this
+ definition to be effective.
+
+ NOWARNBLKDEV specifies that no warning is to be issued
+ when no block devices are found. This
+ definiton is used only when HASBLKDEV is
+ also defined.
+
+ OFFDECDIG specifies how many decimal digits will be
+ printed for the file offset in a 0t form
+ before switching to a 0x form. The count
+ includes the "0t". A count of zero means
+ the size is unlimited.
+
+ PRIVFILETYPE is the number of a private file type, found
+ in the f_type member of the file struct, to
+ be processed by the HASPRIVFILETYPE function.
+ See the AIX dialect sources for an example.
+
+ _PSTAT_STREAM_GET_XPORT
+ indicates the HP-UX PSTAT header files require
+ this symbol to be defined for proper handling of
+ stream export data.
+
+ SAVE_MP_IN_SFILE indicates the dialect needs to have the mounts
+ structure pointer for a file system search argument
+ recorded in the dialect's sfile structure. This
+ definition is made in the dialect's dlsof.h header
+ file within the sfile structure.
+
+ TIMEVAL_LSOF defines the name of the timeval structure.
+ The default is timeval. /dev/kmem-based
+ Linux lsof redefines timeval with this
+ symbol to avoid conflicts between glibc
+ and kernel definitions.
+
+ TYPELOGSECSHIFT defines the type of the cdfs_LogSecShift
+ member of the cdfs structure for UnixWare
+ 7 and higher.
+
+ UID_ARG_T defines the cast on a User ID when passed
+ as a function argument.
+
+ USE_LIB_COMPLETEVFS
+ selects the use of the completevfs() function
+ in lsof4/lib/cvfs.c.
+
+ USE_LIB_FIND_CH_INO
+ selects the use of the find_ch_ino() inode
+ function in lsof4/lib/fino.c.
+
+ Note: HASBLKDEV selects the has_bl_ino()
+ function.
+
+ USE_LIB_IS_FILE_NAMED
+ selects the use of the is_file_named() function
+ in lsof4/lib/isfn.c.
+
+ USE_LIB_LKUPDEV selects the use of the lkupdev() function
+ in lsof4/lib/lkud.c.
+
+ Note: HASBLKDEV selects the lkupbdev() function.
+
+ USE_LIB_PRINTDEVNAME
+ selects the use of the printdevname() function
+ in lsof4/lib/pdvn.c.
+
+ Note: HASBLKDEV selects the printbdevname()
+ function.
+
+ USE_LIB_PRINT_TCPTPI
+ selects the use of the print_tcptpi() function
+ in lsof4/lib/ptti.c.
+
+ USE_LIB_PROCESS_FILE
+ selects the use of the process_file() function
+ in lsof4/lib/prfp.c.
+
+ USE_LIB_READDEV selects the use of the readdev() and stkdir()
+ functions in lsof4/lib/rdev.c.
+
+ USE_LIB_READMNT selects the use of the readmnt() function
+ in lsof4/lib/rmnt.c.
+
+ USE_LIB_RNAM selects the use of the device cache functions
+ in lsof4/lib/rnam.c.
+
+ Note: HASNCACHE must also be defined.
+
+ USE_LIB_RNCH selects the use of the device cache functions
+ in lsof4/lib/rnch.c.
+
+ Note: HASNCACHE must also be defined.
+
+ USE_STAT is defined for those dialects that must
+ use the stat(2) function instead of lstat(2)
+ to scan /dev -- i.e., in the readdev()
+ function.
+
+ VNODE_VFLAG is an alternate name for the vnode structure's
+ v_flag member.
+
+ WARNDEVACCESS enables the issuing of a warning message when
+ lsof is unable to access /dev (or /device)
+ or one of its subdirectories, or stat(2)
+ a file in them. Some dialects (e.g., HP-UX)
+ have many inaccessible subdirectories and
+ it is appropriate to inhibit the warning
+ for them with WARNDEVACCESS. The -w option
+ will also inhibit these warnings.
+
+ WARNINGSTATE when defined, disables the default issuing
+ of warning messages. WARNINGSTATE is
+ undefined by default for all dialects in
+ the lsof distribution.
+
+ WIDECHARINCL defines the header file to be included (if any)
+ when wide-character support is enabled with
+ HASWIDECHAR.
+
+ zeromem() defines a macro to zero memory -- e.g., using
+ bzero() or memset().
+
+Any dialect's machine.h file and Configure stanza can serve as a
+template for building your own. All machine.h files usually have
+all definitions, disabling some (with comment prefix and suffix)
+and enabling others.
+
+
+Options: Common and Special
+---------------------------
+
+All but one lsof option is common; the specific option is ``-X''.
+If a dialect does not support a common option, the related #define
+in machine.h -- e.g., HASCOPT -- should be deselected.
+
+The specific option, ``-X'', may be used by any dialect for its
+own purpose. Right now (May 30, 1995) the ``-X'' option is binary
+(i.e., it's not allowed arguments of its own, and its value must
+be 0 or 1) but that could be changed should the need arise. The
+option is enabled with the HASXOPT definition in machine.h; its
+default value is defined by HASXOPT_VALUE.
+
+The value of HASXOPT should be the text displayed for ``-X'' by
+the usage() function in usage.c. HASXOPT_VALUE should be the
+default value, 0 or 1.
+
+AIX for the IBM RICS System/6000 defines the ``-X'' option to
+control readx() usage, since there is a bug in AIX kernels that
+readx() can expose for other processes.
+
+
+Defining Dialect-Specific Symbols and Global Storage
+----------------------------------------------------
+
+A dialect's dlsof.h and dstore.c files contain dialect-specific
+symbol and global storage definitions. There are symbol definitions,
+for example, for function and data casts, and for file paths.
+Dslof.h defines lookup names the nlist() table -- X_* symbols --
+when nlist() is being used.
+
+Global storage definitions include such things as structures for
+local Virtual File System (vfs) information; mount information;
+search file information; and kernel memory file descriptors --
+e.g., Kmem for /dev/kmem, Mem for /dev/mem, Swap for /dev/drum.
+
+
+Coding Dialect-specific Functions
+---------------------------------
+
+Each supported dialect must have some basic functions that the
+common functions of the top level may call. Some of them may be
+obtained from the library in lsof4/lib, selected and customized by
+#define's in the dialect machine.h header file. Others may have
+to be coded specifically for the dialect.
+
+Each supported dialect usually has private functions, too. Those
+are wholly determined by the needs of the dialect's data organization
+and access.
+
+These are some of the basic functions that each dialect must supply
+-- they're all defined in proto.h:
+
+ initialize() function to initialize the dialect
+
+ is_file_named() function to check if a file was named
+ by an optional file name argument
+ (lsof4/lib/isfn.c)
+
+ gather_proc_info() function to gather process table
+ and related information and cache it
+
+ printchdevname() function to locate and optionally
+ print the name of a character device
+ (lsof4/lib/pdvn.c)
+
+ print_tcptpistate() function to print the TCP or TPI
+ state for a TCP or UDP socket file,
+ if the one in lib/ptti.c isn't
+ suitable (define USE_LIB_PRINT_TCPTPI
+ to activate lib/ptti.c)
+
+ process_file() function to process an open file
+ structure (lsof4/lib/prfp.c)
+
+ process_node() function to process a primary node
+
+ process_socket() function to process a socket
+
+ readdev() and stkdir() functions to read and cache device
+ information (lsof4/lib/rdev.c)
+
+ readmnt() function to read mount table information
+ (lsof4/lib/rmnt.c)
+
+Other common functions may be needed, and might be obtained from
+lsof4/lib, depending on the needs of the dialect's node and socket
+file processing functions.
+
+Check the functions in lsof4/lib and specific lsof4/dialects/*
+files for examples.
+
+As you build these functions you will probably have to add #include's
+to dlsof.h.
+
+
+Function Prototype Definitions and the _PROTOTYPE Macro
+-------------------------------------------------------
+
+Once you've defined your dialect-specific definitions, you should
+define their prototypes in dproto.h or locally in the file where
+they occur and are used. Do this even if your compiler is not ANSI
+compliant -- the _PROTOTYPE macro knows how to cope with that and
+will avoid creating prototypes that will confuse your compiler.
+
+
+The Makefile
+------------
+
+Here are some general rules for constructing the dialect Makefile.
+
+ * Use an existing dialect's Makefile as a template.
+
+ * Make sure the echo actions of the install rule are appropriate.
+
+ * Use the DEBUG string to set debugging options, like ``-g''.
+ You may also need to use the -O option when forking and
+ SIGCHLD signals defeat your debugger.
+
+ * Don't put ``\"'' in a compiler flags -D<symbol>=<string>
+ clause in your Makefile. Leave off the ``\"'' even though
+ you want <string> to be a string literal and instead adapt
+ the N_UNIX* macros you'll find in Makefiles for FreeBSD
+ and Linux. That will allow the Makefile's version.h rule
+ to put CFLAGS into version.h without having to worry about
+ the ``\"'' sequences.
+
+ * Finally, remember that strings can be passed from the top
+ level's Configure shell script. That's an appropriate way
+ to handle options, especially if there are multiple versions
+ of the Unix dialect to which you are porting lsof 4.
+
+
+The Mksrc Shell Script
+----------------------
+
+Pattern your Mksrc shell script after an existing one from another
+dialect. Change the D shell variable to the name of your dialect's
+subdirectory in lsof4/dialects. Adjust any other shell variable
+to your local conditions. (Probably that won't be necessary.)
+
+Note that, if using symbolic links from the top level to your
+dialect subdirectory is impossible or impractical, you can set the
+LSOF_MKC shell variable in Configure to something other than
+"ln -s" -- e.g., "cp," and Configure will pass it to the Mksrc
+shell script in the M environment variable.
+
+
+The MkKernOpts Shell Script
+---------------------------
+
+The MkKernOptrs shell script is used by some dialects -- e.g.,
+Pyramid DC/OSx and Reliant UNIX -- to determine the compile-time
+options used to build the current kernel that affect kernel structure
+definitions, so those same options can be used to build lsof.
+Configure calls MkKernOpts for the selected dialects.
+
+If your kernel is built with options that affect structure definitions.
+-- most commonly affected are the proc structure from <sys/proc.h>
+and the user structure from <sys/user.h> -- check the MkKernOpts
+in lsof4/dialects/irix for a comprehensive example.
+
+
+Testing and the Lsof Test Suite
+-------------------------------
+
+Once you have managed to create a port, here are some tips for
+testing it.
+
+* First look at the test suite in the tests/ sub-directory of the
+ lsof distribution. While it will need to be customized to be
+ usable with a new port, it should provide ideas on things to
+ test. Look for more information about the test suite in the
+ 00TEST file.
+
+* Pick a simple process whose open files you are likely to
+ know and see if the lsof output agrees with what you know.
+ (Hint: select the process with `lsof -p <process_PID>`.)
+
+ Are the device numbers and device names correct?
+
+ Are the file system names and mount points correct?
+
+ Are inode numbers and sizes correct?
+
+ Are command names, file descriptor numbers, UIDs, PIDs, PGIDs,
+ and PPIDs correct?
+
+ A simple tool that does a stat(2) of the files being examined
+ and reports the stat struct contents can provide a reference for
+ some values; so can `ls -l /dev/<device>`.
+
+* Let lsof list information about all open files and ask the
+ same questions. Look also for error messages about not being
+ able to read a node or structure.
+
+* Pick a file that you know is open -- open it and hold it
+ that way with a C program (not vi), if you must. Ask lsof to
+ find the file's open instance by specifying its path to lsof.
+
+* Create a C program that opens a large number of files and holds
+ them open. Background the test process and ask lsof to list
+ its files.
+
+* Generate some locks -- you may need to write a C program to
+ do this, hold the locked file open, and see if lsof can identify
+ the lock properly. You may need to write several C programs
+ if your dialect supports different lock functions -- fnctl(),
+ flock(), lockf(), locking().
+
+* Identify a process with known Internet file usage -- inetd
+ is a good one -- and ask lsof to list its open files. See if
+ protocols and service names are listed properly.
+
+ See if your lsof identifies Internet socket files properly for
+ rlogind or telnetd processes.
+
+* Create a UNIX domain socket file, if your dialect allows it,
+ hold it open by backgrounding the process, and see if lsof can
+ identify the open UNIX domain socket file properly.
+
+* Create a FIFO file and see what lsof says about it.
+
+* Watch an open pipe -- `lsof -u <your_login> | less` is a
+ good way to do this.
+
+* See if lsof can identify NFS files and their devices properly.
+ Open and hold open an NFS file and see if lsof can find the open
+ instance by path.
+
+* If your test system has CD-ROM and floppy disk devices, open
+ files on them and see if lsof reports their information correctly.
+ Such devices often have special kernel structures associated
+ with them and need special attention from lsof for their
+ identification. Pay particular attention to the inode numbers
+ lsof reports for CD-ROM and floppy disk files -- often they are
+ calculated dynamically, rather than stored in a kernel node
+ structure.
+
+* If your implementation can probe the kernel name cache, look
+ at some processes with open files whose paths you know to see
+ if lsof identifies any name components. If it doesn't, make
+ sure the name components are in the name cache by accessing
+ the files yourself with ls or a similar tool.
+
+* If your dialect supports the /proc file system, use a C program
+ to open files there, background a test process, and ask lsof to
+ report its open files.
+
+* If your dialect supports fattach(), create a small test program
+ to use it, background a test process, and ask lsof to report
+ its open files.
+
+I can supply some quick-and-dirty tools for reporting stat buffer
+contents, holding files open, creating UNIX domain files, creating
+FIFOs, etc., if you need them.
+
+
+Where Next?
+-----------
+
+Is this document complete? Certainly not! One might wish that it
+were accompanied by man pages for all lsof functions, by free beer
+or chocolates, by ... (You get the idea.)
+
+But those things are not likely to happen as long as lsof is a
+privately supported, one man operation.
+
+So, if you need more information on how lsof is constructed or
+works in order to do a port of your own, you'll have to read the
+lsof source code. You can also ask me questions via email, but
+keep in mind the private, one-man nature of current lsof support.
+
+
+Vic Abell <abe@purdue.edu>
+January 2, 2013