Bump to lsof 4.91
[platform/upstream/lsof.git] / 00PORTING
1
2                 Guide to Porting lsof 4 to Unix OS Dialects
3
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        |
7 | location.                                                          |
8 **********************************************************************
9
10                             Contents
11
12         How Lsof Works
13         /proc-based Linux Lsof -- a Different Approach
14         General Guidelines
15         Organization
16         Source File Naming Conventions
17         Coding Philosophies
18         Data Requirements
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
25         The Makefile
26         The Mksrc Shell Script
27         The MkKernOpts Shell Script
28         Testing and the lsof Test Suite
29         Where Next?
30
31
32 How Lsof Works
33 --------------
34
35 Before getting on with porting guidelines, just a word or two about
36 how lsof works.
37
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.
43
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.
49
50 Once all data has been gathered, lsof reports it from its internal,
51 local tables.
52
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.
62
63
64 /proc-based Linux Lsof -- a Different Approach
65 ==============================================
66
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.)
71
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.
76
77 There are some down-sides to the Linux /proc-based lsof:
78
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
82        permission.
83
84     *  It depends on the exact character format of /proc files, so
85        it is sensitive to changes in /proc file composition.
86
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
94        file.
95
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.
100
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
107 measure.
108
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.
113
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.
117
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.
122
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:
126
127     *  A modification to /usr/src/linux/net/ipx/af_ipx.c adds the
128        inode number to the entries of /proc/net/ipx.
129
130        Jonathan Sergent did this kernel modification.
131
132        It may be found in the .../dialects/linux/proc/patches
133        subdirectory of the lsof distribution.
134
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.
138        
139        Contact me for this modification.
140
141
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.
144
145
146 General Guidelines
147 ------------------
148
149 These are the general guidelines for porting lsof 4 to a new Unix
150 dialect:
151
152     *  Understand the organization of the lsof sources and the
153        philosophies that guide their coding.
154
155     *  Understand the data requirements and determine the methods
156        of locating the necessary data in the new dialect's kernel.
157
158     *  Pick a name for the subdirectory in lsof4/dialects for your
159        dialect.  Generally I use a vendor operating system name
160        abbreviation.
161
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.)
165
166     *  Determine the optional library functions of lsof to be used
167        and set their definitions in the dialect's machine.h file.
168
169     *  Define the dialect's specific symbols and global storage
170        in the dialect's dlsof.h and dstore.c files.
171
172     *  Code the dialect-specific functions in the appropriate
173        source files of the dialect's subdirectory.
174
175        Include the necessary prototype definitions of the dialect-
176        specific functions in the dproto.h file in the dialect's
177        subdirectory.
178
179     *  Define the dialect's Makefile and source construction shell
180        script, Mksrc.
181
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.
186
187
188 Organization
189 ------------
190
191 The code in a dialect-specific version of lsof comes from three
192 sources:
193
194     1)  functions common to all versions, located in the top level
195         directory, lsof4;
196
197     2)  functions specific to the dialect, located in the dialect's
198         subdirectory -- e.g., lsof4/dialects/sun;
199
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.
204
205 The tree looks like this:
206
207                             lsof4 ----------------------+ 3) library --
208                             |   \                            lsof4/lib
209   1) fully common functions +    \
210       e.g., lsof4/main.c          + lsof4/dialects/
211                            / / / / \
212                            + + + +  +
213   2) dialect-specific subdirectories -- e.g., lsof4/dialects/sun
214
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
220 subdirectories.
221
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.
228
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.
234
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
240 definitions.
241
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.
245
246
247 Source File Naming Conventions
248 ------------------------------
249
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.
255
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.
261
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.
266
267 These are common files in lsof4/:
268
269     Configure   the configuration script
270
271     Customize   does some customization of the selected lsof
272                 dialect
273
274     Inventory   takes an inventory of the files in an lsof
275                 distribution
276
277     version     the version number
278
279     dialects/   the dialects subdirectory
280
281 These are the common function source files in lsof4/:
282
283     arg.c       common argument processing functions
284
285     lsof.h      common header file that #include's the dialect-specific
286                 header files
287
288     main.c      common main function for lsof 4
289
290     misc.c      common miscellaneous functions -- e.g., special versions
291                 of stat() and readlink()
292
293     node.c      common node reading functions -- readinode(), readvnode()
294
295     print.c     common print support functions
296
297     proc.c      common process and file structure functions
298
299     proto.h     common prototype definitions, including the definition of
300                 the _PROTOTYPE() macro
301
302     store.c     common global storage version.h the current lsof version
303                 number, derived from the file version by the Makefile
304
305     usage.c     functions to display lsof usage panel
306
307 These are the dialect-specific files:
308
309     Makefile    the Makefile skeleton
310
311     Mksrc       a shell script that assists the Configure script
312                 in configuring dialect sources
313
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
317
318     ddev.c      device support functions -- readdev() -- may be
319                 eliminated by functions from lsof4/lib/
320
321     dfile.c     file processing functions -- may be eliminated by
322                 functions from lsof4/lib/
323
324     dlsof.h     dialect-specific header file -- contains #include's
325                 for system header files and dialect-specific global
326                 storage declarations
327
328     dmnt.c      mount support functions -- may be eliminated by
329                 functions from lsof4/lib/
330
331     dnode.c     node processing functions -- e.g., for gnode or vnode
332
333     dnode?.c    additional node processing functions, used when node
334                 header files have duplicate and conflicting element
335                 names.
336
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()
340
341     dproto.h    dialect-specific prototype declarations
342
343     dsock.c     dialect-specific socket processing functions
344
345     dstore.c    dialect-specific global storage -- e.g., the nlist()
346                 structure
347
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
351
352                 The machine.h header file also selects and customizes
353                 the functions of lsof4/lib/.
354
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.
358
359     Makefile.skel       is a skeleton Makefile, used by Configure
360                         to construct the Makefile for the lsof
361                         library.
362
363     cvfs.c              completevfs() function
364
365                         USE_LIB_COMPLETEVFS selects it.
366
367                         CVFS_DEVSAVE, CVFS_NLKSAVE, CVFS_SZSAVE,
368                         and HASFSINO customize it.
369
370     dvch.c              device cache functions
371
372                         HASDCACHE selects them.
373
374                         DCACHE_CLONE, DCACHE_CLR, DCACHE_PSEUDO,
375                         DVCH_CHOWN, DVCH_DEVPATH, DVCH_EXPDEV,
376                         HASBLKDEV, HASENVDC, HASSYSDC, HASPERSDC,
377                         HASPERSDCPATH, and NOWARNBLKDEV customize
378                         them.
379
380     fino.c              find block and character device inode functions
381
382                         HASBLKDEV and USE_LIB_FIND_CH_INO select them.
383
384     isfn.c              hashSfile() and is_file_named() functions
385
386                         USE_LIB_IS_FILE_NAMED selects it.
387
388     lkud.c              device lookup functions
389
390                         HASBLKDEV and USE_LIB_LKUPDEV select them.
391
392     pdvn.c              print device name functions
393
394                         HASBLKDEV and USE_LIB_PRINTDEVNAME select them.
395
396     prfp.c              process_file() function
397
398                         USE_LIB_PROCESS_FILE selects it.
399
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.
404
405     ptti.c              print_tcptpi() function
406
407                         USE_LIB_PRINT_TCPTPI selects it.
408
409                         HASSOOPT, HASSBSTATE, HASSOSTATE, AHSTCPOPT,
410                         HASTCPTPIQ and HASTCPTPIW customize it.
411
412     rdev.c              readdev() function
413
414                         USE_LIB_READDEV selects it.
415
416                         DIRTYPE, HASBLKDEV, HASDCACHE, HASDNAMLEN,
417                         RDEV_EXPDEV, RDEV_STATFN, USE_STAT, and
418                         WARNDEVACCESS customize it.
419
420     rmnt.c              readmnt() function
421
422                         USE_LIB_READMNT selects it.
423
424                         HASFSTYPE, MNTSKIP, RMNT_EXPDEV, RMNT_FSTYPE,
425                         and MOUNTS_FSTYPE customize it.
426
427     rnam.c              BSD format name cache functions
428
429                         HASNCACHE and USE_LIB_RNAM select them.
430
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.
436
437     rnch.c              Sun format name cache functions
438
439                         HASNCACHE and USE_LIB_RNCH select them.
440
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
445                         them.
446
447     snpf.c              Source for the snprintf() family of functions
448
449                         USE_LIB_SNPF selects it.
450
451
452 The comments and the source code in these library files give more
453 information on customization.
454
455
456 Coding Philosophies
457 -------------------
458
459 A few basic philosophies govern the coding of lsof 4 functions:
460
461     *  Use as few #if/#else/#endif constructs as possible, even at
462        the cost of nearly-duplicate code.
463
464        When #if/#else/#endif constructs are necessary:
465        
466        o  Use the form
467
468                 #if     defined(s<symbol>)
469         
470           in preference to
471         
472                 #ifdef  <symbol>
473         
474           to allow easier addition of tests to the #if.
475
476        o  Indent them to signify their level -- e.g.,
477
478                 #if     /* level one */
479                 # if    /* level two */
480                 # endif /* level two */
481                 #else   /* level one */
482                 #endif  /* level one */
483
484         o  Use ANSI standard comments on #else and #endif statements.
485
486     *  Document copiously.
487
488     *  Aim for ANSI-C compatibility:
489     
490        o  Use function prototypes for all functions, hiding them
491           from compilers that cannot handle them with the _PROTOTYPE()
492           macro.
493
494        o  Use the compiler's ANSI conformance checking wherever
495           possible -- e.g., gcc's -ansi option.
496
497
498 Data Requirements
499 -----------------
500
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.
507
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.
513
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
519 and macros.
520
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.
526
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.
532
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.
537
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".
542
543 Once you can access kernel structures, you must understand how
544 they're connected.  You must answer questions like:
545
546     *  How big are kernel addresses?  How are they type cast?
547
548     *  How are kernel variable names converted to addresses?
549        Nlist()?
550
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?
555
556     *  How does one obtain copies of the proc structures?  Via
557        /dev/kmem?  Via a vendor API?
558
559     *  If this is a Mach derivative, is it necessary to obtain the
560        task and thread structures?  How?
561
562     *  How does one obtain the user area (or the utask area in Mach
563        systems) that corresponds to a process?
564
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
568        extensible?
569
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.
573
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.
580
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.
588
589     *  How is the device table -- e.g., /dev or /devices --
590        organized?  How is it read?  Using direct or dirent structures?
591
592        How are major/minor device numbers represented?  How are
593        device numbers assembled and disassembled?
594
595        Are there clone devices?  How are they identified?
596
597     *  How is mount information obtained?  Getmntinfo()?  Getmntent()?
598        Some special kernel call?
599
600     *  How are sockets identified and organized?  BSD-style?  As
601        streams?  Are there streams?
602
603     *  Are there special nodes -- CD-ROM nodes, FIFO nodes, etc.?
604
605     *  How is the kernel's name cache organized?  Can lsof access
606        it to get partial name components?
607
608
609 Dlsof.h and #include's
610 ----------------------
611
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.
617
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.
623
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).
631
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
635 dlsof.h frequently.
636
637
638 Definitions That Affect Compilation
639 -----------------------------------
640
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.
649
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
655 possibilities
656
657     AFS_VICE            See 00XCONFIG.
658
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.
661
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().
665
666     CLONEMAJ            defines the name of the variable that
667                         contains the clone major device number.
668                         (Also see HAS_STD_CLONE and HAVECLONEMAJ.)
669
670     DEVDEV_PATH         defines the path to the directory where device
671                         nodes are stored, usually /dev.  Solaris 10
672                         uses /devices.
673
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.
677
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).
681
682     GET_MAJ_DEV         is a macro to get major portion from device
683                         number instead of via the standard major()
684                         macro.
685
686     GET_MIN_DEV         is a macro to get minor portion from device
687                         number instead of via the standard minor()
688                         macro.
689
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
693                         getdtablesize.
694
695     HAS9660FS           enables CD9660 file system support in a
696                         BSD dialect.
697
698     HAS_ADVLOCK_ARGS    is defined for NetBSD and OpenBSD dialects
699                         whose <sys/lockf.h> references vop_advlock_args.
700
701     HAS_AFS             enables AFS support code for the dialect.
702
703     HAS_AIO_REQ_STRUCT  is defined for Solaris 10 and above systems that
704                         have the aio_req structure definition.
705
706     HAS_ATOMIC_T        indicates the Linux version has an
707                         <asm/atomic.h> header file and it contains
708                         "typedef struct .* atomic_t;"
709
710     HASAOPT             indicates the dialect supports the AFS -A
711                         option when HAS_AFS is also defined.
712
713     HAS_ASM_TERMIOBITS  indicates for Linux Alpha that the
714                         <asm/termiobits.h> header file exists.
715
716     HASAX25CBPTR        indicates that the Linux sock struct has an
717                         ax25_db pointer.
718
719     HASBLKDEV           indicates the dialect has block device support.
720
721     HASBUFQ_H           indicates the *NSD dialect has the <sys/bufq.h>
722                         header file.
723
724     HASCACHEFS          enables cache file system support for the
725                         dialect.
726
727     HAS_CDFS            enables CDFS file system support for the
728                         dialect.
729
730     HASCDRNODE          enables/disables readcdrnode() in node.c.
731
732     HAS_CLOSEFROM       is defined when the FreeBSD C library contains the
733                         closefrom() function.
734
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.
739
740     HAS_CONST           indicates that the compiler supports the
741                         const keyword.
742
743     HASCPUMASK_T        indicates the FreeBSD 5.2 or higher dialect
744                         has cpumask_t typedef's.
745
746     HAS_CRED_IMPL_H     indicates the Solaris 10 dialect has the
747                         <sys/cred_impl.h> header file available.
748
749     HASCWDINFO          indicates the cwdinfo structure is defined
750                         in the NetBSD <sys/filedesc.h>.
751
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
759                         feature.
760
761     HASDENTRY           indicates the Linux version has a dentry
762                         struct defined in <linux/dcache.h>.
763
764     HASDEVKNC           indicates the Linux version has a kernel
765                         name cached keyed on device number.
766
767     HAS_DINODE_U        indicates the OpenBSD version has a dinode_u
768                         union in its inode structure.
769
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.
773
774     HAS_DUP2            is defined when the FreeBSD C library contains the
775                         dup2() function.
776
777     HASEFFNLINK         indicates the *BSD system has the i_effnlink
778                         member in the inode structure.
779
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.)
786
787     HASEOPT             indicates the dialect supports the -e option to
788                         eliminate kernel blocks on a named file system.
789
790     HASEPTOPTS          indicates the dialect supports the +|-E end point
791                         options.
792
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
796                         exist; 2, it exists.
797
798     HASF_VNODE          indicates the dialect's file structure has an
799                         f_vnode member in it.
800
801     HAS_FDESCENTTBL     indicates the FreeBSD system has the fdescenttbl
802                         structure.
803
804     HAS_FILEDESCENT     indicates the FreeBSD system has the filedescent
805                         definition in the <sys/filedesc.h> header file.
806
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,
810                         it does not.
811
812     HASFDLINK           indicates the file descriptor file system
813                         node has the fd_link member.
814
815     HASFIFONODE         enables/disables readfifonode() in node.c.
816
817     HAS_FL_FD           indicates the Linux version has an fl_fd
818                         element in the lock structure of <linux/fs.h>.
819
820     HAS_FL_FILE         indicates the Linux version has an fl_file
821                         element in the lock structure of <linux/fs.h>.
822
823     HAS_FL_WHENCE       indicates the Linux version has an fl_whence
824                         element in the lock structure of <linux/fs.h>.
825
826     HAS_F_OPEN          indicates the UnixWare 7.x dialect has the
827                         f_open member in its file struct.
828
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
834                         an example.
835
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.
840
841     HASFSTYPE           enables/disables the use of the file system's
842                         stat(2) st_fstype member.
843
844                         If the HASFSTYPE value is 1, st_fstype is
845                         treated as a character array; 2, it is
846                         treated as an integer.
847
848                         See also the RMNT_EXPDEV and RMNT_FSTYPE
849                         documentation in lib/rmnt.c
850
851     HASFUSEFS           is defined when the FreeBSD system has FUSE file system
852                         support.
853
854     HASGETBOOTFILE      indicates the NetBSD or OpenBSD dialect has
855                         a getbootfile() function.
856
857     HASGNODE            enables/disables readgnode() in node.c.
858
859     HASHASHPID          is defined when the Linux version (probably
860                         above 2.1.35) has a pidhash_next member in
861                         its task structure.
862
863     HASHSNODE           enables/disables readhsnode() in node.c.
864
865     HASI_E2FS_PTR       indicates the BSD dialect has a pointer in
866                         its inode to the EXTFS dinode.
867
868     HASI_FFS            indicates the BSD dialect has i_ffs_size
869                         in <ufs/ufs/inode.h>.
870
871     HASI_FFS1           indicates the BSD dialect supports the fast
872                         UFS1 and UFS2 file systems.
873
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
877                         <netinet/tcp_var.h>.
878
879     HASINODE            enables/disables readinode() in node.c.
880
881     HASINOKNC           indicates the Linux version has a kernel
882                         name cache keyed on inode address.
883
884     HASINADDRSTR        is defined when the inp_[fl]addr members
885                         of the inpcb structure are structures.
886
887     HASINRIAIPv6        is defined if the dialect has the INRIA IPv6
888                         support.  (HASIPv6 will also be defined.)
889
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>).
893
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>).
897
898     HASINTSIGNAL        is defined when signal() returns an int.
899
900     HAS_IPCLASSIFIER_H  is defined for Solaris dialects that have the
901                         <inet/ipclassifier.h> header file.
902
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.
909
910     HASIPv6             indicates the dialect supports the IPv6
911                         Internet address family.
912
913     HAS_JFS2            The AIX >= 5.0 dialect has jfs2 support.
914
915     HASKERNELKEYT       indicates the Linux version has a
916                         __kernel_key_t typedef in <linux/types.h>.
917
918     HASKERNFS           is defined for BSD dialects for which
919                         /kern file system support can be provided.
920
921     HASKERNFS_KFS_KT    indicates *kfs_kt is in the BSD dialect's
922                         <miscfs/kernfs/kernfs.h>.
923
924     HASKOPT             enables/disables the ability to read the
925                         kernel's name list from a file -- e.g., from
926                         a crash dump file.
927
928     HAS_PAUSE_SBT       indicates the FreeBSD system's systm.h has the
929                         pause to pause_sbt definition.
930
931     HASKQUEUE           indicates the dialect supports the kqueue
932                         file type.
933
934     HASKVMGETPROC2      The *BSD dialect has the kvm_gettproc2()
935                         function.
936
937     HAS_KVM_VNODE       indicates the FreeBSD 5.3 or higher dialect has
938                         "defined(_KVM_VNODE)" in <sys/vnode.h>.
939
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.
945
946     HAS_LF_LWP          is defined for BSD dialects where the lockf
947                         structure has an lf_lwp member.
948
949     HASLFS              indicates the *BSD dialect has log-structured
950                         file system support.
951
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.
956
957     HAS_LIBCTF          indicates the Solaris 10 and above system has
958                         the CTF library.
959
960     HAS_LOCKF_ENTRY     indicates the FreeBSD version has a lockf_entry
961                         structure in its <sys/lockf.h> header file.
962
963     HAS_LWP_H           is defined for BSD dialects that have the
964                         <sys/lwp.h> header file.
965
966     HASMOPT             enables/disables the ability to read kernel
967                         memory from a file -- e.g., from a crash
968                         dump file.
969
970     HASMSDOSFS          enables MS-DOS file system support in a
971                         BSD dialect.
972
973     HASMNTSTAT          indicates the dialect has a stat(2) status
974                         element in its mounts structure.
975
976     HASMNTSUP           indicates the dialect supports the mount supplement
977                         option.
978
979     HASNAMECACHE        indicates the FreeBSD dialect has a namecache
980                         structure definition in <sys/namei.h>.
981
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.
987
988     HASNCVPID           The *BSD dialect namecache struct has an
989                         nc_vpid member.
990
991     HASNETDEVICE_H      indicates the Linux version has a netdevice.h
992                         header file.
993
994     HAS_NFS             enables NFS support for the dialect.
995
996     HASNFSKNC           indicates the LINUX version has a separate
997                         NFS name cache.
998
999     HASNFSPROTO         indicates the NetBSD or OpenBSD version
1000                         has the nfsproto.h header file.
1001
1002     HASNFSVATTRP        indicates the n_vattr member of the nfsnode of
1003                         the *BSD dialect is a pointer.
1004
1005     HASNLIST            enables/disables nlist() function support.
1006                         (See NLIST_TYPE.)
1007
1008     HASNOFSADDR         is defined if the dialect has no file structure
1009                         addresses.  (HASFSTRUCT must be defined.)
1010
1011     HASNOFSCOUNT        is defined if the dialect has no file structure counts.
1012                         (HASFSTRUCT must be defined.)
1013
1014     HASNOFSFLAGS        is defined if the dialect has no file structure flags.
1015                         (HASFSTRUCT must be defined.)
1016
1017     HASNOFSNADDR        is defined if the dialect has no file structure node
1018                         addresses.  (HASFSTRUCT must be defined.)
1019
1020     HAS_NO_6PORT        is defined if the FreeBSD in_pcb.h has no in6p_.port
1021                         definitions.
1022
1023     HAS_NO_6PPCB        is defined if the FreeBSD in_pcb.h has no in6p_ppcb
1024                         definition.
1025
1026     HAS_NO_IDEV         indicates the FreeBSD system's inode has no i_dev
1027                         member.
1028
1029     HAS_NO_ISO_DEV      indicates the FreeBSD 6 and higher system has
1030                         no i_dev member in its iso_node structure.
1031
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.
1035
1036     HASNORPC_H          indicates the dialect has no /usr/include/rpc/rpc.h
1037                         header file.
1038
1039     HAS_NO_SI_UDEV      indicates the FreeBSD 6 and higher system has
1040                         no si_udev member in its cdev structure.
1041
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
1048                         is also defined.
1049
1050     HASNULLFS           indicates the dialect (usually *BSD) has a
1051                         null file system.
1052
1053     HASOBJFS            indicates the Pyramid version has OBJFS
1054                         support.
1055
1056     HASONLINEJFS        indicates the HP-UX 11 dialect has the optional
1057                         OnlineJFS package installed.
1058
1059     HAS_PC_DIRENTPERSEC
1060                         indicates the Solaris 10 system's <sys/fs/pc_node.h>
1061                         header file has the pc_direntpersec() macro.
1062
1063     HAS_PAD_MUTEX       indicates the Solaris 11 system has the pad_mutex_t
1064                         typedef in its <sys/mutex.h> header file.
1065
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
1070                         on the format.
1071
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
1078                         cache file path.
1079
1080     HASPINODEN          declares that the inode number of a /proc file
1081                         should be stored in its procfsid structure.
1082
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.
1087
1088     HASPIPENODE         enables/disables readpipenode() in node.c.
1089
1090     HASPMAPENABLED      enables the automatic reporting of portmapper
1091                         registration information for TCP and UDP
1092                         ports that have been registered.
1093
1094     HASPPID             indicates the dialect has parent PID support.
1095
1096     HASPR_LDT           indicates the Solaris dialect has a pr_ldt
1097                         member in the pronodetype enum.
1098
1099     HASPR_GWINDOWS      indicates the Solaris dialect has a pr_windows
1100                         member in the pronodetype enum.
1101
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:
1105
1106                         char *HASPRINTDEV(struct lfile *)
1107
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:
1111
1112                         char *HASPRINTINO(struct lfile *)
1113
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:
1117
1118                         void HASPRINTNM(struct lfile *)
1119
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:
1123
1124                         char *HASPRINTOFF(struct lfile *, int ty)
1125
1126                         Where ty == 0 if the offset is to be printed
1127                         in 0t<decimal> format; 1, 0x<hexadecimal>.
1128
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:
1132
1133                         char *HASPRINTSZ(struct lfile *)
1134
1135                         void HASPRINTNM(struct lfile *)
1136
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()
1145                         function.
1146
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.
1153
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().
1158
1159     HASPROCFS           defines the name (if any) of the process file
1160                         system -- e.g., /proc.
1161
1162     HASPROCFS_PFSROOT   indicates PFSroot is in the BSD dialect's
1163                         <miscfs/procfs/procfs.h>.
1164
1165     HASPSEUDOFS         indicates the FreeBSD dialect has pseudofs
1166                         file system support.
1167
1168     HASPSXSEM           indicates the dialect has support for the POSIX
1169                         semaphore file type.
1170
1171     HASPSXSHM           indicates the dialect has support for the POSIX
1172                         shared memory file type.
1173
1174     HASPTSFN            indicates the dialect has a DNODE_PTS file descriptor
1175                         type and defines the function that processes it.
1176
1177     HASPTYEPT           indicates the Linux dialect has support for the
1178                         pseudoterminal endpoint option.
1179
1180     HASPTYFS            indicates the *BSD dialect has a ptyfs file system.
1181
1182     HASRNODE            enables/disables readrnode() in node.c.
1183
1184     HASRNODE3           indicates the HPUX 10.20 or lower dialect has NFS3
1185                         support with a modified rnode structure.
1186
1187     HASRPCV2H           The FreeBSD dialect has <nfs/rpcv2.h>.
1188
1189     HAS_SANFS           indicates the AIX system has SANFS file system
1190                         support.
1191
1192     HAS_SB_CC           indicates the FreeBSD system's sockbuf structure has
1193                         the sb_ccc member, rather than the sb_cc member.
1194
1195     HASSBSTATE          indicates the dialect has socket buffer state
1196                         information (e.g., SBS_* symbols) available.
1197
1198     HASSECURITY         enables/disables restricting open file
1199                         information access.  (Also see HASNOSOCKSECURITY.)
1200
1201     HASSELINUX          indicates the Linux dialect has SELinux security
1202                         context support available.
1203
1204     HASSETLOCALE        is defined if the dialect has <locale.h> and
1205                         setlocale().
1206
1207     HAS_SI_PRIV         indicates the FreeBSD 6.0 and higher cdev
1208                         structure has an si_priv member.
1209
1210     HAS_SOCKET_PROTO_H  indicates the Solaris 10 system has the header file
1211                         <sys/socket_proto.h>.
1212
1213     HASSOUXSOUA         indicates that the Solaris <sys/socketvar.h> has
1214                         soua_* members in its so_ux_addr structure.
1215
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.
1220
1221     HASSPECNODE         indicates the DEC OSF/1, or Digital UNIX,
1222                         or Tru64 UNIX <sys/specdev.h> has a spec_node
1223                         structure definition.
1224
1225     HASSNODE            indicates the dialect has snode support.
1226
1227     HAS_SOCKET_SK       indicates that the Linux socket structure
1228                         has the ``struct sock *sk'' member.
1229
1230     HASSOOPT            indicates the dialect has socket option
1231                         information (e.g., SO_* symbols) available.
1232
1233     HASSOSTATE          indicates the dialect has socket state
1234                         information (e.g., SS_* symbols) available.
1235
1236     HASSTATVFS          indicates the NetBSD dialect has a statvfs
1237                         struct definition.
1238
1239     HASSTAT64           indicates the dialect's <sys/stat.h> contains
1240                         stat64.
1241
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.)
1250
1251     HASSTREAMS          enables/disables streams.  CAUTION, requires
1252                         specific support code in the dialect sources.
1253
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.
1258
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.
1264
1265     HAS_SYS_PIPEH       indicates the dialect has a <sys/pipe.h>
1266                         header file.
1267
1268     HAS_SYS_SX_H        indicates the FreeBSD 7.0 and higher system has
1269                         a <sys/sx.h> header file.
1270
1271     HASTAGTOPATH        indicates the DEC OSF/1, Digital UNIX, or
1272                         Tru64 UNIX dialect has a libmsfs.so,
1273                         containing tag_to_path().
1274
1275     HAS_TMPFS           indicates the FreeBSD system has the <fs/tmpfs.h>
1276                         header file.
1277
1278     HASTMPNODE          enables/disables readtnode() in node.c.
1279
1280     HASTCPOPT           indicates the dialect has TCP option
1281                         information (i.e., from TF_* symbols)
1282                         available.
1283
1284     HASTCPTPIQ          is defined when the dialect can duplicate
1285                         the receive and send queue sizes reported
1286                         by netstat.
1287
1288     HASTCPTPIW          is defined when the dialect can duplicate
1289                         the receive and send window sizes reported
1290                         by netstat.
1291
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.
1295
1296     HASTFS              indicates that the Pyramid dialect has TFS
1297                         file system support.
1298
1299     HAS_UFS1_2          indicates the FreeBSD 6 and higher system has
1300                         UFS1 and UFS2 members in its inode structure.
1301
1302     HAS_UM_UFS          indicates the OpenBSD version has UM_UFS[12]
1303                         definitions.
1304
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,
1308                         there is.
1309
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>).
1313
1314     HASUXSOCKEPT        indicates the Linux version has support for the
1315                         UNIX socket endpoint option.
1316
1317     HASUTMPX            indicates the dialect has a <utmpx.h> header
1318                         file.
1319
1320     HAS_UVM_INCL        indicates the NetBSD or OpenBSD dialect has
1321                         a <uvm> include directory.
1322
1323     HAS_UW_CFS          indicates the UnixWare 7.1.1 or above dialect
1324                         has CFS file system support.
1325
1326     HAS_UW_NSC          indicates the UnixWare 7.1.1 or above dialect
1327                         has a NonStop Cluster (NSC) kernel.
1328
1329     HAS_V_LOCKF         indicates the FreeBSD version has a v_lockf
1330                         member in the vode structure, defined in
1331                         <sys/vnode.h>.
1332
1333     HAS_VM_MEMATTR_T    indicates the FreeBSD <sys/conf.h> uses the
1334                         vm_memattr_t typedef.
1335
1336     HASVMLOCKH          indicates the FreeBSD dialect has <vm/lock.h>.
1337
1338     HASVNODE            enables/disables readvnode() function in node.c.
1339
1340     HAS_V_PATH          indicates the dialect's vnode structure has a
1341                         v_path member.
1342
1343     HAS_VSOCK           indicates that the Solaris version has a VSOCK
1344                         member in the vtype enum
1345
1346     HASVXFS             enables Veritas VxFS file system support for
1347                         the dialect.  CAUTION, the dialect sources
1348                         must have the necessary support code.
1349
1350     HASVXFSDNLC         indicates the VxFS file system has its own
1351                         name cache.
1352
1353     HASVXFS_FS_H        indicates <sys/fs/vx_fs.h> exists.
1354
1355     HASVXFS_MACHDEP_H   indicates <sys/fs/vx_machdep.h> exists.
1356
1357     HASVXFS_OFF64_T     indicates <sys/fs/vx_solaris.h> exists and
1358                         has an off64_t typedef.
1359
1360     HASXVFSRNL          indicates the dialect has VxFS Reverse Name
1361                         Lookup (RNL) support.
1362
1363     HASVXFS_SOL_H       indicates <sys/fs/vx_sol.h> exists.
1364
1365     HASVXFS_SOLARIS_H   indicates <sys/fs/vx_solaris.h> exists.
1366
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.
1370
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
1374                         (64 bit).
1375
1376     HASVXFS_VX_INODE    indicates that <sys/fs/vx_inode.h> contains
1377                         a vx_inode structure.
1378
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.
1382
1383     HASWIDECHAR         indicates the dialect has the wide-character
1384                         support functions iswprint(), mblen() and mbtowc().
1385
1386     HASXNAMNODE         indicates the OSR dialect has <sys/fs/xnamnode.h>.
1387
1388     HASXOPT             defines help text for dialect-specific X option
1389                         and enables X option processing in usage.c and
1390                         main.c.
1391
1392     HASXOPT_ROOT        when defined, restricts the dialect-specific
1393                         X option to processes whose real user ID
1394                         is root.
1395
1396     HASXOPT_VALUE       defines the default binary value for the X option
1397                         in store.c.
1398
1399     HAS_ZFS             indicates the dialect has support for the ZFS file
1400                         system.
1401
1402     HASZONES            the Solaris dialect has zones.
1403
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
1407                         and HAS_STD_CLONE.)
1408
1409     HPUX_KERNBITS       defines the number of bits in the HP-UX 10.30
1410                         and above kernel "basic" word: 32 or 64.
1411
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
1415                         unsigned long.
1416
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.
1420
1421     LSOF_ARCH           See 00XCONFIG.
1422
1423     LSOF_BLDCMT         See 00XCONFIG.
1424
1425     LSOF_CC             See 00XCONFIG.
1426
1427     LSOF_CCV            See 00XCONFIG.
1428
1429     LSOF_HOST           See 00XCONFIG.
1430
1431     LSOF_INCLUDE        See 00XCONFIG.
1432
1433     LSOF_LOGNAME        See 00XCONFIG.
1434
1435     LSOF_MKC            See the "The Mksrc Shell Script" section of
1436                         this file.
1437
1438     LSOF_SYSINFO        See 00XCONFIG.
1439
1440     LSOF_USER           See 00XCONFIG.
1441
1442     LSOF_VERS           See 00XCONFIG.
1443
1444     LSOF_VSTR           See 00XCONFIG.
1445
1446     MACH                defines a MACH system.
1447
1448     N_UNIXV             defines an alternate value for the N_UNIV symbol.
1449
1450     NCACHELDPFX         defines C code to be executed before calling
1451                         ncache_load().
1452
1453     NCACHELDSFX         defines C code to be executed after calling
1454                         ncache_load().
1455
1456     NEEDS_BOOL_TYPEDEF  indicates the FreeBSD 10 system, being built on an
1457                         i386 architecture systemn, needs typdef bool.
1458
1459     NEEDS_BOOLEAN_T     indicates the FreeBSD 9 and above system needs a
1460                         boolean_t definition for <sys/conf.h>.
1461
1462     NEEDS_MACH_PORT_T   is defined for Darwin versions that need the inclusion
1463                         of the header file <device/device_types.h>.
1464
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.
1468
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.
1474
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.
1480
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.
1484
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
1488                         also defined.
1489
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.
1495
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.
1500
1501     _PSTAT_STREAM_GET_XPORT
1502                         indicates the HP-UX PSTAT header files require
1503                         this symbol to be defined for proper handling of
1504                         stream export data.
1505
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.
1511
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.
1517
1518     TYPELOGSECSHIFT     defines the type of the cdfs_LogSecShift
1519                         member of the cdfs structure for UnixWare
1520                         7 and higher.
1521
1522     UID_ARG_T           defines the cast on a User ID when passed
1523                         as a function argument.
1524
1525     USE_LIB_COMPLETEVFS
1526                         selects the use of the completevfs() function
1527                         in lsof4/lib/cvfs.c.
1528
1529     USE_LIB_FIND_CH_INO
1530                         selects the use of the find_ch_ino() inode
1531                         function in lsof4/lib/fino.c.
1532
1533                         Note: HASBLKDEV selects the has_bl_ino()
1534                         function.
1535
1536     USE_LIB_IS_FILE_NAMED
1537                         selects the use of the is_file_named() function
1538                         in lsof4/lib/isfn.c.
1539
1540     USE_LIB_LKUPDEV     selects the use of the lkupdev() function
1541                         in lsof4/lib/lkud.c.
1542
1543                         Note: HASBLKDEV selects the lkupbdev() function.
1544
1545     USE_LIB_PRINTDEVNAME
1546                         selects the use of the printdevname() function
1547                         in lsof4/lib/pdvn.c.
1548
1549                         Note: HASBLKDEV selects the printbdevname()
1550                         function.
1551
1552     USE_LIB_PRINT_TCPTPI
1553                         selects the use of the print_tcptpi() function
1554                         in lsof4/lib/ptti.c.
1555
1556     USE_LIB_PROCESS_FILE
1557                         selects the use of the process_file() function
1558                         in lsof4/lib/prfp.c.
1559
1560     USE_LIB_READDEV     selects the use of the readdev() and stkdir()
1561                         functions in lsof4/lib/rdev.c.
1562
1563     USE_LIB_READMNT     selects the use of the readmnt() function
1564                         in lsof4/lib/rmnt.c.
1565
1566     USE_LIB_RNAM        selects the use of the device cache functions
1567                         in lsof4/lib/rnam.c.
1568
1569                         Note: HASNCACHE must also be defined.
1570
1571     USE_LIB_RNCH        selects the use of the device cache functions
1572                         in lsof4/lib/rnch.c.
1573
1574                         Note: HASNCACHE must also be defined.
1575
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()
1579                         function.
1580
1581     VNODE_VFLAG         is an alternate name for the vnode structure's
1582                         v_flag member.
1583
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.
1592
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.
1597
1598     WIDECHARINCL        defines the header file to be included (if any)
1599                         when wide-character support is enabled with
1600                         HASWIDECHAR.
1601
1602     zeromem()           defines a macro to zero memory -- e.g., using
1603                         bzero() or memset().
1604
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.
1609
1610
1611 Options: Common and Special
1612 ---------------------------
1613
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.
1617
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.
1624
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.
1628
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.
1632
1633
1634 Defining Dialect-Specific Symbols and Global Storage
1635 ----------------------------------------------------
1636
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.
1642
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.
1647
1648
1649 Coding Dialect-specific Functions
1650 ---------------------------------
1651
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.
1657
1658 Each supported dialect usually has private functions, too.  Those
1659 are wholly determined by the needs of the dialect's data organization
1660 and access.
1661
1662 These are some of the basic functions that each dialect must supply
1663 -- they're all defined in proto.h:
1664
1665     initialize()                function to initialize the dialect
1666
1667     is_file_named()             function to check if a file was named
1668                                 by an optional file name argument
1669                                 (lsof4/lib/isfn.c)
1670
1671     gather_proc_info()          function to gather process table
1672                                 and related information and cache it
1673
1674     printchdevname()            function to locate and optionally
1675                                 print the name of a character device
1676                                 (lsof4/lib/pdvn.c)
1677
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)
1683
1684     process_file()              function to process an open file
1685                                 structure (lsof4/lib/prfp.c)
1686
1687     process_node()              function to process a primary node
1688
1689     process_socket()            function to process a socket
1690
1691     readdev() and stkdir()      functions to read and cache device
1692                                 information (lsof4/lib/rdev.c)
1693
1694     readmnt()                   function to read mount table information
1695                                 (lsof4/lib/rmnt.c)
1696
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.
1700
1701 Check the functions in lsof4/lib and specific lsof4/dialects/*
1702 files for examples.
1703
1704 As you build these functions you will probably have to add #include's
1705 to dlsof.h.
1706
1707
1708 Function Prototype Definitions and the _PROTOTYPE Macro
1709 -------------------------------------------------------
1710
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.
1716
1717
1718 The Makefile
1719 ------------
1720
1721 Here are some general rules for constructing the dialect Makefile.
1722
1723     *  Use an existing dialect's Makefile as a template.
1724
1725     *  Make sure the echo actions of the install rule are appropriate.
1726
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.
1730
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.
1738
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.
1743
1744
1745 The Mksrc Shell Script
1746 ----------------------
1747
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.)
1752
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.
1758
1759
1760 The MkKernOpts Shell Script
1761 ---------------------------
1762
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.
1768
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.
1773
1774
1775 Testing and the Lsof Test Suite
1776 -------------------------------
1777
1778 Once you have managed to create a port, here are some tips for
1779 testing it.
1780
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
1785    00TEST file.
1786
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>`.)
1790
1791    Are the device numbers and device names correct?
1792
1793    Are the file system names and mount points correct?
1794
1795    Are inode numbers and sizes correct?
1796
1797    Are command names, file descriptor numbers, UIDs, PIDs, PGIDs,
1798    and PPIDs correct?
1799
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>`.
1803
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.
1807
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.
1811
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
1814    its files.
1815
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().
1821
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.
1825
1826    See if your lsof identifies Internet socket files properly for
1827    rlogind or telnetd processes.
1828
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.
1832
1833 *  Create a FIFO file and see what lsof says about it.
1834
1835 *  Watch an open pipe -- `lsof -u <your_login>  | less` is a
1836    good way to do this.
1837
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
1840    instance by path.
1841
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
1849    structure.
1850
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.
1856
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.
1860
1861 *  If your dialect supports fattach(), create a small test program
1862    to use it, background a test process, and ask lsof to report
1863    its open files.
1864
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.
1868
1869
1870 Where Next?
1871 -----------
1872
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.)
1876
1877 But those things are not likely to happen as long as lsof is a
1878 privately supported, one man operation.
1879
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.
1884
1885
1886 Vic Abell <abe@purdue.edu>
1887 February 14, 2018