Annotation of mandoc/mandocd.8, Revision 1.5
1.5 ! schwarze 1: .\" $Id: mandocd.8,v 1.4 2025/06/30 11:24:30 schwarze Exp $
1.1 schwarze 2: .\"
1.4 schwarze 3: .\" Copyright (c) 2017, 2025 Ingo Schwarze <schwarze@openbsd.org>
1.1 schwarze 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.5 ! schwarze 17: .Dd $Mdocdate: June 30 2025 $
1.1 schwarze 18: .Dt MANDOCD 8
19: .Os
20: .Sh NAME
21: .Nm mandocd
22: .Nd server process to format manual pages in batch mode
23: .Sh SYNOPSIS
24: .Nm mandocd
25: .Op Fl I Cm os Ns = Ns Ar name
26: .Op Fl T Ar output
27: .Ar socket_fd
28: .Sh DESCRIPTION
29: The
30: .Nm
31: utility formats many manual pages without requiring
32: .Xr fork 2
33: and
34: .Xr exec 3
35: overhead in between.
36: It does not require listing all the manuals to be formatted on the
37: command line, and it supports writing each formatted manual to its
38: own file descriptor.
39: .Pp
40: This server requires that a connected UNIX domain
41: .Xr socket 2
42: is already present at
43: .Xr exec 3
44: time.
45: Consequently, it cannot be started from the
46: .Xr sh 1
47: command line because the shell cannot supply such a socket.
48: Typically, the socket is created by the parent process using
49: .Xr socketpair 2
50: before calling
51: .Xr fork 2
52: and
53: .Xr exec 3
54: on
55: .Nm .
56: The parent process will pass the file descriptor number as an argument to
57: .Xr exec 3 ,
58: formatted as a decimal ASCII-encoded integer.
59: See
60: .Xr catman 8
61: for a typical implementation of a parent process.
62: .Pp
63: .Nm
64: loops reading one-byte messages with
65: .Xr recvmsg 2
66: from the file descriptor number
67: .Ar socket_fd .
68: It ignores the byte read and only uses the out-of-band auxiliary
69: .Vt struct cmsghdr
70: control data, typically supplied by the calling process using
71: .Xr CMSG_FIRSTHDR 3 .
72: The parent process is expected to pass three file descriptors
73: with each dummy byte.
74: The first one is used for
75: .Xr mdoc 7
76: or
77: .Xr man 7
78: input, the second one for formatted output, and the third one
79: for error output.
80: .Pp
1.5 ! schwarze 81: After accepting each message,
1.4 schwarze 82: .Nm
83: replies with a one-byte message of its own,
84: such that the parent process can keep track of how many messages
85: .Nm
86: has already accepted and how many file descriptors
87: consequently are still in flight, such that the parent process
88: can limit the number of file descriptors in flight at any given time
89: in order to prevent
90: .Er EMFILE
91: failure of
92: .Xr sendmsg 2 .
93: .Pp
1.1 schwarze 94: The options are as follows:
95: .Bl -tag -width Ds
96: .It Fl I Cm os Ns = Ns Ar name
97: Override the default operating system
98: .Ar name
99: for the
100: .Xr mdoc 7
1.2 schwarze 101: .Ic \&Os
1.1 schwarze 102: and for the
103: .Xr man 7
104: .Ic TH
105: macro.
106: .It Fl T Ar output
107: Output format.
108: The
109: .Ar output
110: argument can be
111: .Cm ascii ,
112: .Cm utf8 ,
113: or
114: .Cm html ;
115: see
116: .Xr mandoc 1 .
117: In
118: .Cm html
119: output mode, the
120: .Cm fragment
121: output option is implied.
122: Other output options are not supported.
123: .El
124: .Pp
125: After exhausting one input file descriptor, all three file descriptors
126: are closed before reading the next dummy byte and control message.
127: .Pp
1.4 schwarze 128: When a zero-byte message or a misformatted message is read, when the
1.1 schwarze 129: .Ar socket_fd
130: is closed by the parent process,
131: or when an error occurs,
132: .Nm
133: exits.
134: .Sh EXIT STATUS
135: .Ex -std
136: .Pp
137: A zero-byte message or a closed
138: .Ar socket_fd
139: is considered success.
140: Possible errors include:
141: .Bl -bullet
142: .It
143: missing, invalid, or excessive
144: .Xr exec 3
145: arguments
146: .It
1.5 ! schwarze 147: communication failure with the parent, for example failure in
1.1 schwarze 148: .Xr recvmsg 2
1.5 ! schwarze 149: or
! 150: .Xr send 2
1.1 schwarze 151: .It
152: missing or unexpected control data, in particular a
153: .Fa cmsg_level
154: in the
155: .Vt struct cmsghdr
156: that differs from
157: .Dv SOL_SOCKET ,
158: a
159: .Fa cmsg_type
160: that differs from
161: .Dv SCM_RIGHTS ,
162: or a
163: .Fa cmsg_len
164: that is not three times the size of an
165: .Vt int
166: .It
167: invalid file descriptors passed in the
168: .Xr CMSG_DATA 3
169: .It
170: resource exhaustion, in particular
171: .Xr dup 2
172: or
173: .Xr malloc 3
174: failure
175: .El
176: .Pp
177: Except for memory exhaustion and similar system-level failures,
178: parsing and formatting errors do not cause
179: .Nm
180: to return an error exit status.
181: Even after severe parsing errors,
182: .Nm
183: will simply accept and process the next input file descriptor.
184: .Sh SEE ALSO
185: .Xr mandoc 1 ,
186: .Xr mandoc 3 ,
187: .Xr catman 8
188: .Sh HISTORY
189: The
190: .Nm
1.3 schwarze 191: utility appeared in version 1.14.1 of the
1.1 schwarze 192: .Sy mandoc
193: toolkit.
194: .Sh AUTHORS
195: .An -nosplit
196: The concept was designed and implemented by
197: .An Michael Stapelberg Aq Mt stapelberg@debian.org .
198: The
199: .Xr mandoc 3
200: glue needed to make it a stand-alone process was added by
201: .An Ingo Schwarze Aq Mt schwarze@openbsd.org .
202: .Sh CAVEATS
203: If the parsed manual pages contain
204: .Xr roff 7
205: .Pf . Ic so
206: requests,
207: .Nm
208: needs to be started with the current working directory set to the
209: root of the manual page tree.
210: Avoid starting it in directories that contain secret files in any
1.3 schwarze 211: subdirectories, in particular if the user starting it has read
1.1 schwarze 212: access to these secret files.
CVSweb