Annotation of mandoc/catman.8, Revision 1.15
1.15 ! schwarze 1: .\" $Id: catman.8,v 1.14 2025/06/30 12:28:12 schwarze Exp $
1.1 kristaps 2: .\"
1.11 schwarze 3: .\" Copyright (c) 2017, 2025 Ingo Schwarze <schwarze@openbsd.org>
1.1 kristaps 4: .\"
5: .\" Permission to use, copy, modify, and distribute this software for any
6: .\" purpose with or without fee is hereby granted, provided that the above
7: .\" copyright notice and this permission notice appear in all copies.
8: .\"
9: .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: .\"
1.13 schwarze 17: .Dd $Mdocdate: June 30 2025 $
1.1 kristaps 18: .Dt CATMAN 8
19: .Os
20: .Sh NAME
21: .Nm catman
1.7 schwarze 22: .Nd format all manual pages below a directory
1.1 kristaps 23: .Sh SYNOPSIS
24: .Nm catman
1.7 schwarze 25: .Op Fl I Cm os Ns = Ns Ar name
26: .Op Fl T Ar output
27: .Ar srcdir dstdir
1.1 kristaps 28: .Sh DESCRIPTION
29: The
30: .Nm
1.7 schwarze 31: utility assumes that all files below
32: .Ar srcdir
33: are manual pages in
34: .Xr mdoc 7
35: and
36: .Xr man 7
37: format and formats all of them, storing the formatted versions in
38: the same relative paths below
39: .Ar dstdir .
1.15 ! schwarze 40: Unless they already exist,
1.7 schwarze 41: .Ar dstdir
1.15 ! schwarze 42: itself and any required subdirectories are created.
1.7 schwarze 43: Existing files are not explicitly deleted, but possibly overwritten.
1.5 kristaps 44: .Pp
1.7 schwarze 45: The options are as follows:
46: .Bl -tag -width Ds
47: .It Fl I Cm os Ns = Ns Ar name
48: Override the default operating system
49: .Ar name
50: for the
51: .Xr mdoc 7
1.8 schwarze 52: .Ic \&Os
1.7 schwarze 53: and for the
54: .Xr man 7
55: .Ic TH
56: macro.
57: .It Fl T Ar output
58: Output format.
59: The
60: .Ar output
61: argument can be
62: .Cm ascii ,
63: .Cm utf8 ,
64: or
65: .Cm html ;
66: see
67: .Xr mandoc 1 .
68: In
69: .Cm html
70: output mode, the
71: .Cm fragment
72: output option is implied.
73: Other output options are not supported.
1.11 schwarze 74: .It Fl v
1.13 schwarze 75: Verbose mode, printing additional information to standard error output.
76: Specifying this once prints a summary about the number of files
77: and directories processed at the end of the iteration.
78: Specifying it twice additionally prints debugging information
79: about the backchannel from
80: .Xr mandocd 8
81: to
82: .Nm
83: that is used to limit the number of files in flight at any given time.
84: For details, see
1.11 schwarze 85: .Sx DIAGNOSTICS .
1.7 schwarze 86: .El
87: .Sh IMPLEMENTATION NOTES
88: Since this version avoids
89: .Xr fork 2
90: and
91: .Xr exec 3
92: overhead and uses the much faster
93: .Sy mandoc
94: parsers and formatters rather than
95: .Sy groff ,
96: it may be about one order of magnitude faster than other
1.5 kristaps 97: .Nm
1.7 schwarze 98: implementations.
99: .Sh EXIT STATUS
100: .Ex -std
1.5 kristaps 101: .Pp
1.9 schwarze 102: Failures while trying to open individual manual pages for reading,
103: to save individual formatted files to the file system,
104: or even to read or create subdirectories do not cause
105: .Nm
106: to return an error exit status.
107: In such cases,
108: .Nm
109: simply continues with the next file or subdirectory.
110: .Sh DIAGNOSTICS
111: Some fatal errors cause
112: .Nm
113: to exit before the iteration over input files is even started:
114: .Bl -tag -width Ds -offset indent
115: .It unknown option \-\- Ar option
116: An invalid option was passed on the command line.
1.10 schwarze 117: .It missing arguments: srcdir and dstdir
118: No argument was provided.
119: Both
120: .Ar srcdir
121: and
122: .Ar dstdir
123: are mandatory.
124: .It missing argument: dstdir
125: Only one argument was provided.
126: The second argument,
127: .Ar dstdir ,
128: is mandatory, too.
129: .It too many arguments: Ar third argument
130: Three or more arguments were provided, but only two are supported.
1.9 schwarze 131: .It Sy socketpair : Ar reason
132: The sockets needed for communication with
133: .Xr mandocd 8
134: could not be created, for example due to file descriptor or memory exhaustion.
135: .It Sy fork : Ar reason
136: The new process needed to run
137: .Xr mandocd 8
138: could not be created, for example due to process table exhaustion
139: or system resource limits.
140: .It Sy exec Ns Po Sy mandocd Pc : Ar reason
141: The
142: .Xr mandocd 8
143: child program could not be started, for example because it is not in the
144: .Ev PATH
145: or has no execute permission.
1.15 ! schwarze 146: .It Sy mkdir No destination Ar dstdir : reason
! 147: The
! 148: .Ar dstdir
! 149: does not exist and could not be created, for example because
! 150: the parent directory does not exist or permission is denied.
1.9 schwarze 151: .It Sy open No destination Ar dstdir : reason
152: The
153: .Ar dstdir
1.15 ! schwarze 154: could not be opened for reading, for example because
! 155: it is not a directory or permission is denied.
1.9 schwarze 156: .It Sy chdir No to source Ar srcdir : reason
157: The current working directory could not be changed to
158: .Ar srcdir ,
159: for example because it does not exist, it is not a directory,
160: or permission is denied.
161: .It Sy fts_open : Ar reason
1.14 schwarze 162: Starting the iteration was attempted but failed,
163: for example due to memory exhaustion.
1.9 schwarze 164: .El
165: .Pp
166: Some fatal errors cause the iteration over input files to be aborted
167: prematurely:
168: .Bl -tag -width Ds -offset indent
169: .It FATAL: Sy fts_read : Ar reason
170: A call to
171: .Xr fts_read 3
172: returned
173: .Dv NULL ,
174: meaning that the iteration failed before being complete.
1.12 schwarze 175: .It FATAL: mandocd child died: got Ar SIGNAME
176: This message appears if
177: .Nm
178: gets the
179: .Dv SIGCHLD
180: or
181: .Dv SIGPIPE
182: signal, most likely due to a fatal bug in
183: .Xr mandocd 8 .
1.9 schwarze 184: .It FATAL: Sy sendmsg : Ar reason
185: The file descriptors needed to process one of the manual pages
186: could not be sent to
187: .Xr mandocd 8 ,
188: for example because
189: .Xr mandocd 8
190: could not be started or died unexpectedly.
1.14 schwarze 191: .It FATAL: Sy recv : Ar reason
192: Trying to read a reply message from
193: .Xr mandocd 8
194: failed, most likely because
195: .Xr mandocd 8
196: unexpectedly died or closed the socket.
1.12 schwarze 197: .It FATAL: signal Ar SIGNAME
198: This message appears if
199: .Nm
200: gets a
201: .Dv SIGHUP ,
202: .Dv SIGINT ,
203: or
204: .Dv SIGTERM
205: signal, for example because the user deliberately killed it.
1.9 schwarze 206: .El
207: .Pp
208: Some non-fatal errors cause a single subdirectory to be skipped.
209: The iteration is not aborted but continues with the next subdirectory,
210: and the exit status is unaffected:
211: .Bl -tag -width Ds -offset indent
212: .It directory Ar subdirectory No unreadable : Ar reason
213: A directory below
214: .Ar srcdir
215: could not be read and is skipped.
216: .It directory Ar subdirectory No causes cycle
217: A directory below
218: .Ar srcdir
219: is skipped because it would cause cyclic processing.
220: .It Sy mkdirat Ar subdirectory : reason
221: A required directory below
222: .Ar dstdir
223: does not exist and could not be created.
224: The corresponding subdirectory below
225: .Ar srcdir
226: is skipped.
227: .El
228: .Pp
229: Some non-fatal errors cause a single source file to be skipped.
230: The iteration is not aborted but continues with the next file,
231: and the exit status is unaffected:
232: .Bl -tag -width Ds -offset indent
233: .It file Ar filename : reason
234: The function
235: .Xr fts_read 3
236: reported a non-fatal error with respect to
237: .Ar filename .
1.10 schwarze 238: .It file Ar filename : No not a regular file
1.9 schwarze 239: For example, it might be a symbolic link or a device file.
240: .It Sy open Ar filename No for reading : Ar reason
241: A file below
1.7 schwarze 242: .Ar srcdir
1.9 schwarze 243: could not be read, for example due to permission problems.
244: .It Sy openat Ar filename No for writing : Ar reason
245: A file below
1.7 schwarze 246: .Ar dstdir
1.9 schwarze 247: could not be created or truncated, for example due to permission problems.
1.1 kristaps 248: .El
249: .Pp
1.9 schwarze 250: If errors occur, the applicable summary messages appear
251: after the end of the iteration:
252: .Pp
253: .Bl -tag -width Ds -offset indent -compact
254: .It skipped Ar number No directories due to errors
255: .It skipped Ar number No files due to errors
256: .It processing aborted due to fatal error
1.11 schwarze 257: .El
258: .Pp
259: If the
260: .Fl v
261: flag is specified, the following summary message also appears:
1.13 schwarze 262: .Bl -tag -width Ds -offset indent
1.11 schwarze 263: .It processed Ar nfiles No files in Ar ndirs No directories
264: A file is counted if it could be opened for reading and the
265: corresponding output file could be opened for writing;
266: this does not necessarily mean that it is a useful manual page.
267: A directory is counted if it could be opened for reading and the
268: corresponding output directory existed or could be created;
269: this does not necessarily mean that any files could be
270: processed inside.
1.13 schwarze 271: .El
272: .Pp
273: If the
274: .Fl v
275: flag is specified twice, the following messages also appear:
276: .Bl -tag -width Ds -offset indent
277: .It allowing up to Ar number No files in flight
278: This is printed at the beginning of the iteration,
279: showing the maximum number of files that
280: .Nm
281: allows to be in flight at any given time.
282: .It files in flight: Ar old No \- Ar decrement No = Ar new
283: This message is printed when
284: .Nm
285: learns about
286: .Xr mandocd 8
287: accepting more than one file at the same time.
288: The three numbers printed are the old number of files in flight,
289: the amount this number is being reduced, and the resulting
290: new number of files in flight.
291: .It waiting for Ar number No files in flight
292: This message is printed at the end of the iteration, after
293: .Nm
294: has submitted all files to
295: .Xr mandocd 8
296: that it intends to.
297: THe message informs about the number of files still in flight
298: at this point.
299: The
300: .Nm
301: program then waits until
302: .Xr mandocd 8
303: has accepted them all or until an error occurs.
1.9 schwarze 304: .El
1.1 kristaps 305: .Sh SEE ALSO
306: .Xr mandoc 1 ,
1.7 schwarze 307: .Xr mandocd 8
308: .Sh HISTORY
309: A
310: .Nm
311: utility first appeared in
312: .Fx 1.0 .
313: Other, incompatible implementations appeared in
314: .Nx 1.0
315: and in
316: .Sy man-db No 2.2 .
317: .Pp
318: This version appeared in version 1.14.1 of the
319: .Sy mandoc
320: toolkit.
1.1 kristaps 321: .Sh AUTHORS
1.7 schwarze 322: .An -nosplit
323: The first
324: .Nm
325: implementation was a short shell script by
326: .An Christoph Robitschko
327: in July 1993.
328: .Pp
1.1 kristaps 329: The
1.7 schwarze 330: .Nx
331: implementations were written by
332: .An J. T. Conklin Aq Mt jtc@netbsd.org
333: in 1993,
334: .An Christian E. Hopps Aq Mt chopps@netbsd.org
335: in 1994,
336: and
337: .An Dante Profeta Aq Mt dante@netbsd.org
338: in 1999; the
339: .Sy man-db
340: implementation by
341: .An Graeme W. Wilford
342: in 1994; and the
343: .Fx
344: implementations by
345: .An Wolfram Schneider Aq Mt wosch@freebsd.org
346: in 1995 and
347: .An John Rochester Aq Mt john@jrochester.org
348: in 2002.
349: .Pp
350: The concept of the present version was designed and implemented by
351: .An Michael Stapelberg Aq Mt stapelberg@debian.org
352: in 2017.
353: Option and argument handling and directory iteration was added by
354: .An Ingo Schwarze Aq Mt schwarze@openbsd.org .
355: .Sh CAVEATS
356: All versions of
357: .Nm
358: are incompatible with each other because each caters to the needs
359: of a specific operating system, for example regarding directory
360: structures and file naming conventions.
361: .Pp
362: This version is more flexible than the others in so far as it does
363: not assume any particular directory structure or naming convention.
364: That flexibility comes at the price of not being able to change the
365: names and relative paths of the source files when reusing them to
366: store the formatted files, of not supporting any configuration file
367: formats or environment variables, and of being unable to scan for
368: and remove junk files in
369: .Ar dstdir .
370: .Pp
371: Currently,
1.1 kristaps 372: .Nm
1.7 schwarze 373: always reformats each page, even if the formatted version is newer
374: than the source version.
CVSweb