2 Guide to Porting lsof 4 to Unix OS Dialects
4 **********************************************************************
5 | The latest release of lsof is always available via anonymous ftp |
6 | from lsof.itap.purdue.edu. Look in pub/lsof.README for its |
8 **********************************************************************
13 /proc-based Linux Lsof -- a Different Approach
16 Source File Naming Conventions
19 Dlsof.h and #include's
20 Definitions That Affect Compilation
21 Options: Common and Special
22 Defining Dialect-Specific Symbols and Global Storage
23 Coding Dialect-specific Functions
24 Function Prototype Definitions and the _PROTOTYPE Macro
26 The Mksrc Shell Script
27 The MkKernOpts Shell Script
28 Testing and the lsof Test Suite
35 Before getting on with porting guidelines, just a word or two about
38 Lsof obtains data about open UNIX dialect files by reading the
39 kernel's proc structure information, following it to the related
40 user structure, then reading the open file structures stored
41 (usually) in the user structure. Typically lsof uses the kernel
42 memory devices, /dev/kmem, /dev/mem, etc. to read kernel data.
44 Lsof stores information from the proc and user structures in an
45 internal, local proc structure table. It then processes the open
46 file structures by reading the file system nodes that lie behind
47 them, extracting and storing relevant data in internal local file
48 structures that are linked to the internal local process structure.
50 Once all data has been gathered, lsof reports it from its internal,
53 There are a few variants on this subject. Some systems don't have
54 just proc structures, but have task structures, too, (e.g., NeXTSTEP
55 and OSF/1 derivatives). For some dialects lsof gets proc structures
56 or process information (See "/proc-based Linux Lsof -- a Different
57 Approach) from files of the /proc file system. It's not necessary
58 for lsof to read user structures on some systems (recent versions
59 of HP-UX), because the data lsof needs can be found in the task or
60 proc structures. In the end lsof gathers the same data, just from
61 slightly different sources.
64 /proc-based Linux Lsof -- a Different Approach
65 ==============================================
67 For a completely different approach to lsof construction, take a
68 look at the /proc-based Linux sources in .../dialects/linux/proc.
69 (The sources in .../dialects/linux/kmem are for a traditional lsof
70 that uses /dev/kmem to read information from kernel structures.)
72 The /proc-based lsof obtains all its information from the Linux
73 /proc file system. Consequently, it is relatively immune to changes
74 in Linux kernel structures and doesn't need to be re-compiled each
75 time the Linux kernel version changes.
77 There are some down-sides to the Linux /proc-based lsof:
79 * It must run setuid-root in order to be able to read the
80 /proc file system branches for all processes. In contrast,
81 the /dev/kmem-based Linux lsof usually needs only setgid
84 * It depends on the exact character format of /proc files, so
85 it is sensitive to changes in /proc file composition.
87 * It is limited to the information a /proc file system
88 implementor decides to provide. For example, if a
89 /proc/net/<protocol> file lacks an inode number, the
90 /proc-based lsof can't connect open socket files to that
91 protocol. Another deficiency is that the /proc-based may
92 not be able to report file offset (position) information,
93 when it isn't available in the /proc/<PID>/fd/ entry for a
96 In contrast the /dev/kmem-based lsof has full access to
97 kernel structures and "sees" new data as soon as it appears.
98 Of course, that new data requires that lsof be recompiled
99 and usually also requires changes to lsof.
101 Overall the switch from a /dev/kmem base to a /proc one is an
102 advantage to Linux lsof. The switch was made at lsof revision 4.23
103 for Linux kernel versions 2.1.72 (approximately) and higher. The
104 reason I'm not certain at which Linux kernel version a /proc-based
105 lsof becomes possible is that the /proc additions needed to implement
106 it have been added gradually to Linux 2.1.x in ways that I cannot
109 /proc-based lsof functions in many ways the same as /dev/kmem-based
110 lsof. It scans the /proc directory, looking for <PID>/ subdirectories.
111 Inside each one it collects process-related data from the cwd, exe,
112 maps, root, and stat information files.
114 It collects open file information from the fd/ subdirectory of each
115 <PID>/ subdirectory. The lstat(2), readlink(2), and stat(2) system
116 calls gather information about the files from the kernel.
118 Lock information comes from /proc/locks. It is matched to open
119 files by inode number. Mount information comes from /proc/mounts.
120 Per domain protocol information comes from the files of /proc/net;
121 it's matched to open socket files by inode number.
123 The Linux /proc file system implementors have done an amazing job
124 of providing the information lsof needs. The /proc-based lsof
125 project has so far generated only two kernel modification:
127 * A modification to /usr/src/linux/net/ipx/af_ipx.c adds the
128 inode number to the entries of /proc/net/ipx.
130 Jonathan Sergent did this kernel modification.
132 It may be found in the .../dialects/linux/proc/patches
133 subdirectory of the lsof distribution.
135 * An experimental modification to /usr/src/linux/fs/stat.c
136 allows lstat(2) to return file position information for
137 /proc/<PID>/fd/<FD> files.
139 Contact me for this modification.
142 One final note about the /proc-based Linux lsof: it doesn't need
143 any functions from the lsof library in the lib/ subdirectory.
149 These are the general guidelines for porting lsof 4 to a new Unix
152 * Understand the organization of the lsof sources and the
153 philosophies that guide their coding.
155 * Understand the data requirements and determine the methods
156 of locating the necessary data in the new dialect's kernel.
158 * Pick a name for the subdirectory in lsof4/dialects for your
159 dialect. Generally I use a vendor operating system name
162 * Locate the necessary header files and #include them in the
163 dialect's dlsof.h file. (You may not be able to complete
164 this step until you have coded all dialect-specific functions.)
166 * Determine the optional library functions of lsof to be used
167 and set their definitions in the dialect's machine.h file.
169 * Define the dialect's specific symbols and global storage
170 in the dialect's dlsof.h and dstore.c files.
172 * Code the dialect-specific functions in the appropriate
173 source files of the dialect's subdirectory.
175 Include the necessary prototype definitions of the dialect-
176 specific functions in the dproto.h file in the dialect's
179 * Define the dialect's Makefile and source construction shell
182 * If there are #define's that affect how kernel structures
183 are organized, and those #define's are needed when compiling
184 lsof, build a MkKernOpts shell script to locate the #define's
185 and supply them to the Configure shell script.
191 The code in a dialect-specific version of lsof comes from three
194 1) functions common to all versions, located in the top level
197 2) functions specific to the dialect, located in the dialect's
198 subdirectory -- e.g., lsof4/dialects/sun;
200 3) functions that are common to several dialects, although
201 not to all, organized in a library, liblsof.a. The functions
202 in the library source can be selected and customized with
203 definitions in the dialect machine.h header files.
205 The tree looks like this:
207 lsof4 ----------------------+ 3) library --
209 1) fully common functions + \
210 e.g., lsof4/main.c + lsof4/dialects/
213 2) dialect-specific subdirectories -- e.g., lsof4/dialects/sun
215 The code for a dialect-specific version is constructed from these
216 three sources by the Configure shell script in the top level lsof4
217 directory and definitions in the dialect machine.h header files.
218 Configure uses the Mksrc shell script in each dialect's subdirectory,
219 and may use an optional MkKernOpts shell script in selected dialect
222 Configure calls the Mksrc shell script in each dialect's subdirectory
223 to assemble the dialect-specific sources in the main lsof directory.
224 Configure may call MkKernOpts to determine kernel compile-time
225 options that are needed for compiling kernel structures correctly
226 for use by lsof. Configure puts the options in a dialect-specific
227 Makefile it build, using a template in the dialect subdirectory.
229 The assembly of dialect-specific sources in the main lsof directory
230 is usually done by creating symbolic links from the top level to
231 the dialect's subdirectory. The LSOF_MKC environment variable may
232 be defined prior to using Configure to change the technique used
233 to assemble the sources -- most commonly to use cp instead of ln -s.
235 The Configure script completes the dialect's Makefile by adding
236 string definitions, including the necessary kernel compile-time
237 options, to a dialect skeleton Makefile while copying it from the
238 dialect subdirectory to the top level lsof4 directory. Optionally
239 Makefile may call the dialect's MkKernOpts script to add string
242 When the lsof library, lsof4/lib/liblsof.a, is compiled its
243 functions are selected and customized by #define's in the dialect
244 machine.h header file.
247 Source File Naming Conventions
248 ------------------------------
250 With one exception, dialect-specific source files begin with a
251 lower case `d' character -- ddev.c, dfile.c, dlsof.h. The one
252 exception is the header file that contains dialect-specific
253 definitions for the optional features of the common functions.
254 It's called machine.h for historical reasons.
256 Currently all dialects use almost the same source file names. One
257 exception to the rule happens in dialects where there must be
258 different source files -- e.g., dnode[123].c -- to eliminate node
259 header file structure element name conflicts. The source modules
260 in a few subdirectories are organized that way.
262 Unusual situations occur for NetBSD and OpenBSD, and for NEXTSTEP
263 and OPENSTEP. Each pair of dialects is so close in design that
264 the same dialect sources from the n+obsd subdirectory serves NetBSD
265 and OpenBSD; from n+os, NEXTSTEP and OPENSTEP.
267 These are common files in lsof4/:
269 Configure the configuration script
271 Customize does some customization of the selected lsof
274 Inventory takes an inventory of the files in an lsof
277 version the version number
279 dialects/ the dialects subdirectory
281 These are the common function source files in lsof4/:
283 arg.c common argument processing functions
285 lsof.h common header file that #include's the dialect-specific
288 main.c common main function for lsof 4
290 misc.c common miscellaneous functions -- e.g., special versions
291 of stat() and readlink()
293 node.c common node reading functions -- readinode(), readvnode()
295 print.c common print support functions
297 proc.c common process and file structure functions
299 proto.h common prototype definitions, including the definition of
300 the _PROTOTYPE() macro
302 store.c common global storage version.h the current lsof version
303 number, derived from the file version by the Makefile
305 usage.c functions to display lsof usage panel
307 These are the dialect-specific files:
309 Makefile the Makefile skeleton
311 Mksrc a shell script that assists the Configure script
312 in configuring dialect sources
314 MkKernOpts an optional shell script that identifies kernel
315 compile-time options for selected dialects -- e.g.,
316 Pyramid DC/OSx and Reliant UNIX
318 ddev.c device support functions -- readdev() -- may be
319 eliminated by functions from lsof4/lib/
321 dfile.c file processing functions -- may be eliminated by
322 functions from lsof4/lib/
324 dlsof.h dialect-specific header file -- contains #include's
325 for system header files and dialect-specific global
328 dmnt.c mount support functions -- may be eliminated by
329 functions from lsof4/lib/
331 dnode.c node processing functions -- e.g., for gnode or vnode
333 dnode?.c additional node processing functions, used when node
334 header files have duplicate and conflicting element
337 dproc.c functions to access, read, examine and cache data about
338 dialect-specific process structures -- this file contains
339 the dialect-specific "main" function, gather_proc_info()
341 dproto.h dialect-specific prototype declarations
343 dsock.c dialect-specific socket processing functions
345 dstore.c dialect-specific global storage -- e.g., the nlist()
348 machine.h dialect specific definitions of common function options --
349 e.g., a HASINODE definition to activate the readinode()
350 function in lsof4/node.c
352 The machine.h header file also selects and customizes
353 the functions of lsof4/lib/.
355 These are the lib/ files. Definitions in the dialect machine.h
356 header files select and customize the contained functions that are
357 to be compiled and archived to liblsof.a.
359 Makefile.skel is a skeleton Makefile, used by Configure
360 to construct the Makefile for the lsof
363 cvfs.c completevfs() function
365 USE_LIB_COMPLETEVFS selects it.
367 CVFS_DEVSAVE, CVFS_NLKSAVE, CVFS_SZSAVE,
368 and HASFSINO customize it.
370 dvch.c device cache functions
372 HASDCACHE selects them.
374 DCACHE_CLONE, DCACHE_CLR, DCACHE_PSEUDO,
375 DVCH_CHOWN, DVCH_DEVPATH, DVCH_EXPDEV,
376 HASBLKDEV, HASENVDC, HASSYSDC, HASPERSDC,
377 HASPERSDCPATH, and NOWARNBLKDEV customize
380 fino.c find block and character device inode functions
382 HASBLKDEV and USE_LIB_FIND_CH_INO select them.
384 isfn.c hashSfile() and is_file_named() functions
386 USE_LIB_IS_FILE_NAMED selects it.
388 lkud.c device lookup functions
390 HASBLKDEV and USE_LIB_LKUPDEV select them.
392 pdvn.c print device name functions
394 HASBLKDEV and USE_LIB_PRINTDEVNAME select them.
396 prfp.c process_file() function
398 USE_LIB_PROCESS_FILE selects it.
400 FILEPTR, DTYPE_PIPE, HASPIPEFN, DTYPE_GNODE,
401 DTYPE_INODE, DTYPE_PORT, DTYPE_VNODE, DTYPE_PTS,
402 HASF_VNODE, HASKQUEUE, HASPRIVFILETYPE,
403 HASPSXSHM, HASPSXSEM and HASPTSFN customize it.
405 ptti.c print_tcptpi() function
407 USE_LIB_PRINT_TCPTPI selects it.
409 HASSOOPT, HASSBSTATE, HASSOSTATE, AHSTCPOPT,
410 HASTCPTPIQ and HASTCPTPIW customize it.
412 rdev.c readdev() function
414 USE_LIB_READDEV selects it.
416 DIRTYPE, HASBLKDEV, HASDCACHE, HASDNAMLEN,
417 RDEV_EXPDEV, RDEV_STATFN, USE_STAT, and
418 WARNDEVACCESS customize it.
420 rmnt.c readmnt() function
422 USE_LIB_READMNT selects it.
424 HASFSTYPE, MNTSKIP, RMNT_EXPDEV, RMNT_FSTYPE,
425 and MOUNTS_FSTYPE customize it.
427 rnam.c BSD format name cache functions
429 HASNCACHE and USE_LIB_RNAM select them.
431 HASFSINO, NCACHE, NCACHE_NC_CAST, NCACHE_NM,
432 NCACHE_NMLEN, NCACHE_NODEADDR, NCACHE_NODEID,
433 NCACHE_NO_ROOT, NCACHE_NXT, NCACHE_PARADDR,
434 NCACHE_PARID, NCACHE_SZ_CAST, NCHNAMLEN,
435 X_NCACHE, and X_NCSIZE, customize them.
437 rnch.c Sun format name cache functions
439 HASNCACHE and USE_LIB_RNCH select them.
441 ADDR_NCACHE, HASDNLCPTR, HASFSINO, NCACHE_DP,
442 NCACHE_NAME, NCACHE_NAMLEN, NCACHE_NEGVN,
443 NCACHE_NODEID, NCACHE_NXT, NCACHE_PARID,
444 NCACHE_VP, X_NCACHE, and X_NCSIZE, customize
447 snpf.c Source for the snprintf() family of functions
449 USE_LIB_SNPF selects it.
452 The comments and the source code in these library files give more
453 information on customization.
459 A few basic philosophies govern the coding of lsof 4 functions:
461 * Use as few #if/#else/#endif constructs as possible, even at
462 the cost of nearly-duplicate code.
464 When #if/#else/#endif constructs are necessary:
468 #if defined(s<symbol>)
474 to allow easier addition of tests to the #if.
476 o Indent them to signify their level -- e.g.,
480 # endif /* level two */
481 #else /* level one */
482 #endif /* level one */
484 o Use ANSI standard comments on #else and #endif statements.
486 * Document copiously.
488 * Aim for ANSI-C compatibility:
490 o Use function prototypes for all functions, hiding them
491 from compilers that cannot handle them with the _PROTOTYPE()
494 o Use the compiler's ANSI conformance checking wherever
495 possible -- e.g., gcc's -ansi option.
501 Lsof's strategy in obtaining open file information is to access
502 the process table via its proc structures, then obtain the associated
503 user area and open file structures. The open file structures then
504 lead lsof to file type specific structures -- cdrnodes, fifonodes,
505 inodes, gnodes, hsfsnodes, pipenodes, pcnodes, rnodes, snodes,
506 sockets, tmpnodes, and vnodes.
508 The specific node structures must yield data about the open files. The
509 most important items and device number (raw and cooked) and node
510 number. (Lsof uses them to identify files and file systems named as
511 arguments.) Link counts and file sizes are important, too, as are the
512 special characteristics of sockets, pipes, FIFOs, etc.
514 This means that to begin an lsof port to a new Unix dialect you
515 must understand how to obtain these structures from the dialect's
516 kernel. Look for kernel access functions -- e.g., the AIX readx()
517 function, Sun and Sun-like kvm_*() functions, or SGI's syssgi()
518 function. Look for clues in header files -- e.g. external declarations
521 If you have access to them, look at sources to programs like ps(1),
522 or the freely available monitor and top programs. They may give
523 you important clues on reading proc and user area structures. An
524 appeal to readers of dialect-specific news groups may uncover
525 correspondents who can help.
527 Careful reading of system header files -- e.g., <sys/proc.h> --
528 may give hints about how kernel storage is organized. Look for
529 global variables declared under a KERNEL or _KERNEL #if. Run nm(1)
530 across the kernel image (/vmunix, /unix, etc.) and look for references
531 to structures of interest.
533 Even if there are support functions for reading structures, like the
534 kvm_*() functions, you must still understand how to read data from
535 kernel memory. Typically this requires an understanding of the
536 nlist() function, and how to use /dev/kmem, /dev/mem, and /dev/swap.
538 Don't overlook the possibility that you may have to use the process
539 file system -- e.g., /proc. I try to avoid using /proc when I can,
540 since it usually requires that lsof have setuid(root) permission
541 to read the individual /proc "files".
543 Once you can access kernel structures, you must understand how
544 they're connected. You must answer questions like:
546 * How big are kernel addresses? How are they type cast?
548 * How are kernel variable names converted to addresses?
551 * How are the proc structures organized? Is it a static
552 table? Are the proc structures linked? Is there a
553 kernel pointer to the first proc structure? Is there a
554 proc structure count?
556 * How does one obtain copies of the proc structures? Via
557 /dev/kmem? Via a vendor API?
559 * If this is a Mach derivative, is it necessary to obtain the
560 task and thread structures? How?
562 * How does one obtain the user area (or the utask area in Mach
563 systems) that corresponds to a process?
565 * Where are the file structures located for open file
566 descriptors and how are they located? Are all file
567 structures in the user area? Is the file structure space
570 * Where do the private data pointers in file structures lead?
571 To gnodes? To inodes? To sockets? To vnodes? Hint: look
572 in <sys/file.h> for DTYPE_* instances and further pointers.
574 * How are the nodes organized? To what other nodes do they
575 lead and how? Where are the common bits of information in
576 nodes -- device, node number, size -- stored? Hint: look
577 in the header files for nodes for macros that may be used
578 to obtain the address of one node from another -- e.g., the
579 VTOI() macro that leads from a vnode to an inode.
581 * Are text reference nodes identified and how? Is it
582 necessary to examine the virtual memory map of a process or
583 a task to locate text references? Some kernels have text
584 node pointers in the proc structures; some, in the user
585 area; Mach kernels may have text information in the task
586 structure, reached in various ways from the proc, user area,
587 or user task structure.
589 * How is the device table -- e.g., /dev or /devices --
590 organized? How is it read? Using direct or dirent structures?
592 How are major/minor device numbers represented? How are
593 device numbers assembled and disassembled?
595 Are there clone devices? How are they identified?
597 * How is mount information obtained? Getmntinfo()? Getmntent()?
598 Some special kernel call?
600 * How are sockets identified and organized? BSD-style? As
601 streams? Are there streams?
603 * Are there special nodes -- CD-ROM nodes, FIFO nodes, etc.?
605 * How is the kernel's name cache organized? Can lsof access
606 it to get partial name components?
609 Dlsof.h and #include's
610 ----------------------
612 Once you have identified the kernel's data organization and know
613 what structures it provides, you must add #include's to dlsof.h to
614 access their definitions. Sometimes it is difficult to locate the
615 header files -- you may need to introduce -I specifications in the
616 Makefile via the DINC shell variable in the Configure script.
618 Sometimes it is necessary to define special symbols -- e.g., KERNEL,
619 _KERNEL, _KMEMUSER -- to induce system header files to yield kernel
620 structure definitions. Sometimes making those symbol definitions
621 cause other header file and definition conflicts. There's no good
622 general rule on how to proceed when conflicts occur.
624 Rarely it may be necessary to extract structure definitions from
625 system header files and move them to dlsof.h, create special versions
626 of system header files, or obtain special copies of system header
627 files from "friendly" (e.g., vendor) sources. The dlsof.h header
628 file in lsof4/dialects/sun shows examples of the first case; the
629 second, no examples; the third, the irix5hdr subdirectory in
630 lsof4/dialects/irix (a mixture of the first and third).
632 Building up the necessary #includes in dlsof.h is an iterative
633 process that requires attention as you build the dialect-specific
634 functions that references kernel structures. Be prepared to revisit
638 Definitions That Affect Compilation
639 -----------------------------------
641 The source files at the top level and in the lib/ subdirectory
642 contain optional functions that may be activated with definitions
643 in a dialect's machine.h header file. Some are functions for
644 reading node structures that may not apply to all dialects -- e.g.
645 CD-ROM nodes (cdrnode), or `G' nodes (gnode) -- and others are
646 common functions that may occasionally be replaced by dialect-specific
647 ones. Once you understand your kernel's data organization, you'll
648 be able to decide the optional common node functions to activate.
650 Definitions in machine.h and dlsof.h also enable or disable other
651 optional common features. The following is an attempt to list all
652 the definitions that affect lsof code, but CAUTION, it is only
653 attempt and may be incomplete. Always check lsof4 source code in
654 lib/ and dialects/, and dialect machine.h header files for other
657 AFS_VICE See 00XCONFIG.
659 AIX_KERNBITS specifies the kernel bit size, 32 or 64, of the Power
660 architecture AIX 5.x kernel for which lsof was built.
662 CAN_USE_CLNT_CREATE is defined for dialects where the more modern
663 RPC function clnt_create() can be used in
664 place of the deprecated clnttcp_create().
666 CLONEMAJ defines the name of the variable that
667 contains the clone major device number.
668 (Also see HAS_STD_CLONE and HAVECLONEMAJ.)
670 DEVDEV_PATH defines the path to the directory where device
671 nodes are stored, usually /dev. Solaris 10
674 DIALECT_WARNING may be defined by a dialect to provide a
675 warning message that will be displayed with
676 help (-h) and version (-v) output.
678 FSV_DEFAULT defines the default file structure values to
679 list. It may be composed of or'd FSV_*
680 (See lsof.h) values. The default is none (0).
682 GET_MAJ_DEV is a macro to get major portion from device
683 number instead of via the standard major()
686 GET_MIN_DEV is a macro to get minor portion from device
687 number instead of via the standard minor()
690 GET_MAX_FD the name of the function that returns an
691 int for the maximum open file descriptor
692 plus one. If not defined, defaults to
695 HAS9660FS enables CD9660 file system support in a
698 HAS_ADVLOCK_ARGS is defined for NetBSD and OpenBSD dialects
699 whose <sys/lockf.h> references vop_advlock_args.
701 HAS_AFS enables AFS support code for the dialect.
703 HAS_AIO_REQ_STRUCT is defined for Solaris 10 and above systems that
704 have the aio_req structure definition.
706 HAS_ATOMIC_T indicates the Linux version has an
707 <asm/atomic.h> header file and it contains
708 "typedef struct .* atomic_t;"
710 HASAOPT indicates the dialect supports the AFS -A
711 option when HAS_AFS is also defined.
713 HAS_ASM_TERMIOBITS indicates for Linux Alpha that the
714 <asm/termiobits.h> header file exists.
716 HASAX25CBPTR indicates that the Linux sock struct has an
719 HASBLKDEV indicates the dialect has block device support.
721 HASBUFQ_H indicates the *NSD dialect has the <sys/bufq.h>
724 HASCACHEFS enables cache file system support for the
727 HAS_CDFS enables CDFS file system support for the
730 HASCDRNODE enables/disables readcdrnode() in node.c.
732 HAS_CLOSEFROM is defined when the FreeBSD C library contains the
733 closefrom() function.
735 HAS_CONN_NEW indicates the Solaris version has the new form
736 of the conn_s structure, introduced in b134 of
737 Solaris 11. This will always accompany the
738 HAS_IPCLASSIFIER_H definition.
740 HAS_CONST indicates that the compiler supports the
743 HASCPUMASK_T indicates the FreeBSD 5.2 or higher dialect
744 has cpumask_t typedef's.
746 HAS_CRED_IMPL_H indicates the Solaris 10 dialect has the
747 <sys/cred_impl.h> header file available.
749 HASCWDINFO indicates the cwdinfo structure is defined
750 in the NetBSD <sys/filedesc.h>.
752 HASDCACHE enables device file cache file support.
753 The device cache file contains information
754 about the names, device numbers and inode
755 numbers of entries in the /dev (or /device)
756 node subtree that lsof saves from call to
757 call. See the 00DCACHE file of the lsof
758 distribution for more information on this
761 HASDENTRY indicates the Linux version has a dentry
762 struct defined in <linux/dcache.h>.
764 HASDEVKNC indicates the Linux version has a kernel
765 name cached keyed on device number.
767 HAS_DINODE_U indicates the OpenBSD version has a dinode_u
768 union in its inode structure.
770 HASDNLCPTR is defined when the name cache entry of
771 <sys/dnlc.h> has a name character pointer
772 rather than a name character array.
774 HAS_DUP2 is defined when the FreeBSD C library contains the
777 HASEFFNLINK indicates the *BSD system has the i_effnlink
778 member in the inode structure.
780 HASENVDC enables the use of an environment-defined
781 device cache file path and defines the name
782 of the environment variable from which lsof
783 may take it. (See the 00DCACHE file of
784 the lsof distribution for information on
785 when HASENVDC is used or ignored.)
787 HASEOPT indicates the dialect supports the -e option to
788 eliminate kernel blocks on a named file system.
790 HASEPTOPTS indicates the dialect supports the +|-E end point
793 HASEXT2FS is defined for BSD dialects for which ext2fs
794 file system support can be provided. A value
795 of 1 indicates that the i_e2din member does not
798 HASF_VNODE indicates the dialect's file structure has an
799 f_vnode member in it.
801 HAS_FDESCENTTBL indicates the FreeBSD system has the fdescenttbl
804 HAS_FILEDESCENT indicates the FreeBSD system has the filedescent
805 definition in the <sys/filedesc.h> header file.
807 HASFDESCFS enables file descriptor file system support
808 for the dialect. A value of 1 indicates
809 <miscfs/fdesc.h> has a Fctty definition; 2,
812 HASFDLINK indicates the file descriptor file system
813 node has the fd_link member.
815 HASFIFONODE enables/disables readfifonode() in node.c.
817 HAS_FL_FD indicates the Linux version has an fl_fd
818 element in the lock structure of <linux/fs.h>.
820 HAS_FL_FILE indicates the Linux version has an fl_file
821 element in the lock structure of <linux/fs.h>.
823 HAS_FL_WHENCE indicates the Linux version has an fl_whence
824 element in the lock structure of <linux/fs.h>.
826 HAS_F_OPEN indicates the UnixWare 7.x dialect has the
827 f_open member in its file struct.
829 HASFSINO enables the inclusion of the fs_ino element
830 in the lfile structure definition in lsof.h.
831 This contains the file system's inode number
832 and may be needed when searching the kernel
833 name cache. See dialects/osr/dproc.c for
836 HASFSTRUCT indicates the dialect has a file structure
837 the listing of whose element values can be
838 enabled with +f[cfn]. FSV_DEFAULT defines
839 the default listing values.
841 HASFSTYPE enables/disables the use of the file system's
842 stat(2) st_fstype member.
844 If the HASFSTYPE value is 1, st_fstype is
845 treated as a character array; 2, it is
846 treated as an integer.
848 See also the RMNT_EXPDEV and RMNT_FSTYPE
849 documentation in lib/rmnt.c
851 HASFUSEFS is defined when the FreeBSD system has FUSE file system
854 HASGETBOOTFILE indicates the NetBSD or OpenBSD dialect has
855 a getbootfile() function.
857 HASGNODE enables/disables readgnode() in node.c.
859 HASHASHPID is defined when the Linux version (probably
860 above 2.1.35) has a pidhash_next member in
863 HASHSNODE enables/disables readhsnode() in node.c.
865 HASI_E2FS_PTR indicates the BSD dialect has a pointer in
866 its inode to the EXTFS dinode.
868 HASI_FFS indicates the BSD dialect has i_ffs_size
869 in <ufs/ufs/inode.h>.
871 HASI_FFS1 indicates the BSD dialect supports the fast
872 UFS1 and UFS2 file systems.
874 HAS_INKERNEL indicates the SCO OSR 6.0.0 or higher, or
875 UnixWare 7.1.4 or higher system uses the
876 INKERNEL symbol in <netinet/in_pcb.h> or
879 HASINODE enables/disables readinode() in node.c.
881 HASINOKNC indicates the Linux version has a kernel
882 name cache keyed on inode address.
884 HASINADDRSTR is defined when the inp_[fl]addr members
885 of the inpcb structure are structures.
887 HASINRIAIPv6 is defined if the dialect has the INRIA IPv6
888 support. (HASIPv6 will also be defined.)
890 HASINT16TYPE is defined when the dialect has a typedef
891 for int16 that may conflict with some other
892 header file's redefinition (e.g., <afs/std.h>).
894 HASINT32TYPE is defined when the dialect has a typedef
895 for int32 that may conflict with some other
896 header file's redefinition (e.g., <afs/std.h>).
898 HASINTSIGNAL is defined when signal() returns an int.
900 HAS_IPCLASSIFIER_H is defined for Solaris dialects that have the
901 <inet/ipclassifier.h> header file.
903 HAS_IPC_S_PATCH is defined when the HP-UX 11 dialect has the
904 ipc_s patch installed. It has a value of
905 1 if the ipc_s structure has an ipc_ipis
906 member, but the ipis_s structure lacks the
907 ipis_msgsqueued member; 2, if ipc_s has
908 ipc_ipis, but ipis_s lacks ipis_msgsqueued.
910 HASIPv6 indicates the dialect supports the IPv6
911 Internet address family.
913 HAS_JFS2 The AIX >= 5.0 dialect has jfs2 support.
915 HASKERNELKEYT indicates the Linux version has a
916 __kernel_key_t typedef in <linux/types.h>.
918 HASKERNFS is defined for BSD dialects for which
919 /kern file system support can be provided.
921 HASKERNFS_KFS_KT indicates *kfs_kt is in the BSD dialect's
922 <miscfs/kernfs/kernfs.h>.
924 HASKOPT enables/disables the ability to read the
925 kernel's name list from a file -- e.g., from
928 HAS_PAUSE_SBT indicates the FreeBSD system's systm.h has the
929 pause to pause_sbt definition.
931 HASKQUEUE indicates the dialect supports the kqueue
934 HASKVMGETPROC2 The *BSD dialect has the kvm_gettproc2()
937 HAS_KVM_VNODE indicates the FreeBSD 5.3 or higher dialect has
938 "defined(_KVM_VNODE)" in <sys/vnode.h>.
940 HASLFILEADD defines additional, dialect-specific elements
941 SETLFILEADD in the lfile structure (defined in lsof.h).
942 HASLFILEADD is a macro. The accompanying SETFILEADD
943 macro is used in the alloc_lfile() function of
944 proc.c to preset the additional elements.
946 HAS_LF_LWP is defined for BSD dialects where the lockf
947 structure has an lf_lwp member.
949 HASLFS indicates the *BSD dialect has log-structured
952 HAS_LGRP_ROOT_CONFLICT
953 indicates the Solaris 9 or Solaris 10 system has
954 a conflict over the lgrp_root symbol in the
955 <sys/lgrp.h> and <sys/lgrp_user.h> header files.
957 HAS_LIBCTF indicates the Solaris 10 and above system has
960 HAS_LOCKF_ENTRY indicates the FreeBSD version has a lockf_entry
961 structure in its <sys/lockf.h> header file.
963 HAS_LWP_H is defined for BSD dialects that have the
964 <sys/lwp.h> header file.
966 HASMOPT enables/disables the ability to read kernel
967 memory from a file -- e.g., from a crash
970 HASMSDOSFS enables MS-DOS file system support in a
973 HASMNTSTAT indicates the dialect has a stat(2) status
974 element in its mounts structure.
976 HASMNTSUP indicates the dialect supports the mount supplement
979 HASNAMECACHE indicates the FreeBSD dialect has a namecache
980 structure definition in <sys/namei.h>.
982 HASNCACHE enables the probing of the kernel's name cache
983 to obtain path name components. A value
984 of 1 directs printname() to prefix the
985 cache value with the file system directory
986 name; 2, avoid the prefix.
988 HASNCVPID The *BSD dialect namecache struct has an
991 HASNETDEVICE_H indicates the Linux version has a netdevice.h
994 HAS_NFS enables NFS support for the dialect.
996 HASNFSKNC indicates the LINUX version has a separate
999 HASNFSPROTO indicates the NetBSD or OpenBSD version
1000 has the nfsproto.h header file.
1002 HASNFSVATTRP indicates the n_vattr member of the nfsnode of
1003 the *BSD dialect is a pointer.
1005 HASNLIST enables/disables nlist() function support.
1008 HASNOFSADDR is defined if the dialect has no file structure
1009 addresses. (HASFSTRUCT must be defined.)
1011 HASNOFSCOUNT is defined if the dialect has no file structure counts.
1012 (HASFSTRUCT must be defined.)
1014 HASNOFSFLAGS is defined if the dialect has no file structure flags.
1015 (HASFSTRUCT must be defined.)
1017 HASNOFSNADDR is defined if the dialect has no file structure node
1018 addresses. (HASFSTRUCT must be defined.)
1020 HAS_NO_6PORT is defined if the FreeBSD in_pcb.h has no in6p_.port
1023 HAS_NO_6PPCB is defined if the FreeBSD in_pcb.h has no in6p_ppcb
1026 HAS_NO_IDEV indicates the FreeBSD system's inode has no i_dev
1029 HAS_NO_ISO_DEV indicates the FreeBSD 6 and higher system has
1030 no i_dev member in its iso_node structure.
1032 HAS_NO_LONG_LONG indicates the dialect has no support for the C
1033 long long type. This definition is used by
1034 the built-in snprintf() support of lib/snpf.c.
1036 HASNORPC_H indicates the dialect has no /usr/include/rpc/rpc.h
1039 HAS_NO_SI_UDEV indicates the FreeBSD 6 and higher system has
1040 no si_udev member in its cdev structure.
1042 HASNOSOCKSECURITY enables the listing of open socket files,
1043 even when HASSECURITY restricts listing of
1044 open files to the UID of the user who is
1045 running lsof, provided socket file listing
1046 is selected with the "-i" option. This
1047 definition is only effective when HASSECURITY
1050 HASNULLFS indicates the dialect (usually *BSD) has a
1053 HASOBJFS indicates the Pyramid version has OBJFS
1056 HASONLINEJFS indicates the HP-UX 11 dialect has the optional
1057 OnlineJFS package installed.
1060 indicates the Solaris 10 system's <sys/fs/pc_node.h>
1061 header file has the pc_direntpersec() macro.
1063 HAS_PAD_MUTEX indicates the Solaris 11 system has the pad_mutex_t
1064 typedef in its <sys/mutex.h> header file.
1066 HASPERSDC enables the use of a personal device cache
1067 file path and specifies a format by which
1068 it is constructed. See the 00DCACHE file
1069 of the lsof distribution for more information
1072 HASPERSDCPATH enables the use of a modified personal
1073 device cache file path and specifies the
1074 name of the environment variable from which
1075 its component may be taken. See the 00DCACHE
1076 file of the lsof distribution for more
1077 information on the modified personal device
1080 HASPINODEN declares that the inode number of a /proc file
1081 should be stored in its procfsid structure.
1083 HASPIPEFN defines the function that processes DTYPE_PIPE
1084 file structures. It's used in the prfp.c
1085 library source file. See the FreeBSD
1086 dialect source for an example.
1088 HASPIPENODE enables/disables readpipenode() in node.c.
1090 HASPMAPENABLED enables the automatic reporting of portmapper
1091 registration information for TCP and UDP
1092 ports that have been registered.
1094 HASPPID indicates the dialect has parent PID support.
1096 HASPR_LDT indicates the Solaris dialect has a pr_ldt
1097 member in the pronodetype enum.
1099 HASPR_GWINDOWS indicates the Solaris dialect has a pr_windows
1100 member in the pronodetype enum.
1102 HASPRINTDEV this value defines a private function for
1103 printing the dialect's device number. Used
1104 by print.c/print_file(). Takes one argument:
1106 char *HASPRINTDEV(struct lfile *)
1108 HASPRINTINO this value names a private function for
1109 printing the dialect's inode number. Used
1110 by print.c/print_file(). Takes one argument:
1112 char *HASPRINTINO(struct lfile *)
1114 HASPRINTNM this value names a private function for
1115 printing the dialect's file name. Used by
1116 print.c/print_file(). Takes one argument:
1118 void HASPRINTNM(struct lfile *)
1120 HASPRINTOFF this value names a private function for
1121 printing the dialect's file offset. Used
1122 by print.c/print_file(). Takes two arguments:
1124 char *HASPRINTOFF(struct lfile *, int ty)
1126 Where ty == 0 if the offset is to be printed
1127 in 0t<decimal> format; 1, 0x<hexadecimal>.
1129 HASPRINTSZ this value names a private function for
1130 printing the dialect's file size. Used
1131 by print.c/print_file(). Takes one argument:
1133 char *HASPRINTSZ(struct lfile *)
1135 void HASPRINTNM(struct lfile *)
1137 HASPRIVFILETYPE enables processing of the private file
1138 type, whose number (from f_type of the file
1139 struct) is defined by PRIVFILETYPE.
1140 HASPRIVFILETYPE defines the function that
1141 processes the file struct's f_data member.
1142 Processing is initiated from the process_file()
1143 function of the prfp.c library source file
1144 or from the dialect's own process_file()
1147 HASPRIVNMCACHE enables printing of a file path from a
1148 private name cache. HASPRIVNMCACHE defines
1149 the name of the printing function. The
1150 function takes one argument, a struct lfile
1151 pointer to the file, and returns non-zero
1152 if it prints a cached name to stdout.
1154 HASPRIVPRIPP is defined for dialects that have a private
1155 function for printing the IP protocol name.
1156 When this is not defined, the function to
1157 do that defaults to printiproto().
1159 HASPROCFS defines the name (if any) of the process file
1160 system -- e.g., /proc.
1162 HASPROCFS_PFSROOT indicates PFSroot is in the BSD dialect's
1163 <miscfs/procfs/procfs.h>.
1165 HASPSEUDOFS indicates the FreeBSD dialect has pseudofs
1166 file system support.
1168 HASPSXSEM indicates the dialect has support for the POSIX
1169 semaphore file type.
1171 HASPSXSHM indicates the dialect has support for the POSIX
1172 shared memory file type.
1174 HASPTSFN indicates the dialect has a DNODE_PTS file descriptor
1175 type and defines the function that processes it.
1177 HASPTYEPT indicates the Linux dialect has support for the
1178 pseudoterminal endpoint option.
1180 HASPTYFS indicates the *BSD dialect has a ptyfs file system.
1182 HASRNODE enables/disables readrnode() in node.c.
1184 HASRNODE3 indicates the HPUX 10.20 or lower dialect has NFS3
1185 support with a modified rnode structure.
1187 HASRPCV2H The FreeBSD dialect has <nfs/rpcv2.h>.
1189 HAS_SANFS indicates the AIX system has SANFS file system
1192 HAS_SB_CC indicates the FreeBSD system's sockbuf structure has
1193 the sb_ccc member, rather than the sb_cc member.
1195 HASSBSTATE indicates the dialect has socket buffer state
1196 information (e.g., SBS_* symbols) available.
1198 HASSECURITY enables/disables restricting open file
1199 information access. (Also see HASNOSOCKSECURITY.)
1201 HASSELINUX indicates the Linux dialect has SELinux security
1202 context support available.
1204 HASSETLOCALE is defined if the dialect has <locale.h> and
1207 HAS_SI_PRIV indicates the FreeBSD 6.0 and higher cdev
1208 structure has an si_priv member.
1210 HAS_SOCKET_PROTO_H indicates the Solaris 10 system has the header file
1211 <sys/socket_proto.h>.
1213 HASSOUXSOUA indicates that the Solaris <sys/socketvar.h> has
1214 soua_* members in its so_ux_addr structure.
1216 HASSPECDEVD indicates the dialect has a special device
1217 directory and defines the name of a function
1218 that processes the results of a successful
1219 stat(2) of a file in that directory.
1221 HASSPECNODE indicates the DEC OSF/1, or Digital UNIX,
1222 or Tru64 UNIX <sys/specdev.h> has a spec_node
1223 structure definition.
1225 HASSNODE indicates the dialect has snode support.
1227 HAS_SOCKET_SK indicates that the Linux socket structure
1228 has the ``struct sock *sk'' member.
1230 HASSOOPT indicates the dialect has socket option
1231 information (e.g., SO_* symbols) available.
1233 HASSOSTATE indicates the dialect has socket state
1234 information (e.g., SS_* symbols) available.
1236 HASSTATVFS indicates the NetBSD dialect has a statvfs
1239 HASSTAT64 indicates the dialect's <sys/stat.h> contains
1242 HAS_STD_CLONE indicates the dialect uses a standard clone
1243 device structure that can be used in common
1244 library function clone processing. If the
1245 value is 1, the clone table will be built
1246 by readdev() and cached when HASDCACHE is
1247 defined; if the value is 2, it is assumed
1248 the clone table is built independently.
1249 (Also see CLONEMAJ and HAVECLONEMAJ.)
1251 HASSTREAMS enables/disables streams. CAUTION, requires
1252 specific support code in the dialect sources.
1254 HAS_STRFTIME indicates the dialect has the gmtime() and
1255 strftime() C library functions that support
1256 the -r marker format option. Configure tests
1257 for the functions and defines this symbol.
1259 HASSYSDC enables the use of a system-wide device
1260 cache file and defines its path. See the
1261 00DCACHE file of the lsof distribution for
1262 more information on the system-wide device
1263 cache file path option.
1265 HAS_SYS_PIPEH indicates the dialect has a <sys/pipe.h>
1268 HAS_SYS_SX_H indicates the FreeBSD 7.0 and higher system has
1269 a <sys/sx.h> header file.
1271 HASTAGTOPATH indicates the DEC OSF/1, Digital UNIX, or
1272 Tru64 UNIX dialect has a libmsfs.so,
1273 containing tag_to_path().
1275 HAS_TMPFS indicates the FreeBSD system has the <fs/tmpfs.h>
1278 HASTMPNODE enables/disables readtnode() in node.c.
1280 HASTCPOPT indicates the dialect has TCP option
1281 information (i.e., from TF_* symbols)
1284 HASTCPTPIQ is defined when the dialect can duplicate
1285 the receive and send queue sizes reported
1288 HASTCPTPIW is defined when the dialect can duplicate
1289 the receive and send window sizes reported
1292 HASTCPUDPSTATE is defined when the dialect has support for
1293 TCP and UDP state, including the "-s p:s"
1294 option and associated speed ehancements.
1296 HASTFS indicates that the Pyramid dialect has TFS
1297 file system support.
1299 HAS_UFS1_2 indicates the FreeBSD 6 and higher system has
1300 UFS1 and UFS2 members in its inode structure.
1302 HAS_UM_UFS indicates the OpenBSD version has UM_UFS[12]
1305 HASUNMINSOCK indicates the Linux version has a user name
1306 element in the socket structure; a value of
1307 0 says there is no unix_address member; 1,
1310 HASUINT16TYPE is defined when the dialect has a typedef
1311 for u_int16 that may conflict with some other
1312 header file's redefinition (e.g., <afs/std.h>).
1314 HASUXSOCKEPT indicates the Linux version has support for the
1315 UNIX socket endpoint option.
1317 HASUTMPX indicates the dialect has a <utmpx.h> header
1320 HAS_UVM_INCL indicates the NetBSD or OpenBSD dialect has
1321 a <uvm> include directory.
1323 HAS_UW_CFS indicates the UnixWare 7.1.1 or above dialect
1324 has CFS file system support.
1326 HAS_UW_NSC indicates the UnixWare 7.1.1 or above dialect
1327 has a NonStop Cluster (NSC) kernel.
1329 HAS_V_LOCKF indicates the FreeBSD version has a v_lockf
1330 member in the vode structure, defined in
1333 HAS_VM_MEMATTR_T indicates the FreeBSD <sys/conf.h> uses the
1334 vm_memattr_t typedef.
1336 HASVMLOCKH indicates the FreeBSD dialect has <vm/lock.h>.
1338 HASVNODE enables/disables readvnode() function in node.c.
1340 HAS_V_PATH indicates the dialect's vnode structure has a
1343 HAS_VSOCK indicates that the Solaris version has a VSOCK
1344 member in the vtype enum
1346 HASVXFS enables Veritas VxFS file system support for
1347 the dialect. CAUTION, the dialect sources
1348 must have the necessary support code.
1350 HASVXFSDNLC indicates the VxFS file system has its own
1353 HASVXFS_FS_H indicates <sys/fs/vx_fs.h> exists.
1355 HASVXFS_MACHDEP_H indicates <sys/fs/vx_machdep.h> exists.
1357 HASVXFS_OFF64_T indicates <sys/fs/vx_solaris.h> exists and
1358 has an off64_t typedef.
1360 HASXVFSRNL indicates the dialect has VxFS Reverse Name
1361 Lookup (RNL) support.
1363 HASVXFS_SOL_H indicates <sys/fs/vx_sol.h> exists.
1365 HASVXFS_SOLARIS_H indicates <sys/fs/vx_solaris.h> exists.
1367 HASVXFS_U64_T if HASVXFS_SOLARIS_H is defined, this
1368 variable indicates that <sys/fs/vx_solaris.h>
1369 has a vx_u64_t typedef.
1371 HASVXFSUTIL indicates the Solaris dialect has VxFS 3.4
1372 or higher and has the utility libraries,
1373 libvxfsutil.a (32 bit) and libvxfsutil64.a
1376 HASVXFS_VX_INODE indicates that <sys/fs/vx_inode.h> contains
1377 a vx_inode structure.
1379 HASWCTYPE_H indicates the FreeBSD version has wide-character
1380 support and the <wctype.h> header file. Note:
1381 the HASWIDECHAR #define will also be set.
1383 HASWIDECHAR indicates the dialect has the wide-character
1384 support functions iswprint(), mblen() and mbtowc().
1386 HASXNAMNODE indicates the OSR dialect has <sys/fs/xnamnode.h>.
1388 HASXOPT defines help text for dialect-specific X option
1389 and enables X option processing in usage.c and
1392 HASXOPT_ROOT when defined, restricts the dialect-specific
1393 X option to processes whose real user ID
1396 HASXOPT_VALUE defines the default binary value for the X option
1399 HAS_ZFS indicates the dialect has support for the ZFS file
1402 HASZONES the Solaris dialect has zones.
1404 HAVECLONEMAJ defines the name of the status variable
1405 that indicates a clone major device number
1406 is available in CLONEMAJ. (Also see CLONEMAJ
1409 HPUX_KERNBITS defines the number of bits in the HP-UX 10.30
1410 and above kernel "basic" word: 32 or 64.
1412 KA_T defines the type cast required to assign
1413 space to kernel pointers. When not defined
1414 by a dialect header file, KA_T defaults to
1417 KA_T_FMT_X defines the printf format for printing a
1418 KA_T -- the default is "%#lx" for the
1419 default unsigned long KA_T cast.
1421 LSOF_ARCH See 00XCONFIG.
1423 LSOF_BLDCMT See 00XCONFIG.
1425 LSOF_CC See 00XCONFIG.
1427 LSOF_CCV See 00XCONFIG.
1429 LSOF_HOST See 00XCONFIG.
1431 LSOF_INCLUDE See 00XCONFIG.
1433 LSOF_LOGNAME See 00XCONFIG.
1435 LSOF_MKC See the "The Mksrc Shell Script" section of
1438 LSOF_SYSINFO See 00XCONFIG.
1440 LSOF_USER See 00XCONFIG.
1442 LSOF_VERS See 00XCONFIG.
1444 LSOF_VSTR See 00XCONFIG.
1446 MACH defines a MACH system.
1448 N_UNIXV defines an alternate value for the N_UNIV symbol.
1450 NCACHELDPFX defines C code to be executed before calling
1453 NCACHELDSFX defines C code to be executed after calling
1456 NEEDS_BOOL_TYPEDEF indicates the FreeBSD 10 system, being built on an
1457 i386 architecture systemn, needs typdef bool.
1459 NEEDS_BOOLEAN_T indicates the FreeBSD 9 and above system needs a
1460 boolean_t definition for <sys/conf.h>.
1462 NEEDS_MACH_PORT_T is defined for Darwin versions that need the inclusion
1463 of the header file <device/device_types.h>.
1465 NEEDS_NETINET_TCPH is defined when the Linux version needs to #include
1466 <netinet/tcp.h> in place of <linux/tcp.h> in order to
1467 have access to the TCP_* definitions.
1469 NEVER_HASDCACHE keeps the Customize script from offering to
1470 change HASDCACHE by its presence anywhere
1471 in a dialect's machine.h header file --
1472 e.g., in a comment. See the Customize
1473 script or machine.h in dialects/linux/proc.
1475 NEVER_WARNDEVACCESS keeps the Customize script from offering to
1476 change WARNDEVACCESS by its presence anywhere
1477 in a dialect's machine.h header file --
1478 including in a comment. See the Customize
1479 script or machine.h in dialects/linux/proc.
1481 NLIST_TYPE is the type of the nlist table, Nl[], if it is
1482 not nlist. HASNLIST must be set for this
1483 definition to be effective.
1485 NOWARNBLKDEV specifies that no warning is to be issued
1486 when no block devices are found. This
1487 definiton is used only when HASBLKDEV is
1490 OFFDECDIG specifies how many decimal digits will be
1491 printed for the file offset in a 0t form
1492 before switching to a 0x form. The count
1493 includes the "0t". A count of zero means
1494 the size is unlimited.
1496 PRIVFILETYPE is the number of a private file type, found
1497 in the f_type member of the file struct, to
1498 be processed by the HASPRIVFILETYPE function.
1499 See the AIX dialect sources for an example.
1501 _PSTAT_STREAM_GET_XPORT
1502 indicates the HP-UX PSTAT header files require
1503 this symbol to be defined for proper handling of
1506 SAVE_MP_IN_SFILE indicates the dialect needs to have the mounts
1507 structure pointer for a file system search argument
1508 recorded in the dialect's sfile structure. This
1509 definition is made in the dialect's dlsof.h header
1510 file within the sfile structure.
1512 TIMEVAL_LSOF defines the name of the timeval structure.
1513 The default is timeval. /dev/kmem-based
1514 Linux lsof redefines timeval with this
1515 symbol to avoid conflicts between glibc
1516 and kernel definitions.
1518 TYPELOGSECSHIFT defines the type of the cdfs_LogSecShift
1519 member of the cdfs structure for UnixWare
1522 UID_ARG_T defines the cast on a User ID when passed
1523 as a function argument.
1526 selects the use of the completevfs() function
1527 in lsof4/lib/cvfs.c.
1530 selects the use of the find_ch_ino() inode
1531 function in lsof4/lib/fino.c.
1533 Note: HASBLKDEV selects the has_bl_ino()
1536 USE_LIB_IS_FILE_NAMED
1537 selects the use of the is_file_named() function
1538 in lsof4/lib/isfn.c.
1540 USE_LIB_LKUPDEV selects the use of the lkupdev() function
1541 in lsof4/lib/lkud.c.
1543 Note: HASBLKDEV selects the lkupbdev() function.
1545 USE_LIB_PRINTDEVNAME
1546 selects the use of the printdevname() function
1547 in lsof4/lib/pdvn.c.
1549 Note: HASBLKDEV selects the printbdevname()
1552 USE_LIB_PRINT_TCPTPI
1553 selects the use of the print_tcptpi() function
1554 in lsof4/lib/ptti.c.
1556 USE_LIB_PROCESS_FILE
1557 selects the use of the process_file() function
1558 in lsof4/lib/prfp.c.
1560 USE_LIB_READDEV selects the use of the readdev() and stkdir()
1561 functions in lsof4/lib/rdev.c.
1563 USE_LIB_READMNT selects the use of the readmnt() function
1564 in lsof4/lib/rmnt.c.
1566 USE_LIB_RNAM selects the use of the device cache functions
1567 in lsof4/lib/rnam.c.
1569 Note: HASNCACHE must also be defined.
1571 USE_LIB_RNCH selects the use of the device cache functions
1572 in lsof4/lib/rnch.c.
1574 Note: HASNCACHE must also be defined.
1576 USE_STAT is defined for those dialects that must
1577 use the stat(2) function instead of lstat(2)
1578 to scan /dev -- i.e., in the readdev()
1581 VNODE_VFLAG is an alternate name for the vnode structure's
1584 WARNDEVACCESS enables the issuing of a warning message when
1585 lsof is unable to access /dev (or /device)
1586 or one of its subdirectories, or stat(2)
1587 a file in them. Some dialects (e.g., HP-UX)
1588 have many inaccessible subdirectories and
1589 it is appropriate to inhibit the warning
1590 for them with WARNDEVACCESS. The -w option
1591 will also inhibit these warnings.
1593 WARNINGSTATE when defined, disables the default issuing
1594 of warning messages. WARNINGSTATE is
1595 undefined by default for all dialects in
1596 the lsof distribution.
1598 WIDECHARINCL defines the header file to be included (if any)
1599 when wide-character support is enabled with
1602 zeromem() defines a macro to zero memory -- e.g., using
1603 bzero() or memset().
1605 Any dialect's machine.h file and Configure stanza can serve as a
1606 template for building your own. All machine.h files usually have
1607 all definitions, disabling some (with comment prefix and suffix)
1608 and enabling others.
1611 Options: Common and Special
1612 ---------------------------
1614 All but one lsof option is common; the specific option is ``-X''.
1615 If a dialect does not support a common option, the related #define
1616 in machine.h -- e.g., HASCOPT -- should be deselected.
1618 The specific option, ``-X'', may be used by any dialect for its
1619 own purpose. Right now (May 30, 1995) the ``-X'' option is binary
1620 (i.e., it's not allowed arguments of its own, and its value must
1621 be 0 or 1) but that could be changed should the need arise. The
1622 option is enabled with the HASXOPT definition in machine.h; its
1623 default value is defined by HASXOPT_VALUE.
1625 The value of HASXOPT should be the text displayed for ``-X'' by
1626 the usage() function in usage.c. HASXOPT_VALUE should be the
1627 default value, 0 or 1.
1629 AIX for the IBM RICS System/6000 defines the ``-X'' option to
1630 control readx() usage, since there is a bug in AIX kernels that
1631 readx() can expose for other processes.
1634 Defining Dialect-Specific Symbols and Global Storage
1635 ----------------------------------------------------
1637 A dialect's dlsof.h and dstore.c files contain dialect-specific
1638 symbol and global storage definitions. There are symbol definitions,
1639 for example, for function and data casts, and for file paths.
1640 Dslof.h defines lookup names the nlist() table -- X_* symbols --
1641 when nlist() is being used.
1643 Global storage definitions include such things as structures for
1644 local Virtual File System (vfs) information; mount information;
1645 search file information; and kernel memory file descriptors --
1646 e.g., Kmem for /dev/kmem, Mem for /dev/mem, Swap for /dev/drum.
1649 Coding Dialect-specific Functions
1650 ---------------------------------
1652 Each supported dialect must have some basic functions that the
1653 common functions of the top level may call. Some of them may be
1654 obtained from the library in lsof4/lib, selected and customized by
1655 #define's in the dialect machine.h header file. Others may have
1656 to be coded specifically for the dialect.
1658 Each supported dialect usually has private functions, too. Those
1659 are wholly determined by the needs of the dialect's data organization
1662 These are some of the basic functions that each dialect must supply
1663 -- they're all defined in proto.h:
1665 initialize() function to initialize the dialect
1667 is_file_named() function to check if a file was named
1668 by an optional file name argument
1671 gather_proc_info() function to gather process table
1672 and related information and cache it
1674 printchdevname() function to locate and optionally
1675 print the name of a character device
1678 print_tcptpistate() function to print the TCP or TPI
1679 state for a TCP or UDP socket file,
1680 if the one in lib/ptti.c isn't
1681 suitable (define USE_LIB_PRINT_TCPTPI
1682 to activate lib/ptti.c)
1684 process_file() function to process an open file
1685 structure (lsof4/lib/prfp.c)
1687 process_node() function to process a primary node
1689 process_socket() function to process a socket
1691 readdev() and stkdir() functions to read and cache device
1692 information (lsof4/lib/rdev.c)
1694 readmnt() function to read mount table information
1697 Other common functions may be needed, and might be obtained from
1698 lsof4/lib, depending on the needs of the dialect's node and socket
1699 file processing functions.
1701 Check the functions in lsof4/lib and specific lsof4/dialects/*
1704 As you build these functions you will probably have to add #include's
1708 Function Prototype Definitions and the _PROTOTYPE Macro
1709 -------------------------------------------------------
1711 Once you've defined your dialect-specific definitions, you should
1712 define their prototypes in dproto.h or locally in the file where
1713 they occur and are used. Do this even if your compiler is not ANSI
1714 compliant -- the _PROTOTYPE macro knows how to cope with that and
1715 will avoid creating prototypes that will confuse your compiler.
1721 Here are some general rules for constructing the dialect Makefile.
1723 * Use an existing dialect's Makefile as a template.
1725 * Make sure the echo actions of the install rule are appropriate.
1727 * Use the DEBUG string to set debugging options, like ``-g''.
1728 You may also need to use the -O option when forking and
1729 SIGCHLD signals defeat your debugger.
1731 * Don't put ``\"'' in a compiler flags -D<symbol>=<string>
1732 clause in your Makefile. Leave off the ``\"'' even though
1733 you want <string> to be a string literal and instead adapt
1734 the N_UNIX* macros you'll find in Makefiles for FreeBSD
1735 and Linux. That will allow the Makefile's version.h rule
1736 to put CFLAGS into version.h without having to worry about
1737 the ``\"'' sequences.
1739 * Finally, remember that strings can be passed from the top
1740 level's Configure shell script. That's an appropriate way
1741 to handle options, especially if there are multiple versions
1742 of the Unix dialect to which you are porting lsof 4.
1745 The Mksrc Shell Script
1746 ----------------------
1748 Pattern your Mksrc shell script after an existing one from another
1749 dialect. Change the D shell variable to the name of your dialect's
1750 subdirectory in lsof4/dialects. Adjust any other shell variable
1751 to your local conditions. (Probably that won't be necessary.)
1753 Note that, if using symbolic links from the top level to your
1754 dialect subdirectory is impossible or impractical, you can set the
1755 LSOF_MKC shell variable in Configure to something other than
1756 "ln -s" -- e.g., "cp," and Configure will pass it to the Mksrc
1757 shell script in the M environment variable.
1760 The MkKernOpts Shell Script
1761 ---------------------------
1763 The MkKernOptrs shell script is used by some dialects -- e.g.,
1764 Pyramid DC/OSx and Reliant UNIX -- to determine the compile-time
1765 options used to build the current kernel that affect kernel structure
1766 definitions, so those same options can be used to build lsof.
1767 Configure calls MkKernOpts for the selected dialects.
1769 If your kernel is built with options that affect structure definitions.
1770 -- most commonly affected are the proc structure from <sys/proc.h>
1771 and the user structure from <sys/user.h> -- check the MkKernOpts
1772 in lsof4/dialects/irix for a comprehensive example.
1775 Testing and the Lsof Test Suite
1776 -------------------------------
1778 Once you have managed to create a port, here are some tips for
1781 * First look at the test suite in the tests/ sub-directory of the
1782 lsof distribution. While it will need to be customized to be
1783 usable with a new port, it should provide ideas on things to
1784 test. Look for more information about the test suite in the
1787 * Pick a simple process whose open files you are likely to
1788 know and see if the lsof output agrees with what you know.
1789 (Hint: select the process with `lsof -p <process_PID>`.)
1791 Are the device numbers and device names correct?
1793 Are the file system names and mount points correct?
1795 Are inode numbers and sizes correct?
1797 Are command names, file descriptor numbers, UIDs, PIDs, PGIDs,
1800 A simple tool that does a stat(2) of the files being examined
1801 and reports the stat struct contents can provide a reference for
1802 some values; so can `ls -l /dev/<device>`.
1804 * Let lsof list information about all open files and ask the
1805 same questions. Look also for error messages about not being
1806 able to read a node or structure.
1808 * Pick a file that you know is open -- open it and hold it
1809 that way with a C program (not vi), if you must. Ask lsof to
1810 find the file's open instance by specifying its path to lsof.
1812 * Create a C program that opens a large number of files and holds
1813 them open. Background the test process and ask lsof to list
1816 * Generate some locks -- you may need to write a C program to
1817 do this, hold the locked file open, and see if lsof can identify
1818 the lock properly. You may need to write several C programs
1819 if your dialect supports different lock functions -- fnctl(),
1820 flock(), lockf(), locking().
1822 * Identify a process with known Internet file usage -- inetd
1823 is a good one -- and ask lsof to list its open files. See if
1824 protocols and service names are listed properly.
1826 See if your lsof identifies Internet socket files properly for
1827 rlogind or telnetd processes.
1829 * Create a UNIX domain socket file, if your dialect allows it,
1830 hold it open by backgrounding the process, and see if lsof can
1831 identify the open UNIX domain socket file properly.
1833 * Create a FIFO file and see what lsof says about it.
1835 * Watch an open pipe -- `lsof -u <your_login> | less` is a
1836 good way to do this.
1838 * See if lsof can identify NFS files and their devices properly.
1839 Open and hold open an NFS file and see if lsof can find the open
1842 * If your test system has CD-ROM and floppy disk devices, open
1843 files on them and see if lsof reports their information correctly.
1844 Such devices often have special kernel structures associated
1845 with them and need special attention from lsof for their
1846 identification. Pay particular attention to the inode numbers
1847 lsof reports for CD-ROM and floppy disk files -- often they are
1848 calculated dynamically, rather than stored in a kernel node
1851 * If your implementation can probe the kernel name cache, look
1852 at some processes with open files whose paths you know to see
1853 if lsof identifies any name components. If it doesn't, make
1854 sure the name components are in the name cache by accessing
1855 the files yourself with ls or a similar tool.
1857 * If your dialect supports the /proc file system, use a C program
1858 to open files there, background a test process, and ask lsof to
1859 report its open files.
1861 * If your dialect supports fattach(), create a small test program
1862 to use it, background a test process, and ask lsof to report
1865 I can supply some quick-and-dirty tools for reporting stat buffer
1866 contents, holding files open, creating UNIX domain files, creating
1867 FIFOs, etc., if you need them.
1873 Is this document complete? Certainly not! One might wish that it
1874 were accompanied by man pages for all lsof functions, by free beer
1875 or chocolates, by ... (You get the idea.)
1877 But those things are not likely to happen as long as lsof is a
1878 privately supported, one man operation.
1880 So, if you need more information on how lsof is constructed or
1881 works in order to do a port of your own, you'll have to read the
1882 lsof source code. You can also ask me questions via email, but
1883 keep in mind the private, one-man nature of current lsof support.
1886 Vic Abell <abe@purdue.edu>