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