Imported Upstream version 4.88
[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,
402                         HASF_VNODE, HASKQUEUE, HASPRIVFILETYPE,
403                         HASPSXSHM and HASPSXSEM 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_ATOMIC_T        indicates the Linux version has an
704                         <asm/atomic.h> header file and it contains
705                         "typedef struct .* atomic_t;"
706
707     HASAOPT             indicates the dialect supports the AFS -A
708                         option when HAS_AFS is also defined.
709
710     HAS_ASM_TERMIOBITS  indicates for Linux Alpha that the
711                         <asm/termiobits.h> header file exists.
712
713     HASAX25CBPTR        indicates that the Linux sock struct has an
714                         ax25_db pointer.
715
716     HASBLKDEV           indicates the dialect has block device support.
717
718     HASBUFQ_H           indicates the *NSD dialect has the <sys/bufq.h>
719                         header file.
720
721     HASCACHEFS          enables cache file system support for the
722                         dialect.
723
724     HAS_CDFS            enables CDFS file system support for the
725                         dialect.
726
727     HASCDRNODE          enables/disables readcdrnode() in node.c.
728
729     HAS_CONN_NEW        indicates the Solaris version has the new form
730                         of the conn_s structure, introduced in b134 of
731                         Solaris 11.  This will always accompany the
732                         HAS_IPCLASSIFIER_H definition.
733
734     HAS_CONST           indicates that the compiler supports the
735                         const keyword.
736
737     HASCPUMASK_T        indicates the FreeBSD 5.2 or higher dialect
738                         has cpumask_t typedef's.
739
740     HAS_CRED_IMPL_H     indicates the Solaris 10 dialect has the
741                         <sys/cred_impl.h> header file available.
742
743     HASCWDINFO          indicates the cwdinfo structure is defined
744                         in the NetBSD <sys/filedesc.h>.
745
746     HASDCACHE           enables device file cache file support.
747                         The device cache file contains information
748                         about the names, device numbers and inode
749                         numbers of entries in the /dev (or /device)
750                         node subtree that lsof saves from call to
751                         call.  See the 00DCACHE file of the lsof
752                         distribution for more information on this
753                         feature.
754
755     HASDENTRY           indicates the Linux version has a dentry
756                         struct defined in <linux/dcache.h>.
757
758     HASDEVKNC           indicates the Linux version has a kernel
759                         name cached keyed on device number.
760
761     HAS_DINODE_U        indicates the OpenBSD version has a dinode_u
762                         union in its inode structure.
763
764     HASDNLCPTR          is defined when the name cache entry of
765                         <sys/dnlc.h> has a name character pointer
766                         rather than a name character array.
767
768     HASEFFNLINK         indicates the *BSD system has the i_effnlink
769                         member in the inode structure.
770
771     HASENVDC            enables the use of an environment-defined
772                         device cache file path and defines the name
773                         of the environment variable from which lsof
774                         may take it.  (See the 00DCACHE file of
775                         the lsof distribution for information on
776                         when HASENVDC is used or ignored.)
777
778     HASEOPT             indicates the dialect supports the -e option to
779                         eliminate kernel blocks on a named file system.
780
781     HASEPTOPTS          indicates the dialect supports the +|-E end point
782                         options.
783
784     HASEXT2FS           is defined for BSD dialects for which ext2fs
785                         file system support can be provided.  A value
786                         of 1 indicates that the i_e2din member does not
787                         exist; 2, it exists.
788
789     HASF_VNODE          indicates the dialect's file structure has an
790                         f_vnode member in it.
791
792     HAS_FILEDESCENT     indicates the FreeBSD system has the filedescent
793                         definition in the <sys/filedesc.h> header file.
794
795     HASFDESCFS          enables file descriptor file system support
796                         for the dialect.   A value of 1 indicates
797                         <miscfs/fdesc.h> has a Fctty definition; 2,
798                         it does not.
799
800     HASFDLINK           indicates the file descriptor file system
801                         node has the fd_link member.
802
803     HASFIFONODE         enables/disables readfifonode() in node.c.
804
805     HAS_FL_FD           indicates the Linux version has an fl_fd
806                         element in the lock structure of <linux/fs.h>.
807
808     HAS_FL_FILE         indicates the Linux version has an fl_file
809                         element in the lock structure of <linux/fs.h>.
810
811     HAS_FL_WHENCE       indicates the Linux version has an fl_whence
812                         element in the lock structure of <linux/fs.h>.
813
814     HAS_F_OPEN          indicates the UnixWare 7.x dialect has the
815                         f_open member in its file struct.
816
817     HASFSINO            enables the inclusion of the fs_ino element
818                         in the lfile structure definition in lsof.h.
819                         This contains the file system's inode number
820                         and may be needed when searching the kernel
821                         name cache.  See dialects/osr/dproc.c for
822                         an example.
823
824     HASFSTRUCT          indicates the dialect has a file structure
825                         the listing of whose element values can be
826                         enabled with +f[cfn].  FSV_DEFAULT defines
827                         the default listing values.
828
829     HASFSTYPE           enables/disables the use of the file system's
830                         stat(2) st_fstype member.
831
832                         If the HASFSTYPE value is 1, st_fstype is
833                         treated as a character array; 2, it is
834                         treated as an integer.
835
836                         See also the RMNT_EXPDEV and RMNT_FSTYPE
837                         documentation in lib/rmnt.c
838
839     HASGETBOOTFILE      indicates the NetBSD or OpenBSD dialect has
840                         a getbootfile() function.
841
842     HASGNODE            enables/disables readgnode() in node.c.
843
844     HASHASHPID          is defined when the Linux version (probably
845                         above 2.1.35) has a pidhash_next member in
846                         its task structure.
847
848     HASHSNODE           enables/disables readhsnode() in node.c.
849
850     HASI_E2FS_PTR       indicates the BSD dialect has a pointer in
851                         its inode to the EXTFS dinode.
852
853     HASI_FFS            indicates the BSD dialect has i_ffs_size
854                         in <ufs/ufs/inode.h>.
855
856     HASI_FFS1           indicates the BSD dialect supports the fast
857                         UFS1 and UFS2 file systems.
858
859     HAS_INKERNEL        indicates the SCO OSR 6.0.0 or higher, or
860                         UnixWare 7.1.4 or higher system uses the
861                         INKERNEL symbol in <netinet/in_pcb.h> or
862                         <netinet/tcp_var.h>.
863
864     HASINODE            enables/disables readinode() in node.c.
865
866     HASINOKNC           indicates the Linux version has a kernel
867                         name cache keyed on inode address.
868
869     HASINADDRSTR        is defined when the inp_[fl]addr members
870                         of the inpcb structure are structures.
871
872     HASINRIAIPv6        is defined if the dialect has the INRIA IPv6
873                         support.  (HASIPv6 will also be defined.)
874
875     HASINT16TYPE        is defined when the dialect has a typedef
876                         for int16 that may conflict with some other
877                         header file's redefinition (e.g., <afs/std.h>).
878
879     HASINT32TYPE        is defined when the dialect has a typedef
880                         for int32 that may conflict with some other
881                         header file's redefinition (e.g., <afs/std.h>).
882
883     HASINTSIGNAL        is defined when signal() returns an int.
884
885     HAS_IPCLASSIFIER_H  is defined for Solaris dialects that have the
886                         <inet/ipclassifier.h> header file.
887
888     HAS_IPC_S_PATCH     is defined when the HP-UX 11 dialect has the
889                         ipc_s patch installed.  It has a value of
890                         1 if the ipc_s structure has an ipc_ipis
891                         member, but the ipis_s structure lacks the
892                         ipis_msgsqueued member; 2, if ipc_s has
893                         ipc_ipis, but ipis_s lacks ipis_msgsqueued.
894
895     HASIPv6             indicates the dialect supports the IPv6
896                         Internet address family.
897
898     HAS_JFS2            The AIX >= 5.0 dialect has jfs2 support.
899
900     HASKERNELKEYT       indicates the Linux version has a
901                         __kernel_key_t typedef in <linux/types.h>.
902
903     HASKERNFS           is defined for BSD dialects for which
904                         /kern file system support can be provided.
905
906     HASKERNFS_KFS_KT    indicates *kfs_kt is in the BSD dialect's
907                         <miscfs/kernfs/kernfs.h>.
908
909     HASKOPT             enables/disables the ability to read the
910                         kernel's name list from a file -- e.g., from
911                         a crash dump file.
912
913     HAS_PAUSE_SBT       indicates the FreeBSD system's systm.h has the
914                         pause to pause_sbt definition.
915
916     HASKQUEUE           indicates the dialect supports the kqueue
917                         file type.
918
919     HASKVMGETPROC2      The *BSD dialect has the kvm_gettproc2()
920                         function.
921
922     HAS_KVM_VNODE       indicates the FreeBSD 5.3 or higher dialect has
923                         "defined(_KVM_VNODE)" in <sys/vnode.h>.
924
925     HASLFILEADD         defines additional, dialect-specific elements
926     SETLFILEADD         in the lfile structure (defined in lsof.h).
927                         HASLFILEADD is a macro. The accompanying SETFILEADD
928                         macro is used in the alloc_lfile() function of
929                         proc.c to preset the additional elements.
930
931     HAS_LF_LWP          is defined for BSD dialects where the lockf
932                         structure has an lf_lwp member.
933
934     HASLFS              indicates the *BSD dialect has log-structured
935                         file system support.
936
937     HAS_LGRP_ROOT_CONFLICT
938                         indicates the Solaris 9 or Solaris 10 system has 
939                         a conflict over the lgrp_root symbol in the
940                         <sys/lgrp.h> and <sys/lgrp_user.h> header files.
941
942     HAS_LIBCTF          indicates the Solaris 10 and above system has
943                         the CTF library.
944
945     HAS_LOCKF_ENTRY     indicates the FreeBSD version has a lockf_entry
946                         structure in its <sys/lockf.h> header file.
947
948     HAS_LWP_H           is defined for BSD dialects that have the
949                         <sys/lwp.h> header file.
950
951     HASMOPT             enables/disables the ability to read kernel
952                         memory from a file -- e.g., from a crash
953                         dump file.
954
955     HASMSDOSFS          enables MS-DOS file system support in a
956                         BSD dialect.
957
958     HASMNTSTAT          indicates the dialect has a stat(2) status
959                         element in its mounts structure.
960
961     HASMNTSUP           indicates the dialect supports the mount supplement
962                         option.
963
964     HASNAMECACHE        indicates the FreeBSD dialect has a namecache
965                         structure definition in <sys/namei.h>.
966
967     HASNCACHE           enables the probing of the kernel's name cache
968                         to obtain path name components.  A value
969                         of 1 directs printname() to prefix the
970                         cache value with the file system directory
971                         name; 2, avoid the prefix.
972
973     HASNCVPID           The *BSD dialect namecache struct has an
974                         nc_vpid member.
975
976     HASNETDEVICE_H      indicates the Linux version has a netdevice.h
977                         header file.
978
979     HAS_NFS             enables NFS support for the dialect.
980
981     HASNFSKNC           indicates the LINUX version has a separate
982                         NFS name cache.
983
984     HASNFSPROTO         indicates the NetBSD or OpenBSD version
985                         has the nfsproto.h header file.
986
987     HASNFSVATTRP        indicates the n_vattr member of the nfsnode of
988                         the *BSD dialect is a pointer.
989
990     HASNLIST            enables/disables nlist() function support.
991                         (See NLIST_TYPE.)
992
993     HASNOFSADDR         is defined if the dialect has no file structure
994                         addresses.  (HASFSTRUCT must be defined.)
995
996     HASNOFSCOUNT        is defined if the dialect has no file structure counts.
997                         (HASFSTRUCT must be defined.)
998
999     HASNOFSFLAGS        is defined if the dialect has no file structure flags.
1000                         (HASFSTRUCT must be defined.)
1001
1002     HASNOFSNADDR        is defined if the dialect has no file structure node
1003                         addresses.  (HASFSTRUCT must be defined.)
1004
1005     HAS_NO_6PORT        is defined if the FreeBSD in_pcb.h has no in6p_.port
1006                         definitions.
1007
1008     HAS_NO_6PPCB        is defined if the FreeBSD in_pcb.h has no in6p_ppcb
1009                         definition.
1010
1011     HAS_NO_ISO_DEV      indicates the FreeBSD 6 and higher system has
1012                         no i_dev member in its iso_node structure.
1013
1014     HAS_NO_LONG_LONG    indicates the dialect has no support for the C
1015                         long long type.  This definition is used by
1016                         the built-in snprintf() support of lib/snpf.c.
1017
1018     HASNORPC_H          indicates the dialect has no /usr/include/rpc/rpc.h
1019                         header file.
1020
1021     HAS_NO_SI_UDEV      indicates the FreeBSD 6 and higher system has
1022                         no si_udev member in its cdev structure.
1023
1024     HASNOSOCKSECURITY   enables the listing of open socket files,
1025                         even when HASSECURITY restricts listing of
1026                         open files to the UID of the user who is
1027                         running lsof, provided socket file listing
1028                         is selected with the "-i" option.  This
1029                         definition is only effective when HASSECURITY
1030                         is also defined.
1031
1032     HASNULLFS           indicates the dialect (usually *BSD) has a
1033                         null file system.
1034
1035     HASOBJFS            indicates the Pyramid version has OBJFS
1036                         support.
1037
1038     HASONLINEJFS        indicates the HP-UX 11 dialect has the optional
1039                         OnlineJFS package installed.
1040
1041     HAS_PC_DIRENTPERSEC
1042                         indicates the Solaris 10 system's <sys/fs/pc_node.h>
1043                         header file has the pc_direntpersec() macro.
1044
1045     HAS_PAD_MUTEX       indicates the Solaris 11 system has the pad_mutex_t
1046                         typedef in its <sys/mutex.h> header file.
1047
1048     HASPERSDC           enables the use of a personal device cache
1049                         file path and specifies a format by which
1050                         it is constructed.  See the 00DCACHE file
1051                         of the lsof distribution for more information
1052                         on the format.
1053
1054     HASPERSDCPATH       enables the use of a modified personal
1055                         device cache file path and specifies the
1056                         name of the environment variable from which
1057                         its component may be taken.  See the 00DCACHE
1058                         file of the lsof distribution for more
1059                         information on the modified personal device
1060                         cache file path.
1061
1062     HASPINODEN          declares that the inode number of a /proc file
1063                         should be stored in its procfsid structure.
1064
1065     HASPIPEFN           defines the function that processes DTYPE_PIPE
1066                         file structures.  It's used in the prfp.c
1067                         library source file.  See the FreeBSD
1068                         dialect source for an example.
1069
1070     HASPIPENODE         enables/disables readpipenode() in node.c.
1071
1072     HASPMAPENABLED      enables the automatic reporting of portmapper
1073                         registration information for TCP and UDP
1074                         ports that have been registered.
1075
1076     HASPPID             indicates the dialect has parent PID support.
1077
1078     HASPR_LDT           indicates the Solaris dialect has a pr_ldt
1079                         member in the pronodetype enum.
1080
1081     HASPR_GWINDOWS      indicates the Solaris dialect has a pr_windows
1082                         member in the pronodetype enum.
1083
1084     HASPRINTDEV         this value defines a private function for
1085                         printing the dialect's device number.  Used
1086                         by print.c/print_file().  Takes one argument:
1087
1088                         char *HASPRINTDEV(struct lfile *)
1089
1090     HASPRINTINO         this value names a private function for
1091                         printing the dialect's inode number.  Used
1092                         by print.c/print_file(). Takes one argument:
1093
1094                         char *HASPRINTINO(struct lfile *)
1095
1096     HASPRINTNM          this value names a private function for
1097                         printing the dialect's file name.  Used by
1098                         print.c/print_file().  Takes one argument:
1099
1100                         void HASPRINTNM(struct lfile *)
1101
1102     HASPRINTOFF         this value names a private function for
1103                         printing the dialect's file offset.  Used
1104                         by print.c/print_file().  Takes two arguments:
1105
1106                         char *HASPRINTOFF(struct lfile *, int ty)
1107
1108                         Where ty == 0 if the offset is to be printed
1109                         in 0t<decimal> format; 1, 0x<hexadecimal>.
1110
1111     HASPRINTSZ          this value names a private function for
1112                         printing the dialect's file size.  Used
1113                         by print.c/print_file(). Takes one argument:
1114
1115                         char *HASPRINTSZ(struct lfile *)
1116
1117                         void HASPRINTNM(struct lfile *)
1118
1119     HASPRIVFILETYPE     enables processing of the private file
1120                         type, whose number (from f_type of the file
1121                         struct) is defined by PRIVFILETYPE.
1122                         HASPRIVFILETYPE defines the function that
1123                         processes the file struct's f_data member.
1124                         Processing is initiated from the process_file()
1125                         function of the prfp.c library source file
1126                         or from the dialect's own process_file()
1127                         function.
1128
1129     HASPRIVNMCACHE      enables printing of a file path from a
1130                         private name cache.  HASPRIVNMCACHE defines
1131                         the name of the printing function.  The
1132                         function takes one argument, a struct lfile
1133                         pointer to the file, and returns non-zero
1134                         if it prints a cached name to stdout.
1135
1136     HASPRIVPRIPP        is defined for dialects that have a private
1137                         function for printing the IP protocol name.
1138                         When this is not defined, the function to
1139                         do that defaults to printiproto().
1140
1141     HASPROCFS           defines the name (if any) of the process file
1142                         system -- e.g., /proc.
1143
1144     HASPROCFS_PFSROOT   indicates PFSroot is in the BSD dialect's
1145                         <miscfs/procfs/procfs.h>.
1146
1147     HASPSEUDOFS         indicates the FreeBSD dialect has pseudofs
1148                         file system support.
1149
1150     HASPSXSEM           indicates the dialect has support for the POSIX
1151                         semaphore file type.
1152
1153     HASPSXSHM           indicates the dialect has support for the POSIX
1154                         shared memory file type.
1155
1156     HASPTYFS            indicates the *BSD dialect has a ptyfs file system.
1157
1158     HASRNODE            enables/disables readrnode() in node.c.
1159
1160     HASRNODE3           indicates the HPUX 10.20 or lower dialect has NFS3
1161                         support with a modified rnode structure.
1162
1163     HASRPCV2H           The FreeBSD dialect has <nfs/rpcv2.h>.
1164
1165     HAS_SANFS           indicates the AIX system has SANFS file system
1166                         support.
1167
1168     HASSBSTATE          indicates the dialect has socket buffer state
1169                         information (e.g., SBS_* symbols) available.
1170
1171     HASSECURITY         enables/disables restricting open file
1172                         information access.  (Also see HASNOSOCKSECURITY.)
1173
1174     HASSELINUX          indicates the Linux dialect has SELinux security
1175                         context support available.
1176
1177     HASSETLOCALE        is defined if the dialect has <locale.h> and
1178                         setlocale().
1179
1180     HAS_SI_PRIV         indicates the FreeBSD 6.0 and higher cdev
1181                         structure has an si_priv member.
1182
1183     HAS_SOCKET_PROTO_H  indicates the Solaris 10 system has the header file
1184                         <sys/socket_proto.h>.
1185
1186     HASSOUXSOUA         indicates that the Solaris <sys/socketvar.h> has
1187                         soua_* members in its so_ux_addr structure.
1188
1189     HASSPECDEVD         indicates the dialect has a special device
1190                         directory and defines the name of a function
1191                         that processes the results of a successful
1192                         stat(2) of a file in that directory.
1193
1194     HASSPECNODE         indicates the DEC OSF/1, or Digital UNIX,
1195                         or Tru64 UNIX <sys/specdev.h> has a spec_node
1196                         structure definition.
1197
1198     HASSNODE            indicates the dialect has snode support.
1199
1200     HAS_SOCKET_SK       indicates that the Linux socket structure
1201                         has the ``struct sock *sk'' member.
1202
1203     HASSOOPT            indicates the dialect has socket option
1204                         information (e.g., SO_* symbols) available.
1205
1206     HASSOSTATE          indicates the dialect has socket state
1207                         information (e.g., SS_* symbols) available.
1208
1209     HASSTATVFS          indicates the NetBSD dialect has a statvfs
1210                         struct definition.
1211
1212     HASSTAT64           indicates the dialect's <sys/stat.h> contains
1213                         stat64.
1214
1215     HAS_STD_CLONE       indicates the dialect uses a standard clone
1216                         device structure that can be used in common
1217                         library function clone processing.  If the
1218                         value is 1, the clone table will be built
1219                         by readdev() and cached when HASDCACHE is
1220                         defined; if the value is 2, it is assumed
1221                         the clone table is built independently.
1222                         (Also see CLONEMAJ and HAVECLONEMAJ.)
1223
1224     HASSTREAMS          enables/disables streams.  CAUTION, requires
1225                         specific support code in the dialect sources.
1226
1227     HAS_STRFTIME        indicates the dialect has the gmtime() and
1228                         strftime() C library functions that support
1229                         the -r marker format option.  Configure tests
1230                         for the functions and defines this symbol.
1231
1232     HASSYSDC            enables the use of a system-wide device
1233                         cache file and defines its path.  See the
1234                         00DCACHE file of the lsof distribution for
1235                         more information on the system-wide device
1236                         cache file path option.
1237
1238     HAS_SYS_PIPEH       indicates the dialect has a <sys/pipe.h>
1239                         header file.
1240
1241     HAS_SYS_SX_H        indicates the FreeBSD 7.0 and higher system has
1242                         a <sys/sx.h> header file.
1243
1244     HASTAGTOPATH        indicates the DEC OSF/1, Digital UNIX, or
1245                         Tru64 UNIX dialect has a libmsfs.so,
1246                         containing tag_to_path().
1247
1248     HAS_TMPFS           indicates the FreeBSD system has the <fs/tmpfs.h>
1249                         header file.
1250
1251     HASTMPNODE          enables/disables readtnode() in node.c.
1252
1253     HASTCPOPT           indicates the dialect has TCP option
1254                         information (i.e., from TF_* symbols)
1255                         available.
1256
1257     HASTCPTPIQ          is defined when the dialect can duplicate
1258                         the receive and send queue sizes reported
1259                         by netstat.
1260
1261     HASTCPTPIW          is defined when the dialect can duplicate
1262                         the receive and send window sizes reported
1263                         by netstat.
1264
1265     HASTCPUDPSTATE      is defined when the dialect has support for
1266                         TCP and UDP state, including the "-s p:s"
1267                         option and associated speed ehancements.
1268
1269     HASTFS              indicates that the Pyramid dialect has TFS
1270                         file system support.
1271
1272     HAS_UFS1_2          indicates the FreeBSD 6 and higher system has
1273                         UFS1 and UFS2 members in its inode structure.
1274
1275     HAS_UM_UFS          indicates the OpenBSD version has UM_UFS[12]
1276                         definitions.
1277
1278     HASUNMINSOCK        indicates the Linux version has a user name
1279                         element in the socket structure; a value of
1280                         0 says there is no unix_address member; 1,
1281                         there is.
1282
1283     HASUINT16TYPE       is defined when the dialect has a typedef
1284                         for u_int16 that may conflict with some other
1285                         header file's redefinition (e.g., <afs/std.h>).
1286
1287     HASUTMPX            indicates the dialect has a <utmpx.h> header
1288                         file.
1289
1290     HAS_UVM_INCL        indicates the NetBSD or OpenBSD dialect has
1291                         a <uvm> include directory.
1292
1293     HAS_UW_CFS          indicates the UnixWare 7.1.1 or above dialect
1294                         has CFS file system support.
1295
1296     HAS_UW_NSC          indicates the UnixWare 7.1.1 or above dialect
1297                         has a NonStop Cluster (NSC) kernel.
1298
1299     HAS_V_LOCKF         indicates the FreeBSD version has a v_lockf
1300                         member in the vode structure, defined in
1301                         <sys/vnode.h>.
1302
1303     HAS_VM_MEMATTR_T    indicates the FreeBSD <sys/conf.h> uses the
1304                         vm_memattr_t typedef.
1305
1306     HASVMLOCKH          indicates the FreeBSD dialect has <vm/lock.h>.
1307
1308     HASVNODE            enables/disables readvnode() function in node.c.
1309
1310     HAS_V_PATH          indicates the dialect's vnode structure has a
1311                         v_path member.
1312
1313     HAS_VSOCK           indicates that the Solaris version has a VSOCK
1314                         member in the vtype enum
1315
1316     HASVXFS             enables Veritas VxFS file system support for
1317                         the dialect.  CAUTION, the dialect sources
1318                         must have the necessary support code.
1319
1320     HASVXFSDNLC         indicates the VxFS file system has its own
1321                         name cache.
1322
1323     HASVXFS_FS_H        indicates <sys/fs/vx_fs.h> exists.
1324
1325     HASVXFS_MACHDEP_H   indicates <sys/fs/vx_machdep.h> exists.
1326
1327     HASVXFS_OFF64_T     indicates <sys/fs/vx_solaris.h> exists and
1328                         has an off64_t typedef.
1329
1330     HASXVFSRNL          indicates the dialect has VxFS Reverse Name
1331                         Lookup (RNL) support.
1332
1333     HASVXFS_SOL_H       indicates <sys/fs/vx_sol.h> exists.
1334
1335     HASVXFS_SOLARIS_H   indicates <sys/fs/vx_solaris.h> exists.
1336
1337     HASVXFS_U64_T       if HASVXFS_SOLARIS_H is defined, this
1338                         variable indicates that <sys/fs/vx_solaris.h>
1339                         has a vx_u64_t typedef.
1340
1341     HASVXFSUTIL         indicates the Solaris dialect has VxFS 3.4
1342                         or higher and has the utility libraries,
1343                         libvxfsutil.a (32 bit) and libvxfsutil64.a
1344                         (64 bit).
1345
1346     HASVXFS_VX_INODE    indicates that <sys/fs/vx_inode.h> contains
1347                         a vx_inode structure.
1348
1349     HASWCTYPE_H         indicates the FreeBSD version has wide-character
1350                         support and the <wctype.h> header file.  Note:
1351                         the HASWIDECHAR #define will also be set.
1352
1353     HASWIDECHAR         indicates the dialect has the wide-character
1354                         support functions iswprint(), mblen() and mbtowc().
1355
1356     HASXNAMNODE         indicates the OSR dialect has <sys/fs/xnamnode.h>.
1357
1358     HASXOPT             defines help text for dialect-specific X option
1359                         and enables X option processing in usage.c and
1360                         main.c.
1361
1362     HASXOPT_ROOT        when defined, restricts the dialect-specific
1363                         X option to processes whose real user ID
1364                         is root.
1365
1366     HAS_ZFS             indicates the dialect has support for the ZFS file
1367                         system.
1368
1369     HASXOPT_VALUE       defines the default binary value for the X option
1370                         in store.c.
1371
1372     HASZONES            the Solaris dialect has zones.
1373
1374     HAVECLONEMAJ        defines the name of the status variable
1375                         that indicates a clone major device number
1376                         is available in CLONEMAJ.  (Also see CLONEMAJ
1377                         and HAS_STD_CLONE.)
1378
1379     HPUX_KERNBITS       defines the number of bits in the HP-UX 10.30
1380                         and above kernel "basic" word: 32 or 64.
1381
1382     KA_T                defines the type cast required to assign
1383                         space to kernel pointers.  When not defined
1384                         by a dialect header file, KA_T defaults to
1385                         unsigned long.
1386
1387     KA_T_FMT_X          defines the printf format for printing a
1388                         KA_T -- the default is "%#lx" for the
1389                         default unsigned long KA_T cast.
1390
1391     LSOF_ARCH           See 00XCONFIG.
1392
1393     LSOF_BLDCMT         See 00XCONFIG.
1394
1395     LSOF_CC             See 00XCONFIG.
1396
1397     LSOF_CCV            See 00XCONFIG.
1398
1399     LSOF_HOST           See 00XCONFIG.
1400
1401     LSOF_INCLUDE        See 00XCONFIG.
1402
1403     LSOF_LOGNAME        See 00XCONFIG.
1404
1405     LSOF_MKC            See the "The Mksrc Shell Script" section of
1406                         this file.
1407
1408     LSOF_SYSINFO        See 00XCONFIG.
1409
1410     LSOF_USER           See 00XCONFIG.
1411
1412     LSOF_VERS           See 00XCONFIG.
1413
1414     LSOF_VSTR           See 00XCONFIG.
1415
1416     MACH                defines a MACH system.
1417
1418     N_UNIXV             defines an alternate value for the N_UNIV symbol.
1419
1420     NCACHELDPFX         defines C code to be executed before calling
1421                         ncache_load().
1422
1423     NCACHELDSFX         defines C code to be executed after calling
1424                         ncache_load().
1425
1426     NEEDS_BOOLEAN_T     indicates the FreeBSD 9 and above system needs a
1427                         boolean_t definition for <sys/conf.h>.
1428
1429     NEEDS_MACH_PORT_T   is defined for Darwin versions that need the inclusion
1430                         of the header file <device/device_types.h>.
1431
1432     NEVER_HASDCACHE     keeps the Customize script from offering to
1433                         change HASDCACHE by its presence anywhere
1434                         in a dialect's machine.h header file --
1435                         e.g., in a comment.  See the Customize
1436                         script or machine.h in dialects/linux/proc.
1437
1438     NEVER_WARNDEVACCESS keeps the Customize script from offering to
1439                         change WARNDEVACCESS by its presence anywhere
1440                         in a dialect's machine.h header file --
1441                         including in a comment.  See the Customize
1442                         script or machine.h in dialects/linux/proc.
1443
1444     NLIST_TYPE          is the type of the nlist table, Nl[], if it is
1445                         not nlist.  HASNLIST must be set for this
1446                         definition to be effective.
1447
1448     NOWARNBLKDEV        specifies that no warning is to be issued
1449                         when no block devices are found.  This
1450                         definiton is used only when HASBLKDEV is
1451                         also defined.
1452
1453     OFFDECDIG           specifies how many decimal digits will be
1454                         printed for the file offset in a 0t form
1455                         before switching to a 0x form.  The count
1456                         includes the "0t".  A count of zero means
1457                         the size is unlimited.
1458
1459     PRIVFILETYPE        is the number of a private file type, found
1460                         in the f_type member of the file struct, to
1461                         be processed by the HASPRIVFILETYPE function.
1462                         See the AIX dialect sources for an example.
1463
1464     _PSTAT_STREAM_GET_XPORT
1465                         indicates the HP-UX PSTAT header files require
1466                         this symbol to be defined for proper handling of
1467                         stream export data.
1468
1469     SAVE_MP_IN_SFILE    indicates the dialect needs to have the mounts
1470                         structure pointer for a file system search argument
1471                         recorded in the dialect's sfile structure.  This
1472                         definition is made in the dialect's dlsof.h header
1473                         file within the sfile structure.
1474
1475     TIMEVAL_LSOF        defines the name of the timeval structure.
1476                         The default is timeval.  /dev/kmem-based
1477                         Linux lsof redefines timeval with this
1478                         symbol to avoid conflicts between glibc
1479                         and kernel definitions.
1480
1481     TYPELOGSECSHIFT     defines the type of the cdfs_LogSecShift
1482                         member of the cdfs structure for UnixWare
1483                         7 and higher.
1484
1485     UID_ARG_T           defines the cast on a User ID when passed
1486                         as a function argument.
1487
1488     USE_LIB_COMPLETEVFS
1489                         selects the use of the completevfs() function
1490                         in lsof4/lib/cvfs.c.
1491
1492     USE_LIB_FIND_CH_INO
1493                         selects the use of the find_ch_ino() inode
1494                         function in lsof4/lib/fino.c.
1495
1496                         Note: HASBLKDEV selects the has_bl_ino()
1497                         function.
1498
1499     USE_LIB_IS_FILE_NAMED
1500                         selects the use of the is_file_named() function
1501                         in lsof4/lib/isfn.c.
1502
1503     USE_LIB_LKUPDEV     selects the use of the lkupdev() function
1504                         in lsof4/lib/lkud.c.
1505
1506                         Note: HASBLKDEV selects the lkupbdev() function.
1507
1508     USE_LIB_PRINTDEVNAME
1509                         selects the use of the printdevname() function
1510                         in lsof4/lib/pdvn.c.
1511
1512                         Note: HASBLKDEV selects the printbdevname()
1513                         function.
1514
1515     USE_LIB_PRINT_TCPTPI
1516                         selects the use of the print_tcptpi() function
1517                         in lsof4/lib/ptti.c.
1518
1519     USE_LIB_PROCESS_FILE
1520                         selects the use of the process_file() function
1521                         in lsof4/lib/prfp.c.
1522
1523     USE_LIB_READDEV     selects the use of the readdev() and stkdir()
1524                         functions in lsof4/lib/rdev.c.
1525
1526     USE_LIB_READMNT     selects the use of the readmnt() function
1527                         in lsof4/lib/rmnt.c.
1528
1529     USE_LIB_RNAM        selects the use of the device cache functions
1530                         in lsof4/lib/rnam.c.
1531
1532                         Note: HASNCACHE must also be defined.
1533
1534     USE_LIB_RNCH        selects the use of the device cache functions
1535                         in lsof4/lib/rnch.c.
1536
1537                         Note: HASNCACHE must also be defined.
1538
1539     USE_STAT            is defined for those dialects that must
1540                         use the stat(2) function instead of lstat(2)
1541                         to scan /dev -- i.e., in the readdev()
1542                         function.
1543
1544     VNODE_VFLAG         is an alternate name for the vnode structure's
1545                         v_flag member.
1546
1547     WARNDEVACCESS       enables the issuing of a warning message when
1548                         lsof is unable to access /dev (or /device)
1549                         or one of its subdirectories, or stat(2)
1550                         a file in them. Some dialects (e.g., HP-UX)
1551                         have many inaccessible subdirectories and
1552                         it is appropriate to inhibit the warning
1553                         for them with WARNDEVACCESS.  The -w option
1554                         will also inhibit these warnings.
1555
1556     WARNINGSTATE        when defined, disables the default issuing
1557                         of warning messages.  WARNINGSTATE is
1558                         undefined by default for all dialects in
1559                         the lsof distribution.
1560
1561     WIDECHARINCL        defines the header file to be included (if any)
1562                         when wide-character support is enabled with
1563                         HASWIDECHAR.
1564
1565     zeromem()           defines a macro to zero memory -- e.g., using
1566                         bzero() or memset().
1567
1568 Any dialect's machine.h file and Configure stanza can serve as a
1569 template for building your own.  All machine.h files usually have
1570 all definitions, disabling some (with comment prefix and suffix)
1571 and enabling others.
1572
1573
1574 Options: Common and Special
1575 ---------------------------
1576
1577 All but one lsof option is common; the specific option is ``-X''.
1578 If a dialect does not support a common option, the related #define
1579 in machine.h -- e.g., HASCOPT -- should be deselected.
1580
1581 The specific option, ``-X'', may be used by any dialect for its
1582 own purpose.  Right now (May 30, 1995) the ``-X'' option is binary
1583 (i.e., it's not allowed arguments of its own, and its value must
1584 be 0 or 1) but that could be changed should the need arise.  The
1585 option is enabled with the HASXOPT definition in machine.h; its
1586 default value is defined by HASXOPT_VALUE.
1587
1588 The value of HASXOPT should be the text displayed for ``-X'' by
1589 the usage() function in usage.c.  HASXOPT_VALUE should be the
1590 default value, 0 or 1.
1591
1592 AIX for the IBM RICS System/6000 defines the ``-X'' option to
1593 control readx() usage, since there is a bug in AIX kernels that
1594 readx() can expose for other processes.
1595
1596
1597 Defining Dialect-Specific Symbols and Global Storage
1598 ----------------------------------------------------
1599
1600 A dialect's dlsof.h and dstore.c files contain dialect-specific
1601 symbol and global storage definitions.  There are symbol definitions,
1602 for example, for function and data casts, and for file paths.
1603 Dslof.h defines lookup names the nlist() table -- X_* symbols --
1604 when nlist() is being used.
1605
1606 Global storage definitions include such things as structures for
1607 local Virtual File System (vfs) information; mount information;
1608 search file information; and kernel memory file descriptors --
1609 e.g., Kmem for /dev/kmem, Mem for /dev/mem, Swap for /dev/drum.
1610
1611
1612 Coding Dialect-specific Functions
1613 ---------------------------------
1614
1615 Each supported dialect must have some basic functions that the
1616 common functions of the top level may call.  Some of them may be
1617 obtained from the library in lsof4/lib, selected and customized by
1618 #define's in the dialect machine.h header file.  Others may have
1619 to be coded specifically for the dialect.
1620
1621 Each supported dialect usually has private functions, too.  Those
1622 are wholly determined by the needs of the dialect's data organization
1623 and access.
1624
1625 These are some of the basic functions that each dialect must supply
1626 -- they're all defined in proto.h:
1627
1628     initialize()                function to initialize the dialect
1629
1630     is_file_named()             function to check if a file was named
1631                                 by an optional file name argument
1632                                 (lsof4/lib/isfn.c)
1633
1634     gather_proc_info()          function to gather process table
1635                                 and related information and cache it
1636
1637     printchdevname()            function to locate and optionally
1638                                 print the name of a character device
1639                                 (lsof4/lib/pdvn.c)
1640
1641     print_tcptpistate()         function to print the TCP or TPI
1642                                 state for a TCP or UDP socket file,
1643                                 if the one in lib/ptti.c isn't
1644                                 suitable (define USE_LIB_PRINT_TCPTPI
1645                                 to activate lib/ptti.c)
1646
1647     process_file()              function to process an open file
1648                                 structure (lsof4/lib/prfp.c)
1649
1650     process_node()              function to process a primary node
1651
1652     process_socket()            function to process a socket
1653
1654     readdev() and stkdir()      functions to read and cache device
1655                                 information (lsof4/lib/rdev.c)
1656
1657     readmnt()                   function to read mount table information
1658                                 (lsof4/lib/rmnt.c)
1659
1660 Other common functions may be needed, and might be obtained from
1661 lsof4/lib, depending on the needs of the dialect's node and socket
1662 file processing functions.
1663
1664 Check the functions in lsof4/lib and specific lsof4/dialects/*
1665 files for examples.
1666
1667 As you build these functions you will probably have to add #include's
1668 to dlsof.h.
1669
1670
1671 Function Prototype Definitions and the _PROTOTYPE Macro
1672 -------------------------------------------------------
1673
1674 Once you've defined your dialect-specific definitions, you should
1675 define their prototypes in dproto.h or locally in the file where
1676 they occur and are used.  Do this even if your compiler is not ANSI
1677 compliant -- the _PROTOTYPE macro knows how to cope with that and
1678 will avoid creating prototypes that will confuse your compiler.
1679
1680
1681 The Makefile
1682 ------------
1683
1684 Here are some general rules for constructing the dialect Makefile.
1685
1686     *  Use an existing dialect's Makefile as a template.
1687
1688     *  Make sure the echo actions of the install rule are appropriate.
1689
1690     *  Use the DEBUG string to set debugging options, like ``-g''.
1691        You may also need to use the -O option when forking and
1692        SIGCHLD signals defeat your debugger.
1693
1694     *  Don't put ``\"'' in a compiler flags -D<symbol>=<string>
1695        clause in your Makefile.  Leave off the ``\"'' even though
1696        you want <string> to be a string literal and instead adapt
1697        the N_UNIX* macros you'll find in Makefiles for FreeBSD
1698        and Linux.  That will allow the Makefile's version.h rule
1699        to put CFLAGS into version.h without having to worry about
1700        the ``\"'' sequences.
1701
1702     *  Finally, remember that strings can be passed from the top
1703        level's Configure shell script.  That's an appropriate way
1704        to handle options, especially if there are multiple versions
1705        of the Unix dialect to which you are porting lsof 4.
1706
1707
1708 The Mksrc Shell Script
1709 ----------------------
1710
1711 Pattern your Mksrc shell script after an existing one from another
1712 dialect.  Change the D shell variable to the name of your dialect's
1713 subdirectory in lsof4/dialects.  Adjust any other shell variable
1714 to your local conditions.  (Probably that won't be necessary.)
1715
1716 Note that, if using symbolic links from the top level to your
1717 dialect subdirectory is impossible or impractical, you can set the
1718 LSOF_MKC shell variable in Configure to something other than
1719 "ln -s" -- e.g., "cp," and Configure will pass it to the Mksrc
1720 shell script in the M environment variable.
1721
1722
1723 The MkKernOpts Shell Script
1724 ---------------------------
1725
1726 The MkKernOptrs shell script is used by some dialects -- e.g.,
1727 Pyramid DC/OSx and Reliant UNIX -- to determine the compile-time
1728 options used to build the current kernel that affect kernel structure
1729 definitions, so those same options can be used to build lsof.
1730 Configure calls MkKernOpts for the selected dialects.
1731
1732 If your kernel is built with options that affect structure definitions.
1733 -- most commonly affected are the proc structure from <sys/proc.h>
1734 and the user structure from <sys/user.h> -- check the MkKernOpts
1735 in lsof4/dialects/irix for a comprehensive example.
1736
1737
1738 Testing and the Lsof Test Suite
1739 -------------------------------
1740
1741 Once you have managed to create a port, here are some tips for
1742 testing it.
1743
1744 *  First look at the test suite in the tests/ sub-directory of the
1745    lsof distribution.  While it will need to be customized to be
1746    usable with a new port, it should provide ideas on things to
1747    test.  Look for more information about the test suite in the
1748    00TEST file.
1749
1750 *  Pick a simple process whose open files you are likely to
1751    know and see if the lsof output agrees with what you know.
1752    (Hint: select the process with `lsof -p <process_PID>`.)
1753
1754    Are the device numbers and device names correct?
1755
1756    Are the file system names and mount points correct?
1757
1758    Are inode numbers and sizes correct?
1759
1760    Are command names, file descriptor numbers, UIDs, PIDs, PGIDs,
1761    and PPIDs correct?
1762
1763    A simple tool that does a stat(2) of the files being examined
1764    and reports the stat struct contents can provide a reference for
1765    some values; so can `ls -l /dev/<device>`.
1766
1767 *  Let lsof list information about all open files and ask the
1768    same questions.  Look also for error messages about not being
1769    able to read a node or structure.
1770
1771 *  Pick a file that you know is open -- open it and hold it
1772    that way with a C program (not vi), if you must.  Ask lsof to
1773    find the file's open instance by specifying its path to lsof.
1774
1775 *  Create a C program that opens a large number of files and holds
1776    them open.  Background the test process and ask lsof to list
1777    its files.
1778
1779 *  Generate some locks -- you may need to write a C program to
1780    do this, hold the locked file open, and see if lsof can identify
1781    the lock properly.  You may need to write several C programs
1782    if your dialect supports different lock functions -- fnctl(),
1783    flock(), lockf(), locking().
1784
1785 *  Identify a process with known Internet file usage -- inetd
1786    is a good one -- and ask lsof to list its open files.  See if
1787    protocols and service names are listed properly.
1788
1789    See if your lsof identifies Internet socket files properly for
1790    rlogind or telnetd processes.
1791
1792 *  Create a UNIX domain socket file, if your dialect allows it,
1793    hold it open by backgrounding the process, and see if lsof can
1794    identify the open UNIX domain socket file properly.
1795
1796 *  Create a FIFO file and see what lsof says about it.
1797
1798 *  Watch an open pipe -- `lsof -u <your_login>  | less` is a
1799    good way to do this.
1800
1801 *  See if lsof can identify NFS files and their devices properly.
1802    Open and hold open an NFS file and see if lsof can find the open
1803    instance by path.
1804
1805 *  If your test system has CD-ROM and floppy disk devices, open
1806    files on them and see if lsof reports their information correctly.
1807    Such devices often have special kernel structures associated
1808    with them and need special attention from lsof for their
1809    identification.  Pay particular attention to the inode numbers
1810    lsof reports for CD-ROM and floppy disk files -- often they are
1811    calculated dynamically, rather than stored in a kernel node
1812    structure.
1813
1814 *  If your implementation can probe the kernel name cache, look
1815    at some processes with open files whose paths you know to see
1816    if lsof identifies any name components.  If it doesn't, make
1817    sure the name components are in the name cache by accessing
1818    the files yourself with ls or a similar tool.
1819
1820 *  If your dialect supports the /proc file system, use a C program
1821    to open files there, background a test process, and ask lsof to
1822    report its open files.
1823
1824 *  If your dialect supports fattach(), create a small test program
1825    to use it, background a test process, and ask lsof to report
1826    its open files.
1827
1828 I can supply some quick-and-dirty tools for reporting stat buffer
1829 contents, holding files open, creating UNIX domain files, creating
1830 FIFOs, etc., if you need them.
1831
1832
1833 Where Next?
1834 -----------
1835
1836 Is this document complete?  Certainly not!  One might wish that it
1837 were accompanied by man pages for all lsof functions, by free beer
1838 or chocolates, by ...  (You get the idea.)
1839
1840 But those things are not likely to happen as long as lsof is a
1841 privately supported, one man operation.
1842
1843 So, if you need more information on how lsof is constructed or
1844 works in order to do a port of your own, you'll have to read the
1845 lsof source code.  You can also ask me questions via email, but
1846 keep in mind the private, one-man nature of current lsof support.
1847
1848
1849 Vic Abell <abe@purdue.edu>
1850 October 13, 2014