]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libopenbsd/imsg_init.3
zfs: merge openzfs/zfs@86e115e21
[FreeBSD/FreeBSD.git] / lib / libopenbsd / imsg_init.3
1 .\" $OpenBSD: imsg_init.3,v 1.13 2015/07/11 16:23:59 deraadt Exp $
2 .\"
3 .\" Copyright (c) 2010 Nicholas Marriott <nicm@openbsd.org>
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 MIND, USE, DATA OR PROFITS, WHETHER
14 .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
15 .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 .\"
17 .Dd $Mdocdate: July 11 2015 $
18 .Dt IMSG_INIT 3
19 .Os
20 .Sh NAME
21 .Nm imsg_init ,
22 .Nm imsg_read ,
23 .Nm imsg_get ,
24 .Nm imsg_compose ,
25 .Nm imsg_composev ,
26 .Nm imsg_create ,
27 .Nm imsg_add ,
28 .Nm imsg_close ,
29 .Nm imsg_free ,
30 .Nm imsg_flush ,
31 .Nm imsg_clear ,
32 .Nm ibuf_open ,
33 .Nm ibuf_dynamic ,
34 .Nm ibuf_add ,
35 .Nm ibuf_reserve ,
36 .Nm ibuf_seek ,
37 .Nm ibuf_size ,
38 .Nm ibuf_left ,
39 .Nm ibuf_close ,
40 .Nm ibuf_write ,
41 .Nm ibuf_free ,
42 .Nm msgbuf_init ,
43 .Nm msgbuf_clear ,
44 .Nm msgbuf_write ,
45 .Nm msgbuf_drain
46 .Nd IPC messaging functions
47 .Sh SYNOPSIS
48 .In sys/types.h
49 .In sys/queue.h
50 .In sys/uio.h
51 .In imsg.h
52 .Ft void
53 .Fn imsg_init "struct imsgbuf *ibuf" "int fd"
54 .Ft ssize_t
55 .Fn imsg_read "struct imsgbuf *ibuf"
56 .Ft ssize_t
57 .Fn imsg_get "struct imsgbuf *ibuf" "struct imsg *imsg"
58 .Ft int
59 .Fn imsg_compose "struct imsgbuf *ibuf" "u_int32_t type" "uint32_t peerid" \
60     "pid_t pid" "int fd" "const void *data" "u_int16_t datalen"
61 .Ft int
62 .Fn imsg_composev "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \
63     "pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt"
64 .Ft "struct ibuf *"
65 .Fn imsg_create "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \
66     "pid_t pid" "u_int16_t datalen"
67 .Ft int
68 .Fn imsg_add "struct ibuf *buf" "const void *data" "u_int16_t datalen"
69 .Ft void
70 .Fn imsg_close "struct imsgbuf *ibuf" "struct ibuf *msg"
71 .Ft void
72 .Fn imsg_free "struct imsg *imsg"
73 .Ft int
74 .Fn imsg_flush "struct imsgbuf *ibuf"
75 .Ft void
76 .Fn imsg_clear "struct imsgbuf *ibuf"
77 .Ft "struct ibuf *"
78 .Fn ibuf_open "size_t len"
79 .Ft "struct ibuf *"
80 .Fn ibuf_dynamic "size_t len" "size_t max"
81 .Ft int
82 .Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len"
83 .Ft "void *"
84 .Fn ibuf_reserve "struct ibuf *buf" "size_t len"
85 .Ft "void *"
86 .Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len"
87 .Ft size_t
88 .Fn ibuf_size "struct ibuf *buf"
89 .Ft size_t
90 .Fn ibuf_left "struct ibuf *buf"
91 .Ft void
92 .Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf"
93 .Ft int
94 .Fn ibuf_write "struct msgbuf *msgbuf"
95 .Ft void
96 .Fn ibuf_free "struct ibuf *buf"
97 .Ft void
98 .Fn msgbuf_init "struct msgbuf *msgbuf"
99 .Ft void
100 .Fn msgbuf_clear "struct msgbuf *msgbuf"
101 .Ft int
102 .Fn msgbuf_write "struct msgbuf *msgbuf"
103 .Ft void
104 .Fn msgbuf_drain "struct msgbuf *msgbuf" "size_t n"
105 .Sh DESCRIPTION
106 The
107 .Nm imsg
108 functions provide a simple mechanism for communication between processes
109 using sockets.
110 Each transmitted message is guaranteed to be presented to the receiving program
111 whole.
112 They are commonly used in privilege separated processes, where processes with
113 different rights are required to cooperate.
114 .Pp
115 A program using these functions should be linked with
116 .Em -lutil .
117 .Pp
118 The basic
119 .Nm
120 structure is the
121 .Em imsgbuf ,
122 which wraps a file descriptor and represents one side of a channel on which
123 messages are sent and received:
124 .Bd -literal -offset indent
125 struct imsgbuf {
126         TAILQ_HEAD(, imsg_fd)   fds;
127         struct ibuf_read        r;
128         struct msgbuf           w;
129         int                     fd;
130         pid_t                   pid;
131 };
132 .Ed
133 .Pp
134 .Fn imsg_init
135 is a routine which initializes
136 .Fa ibuf
137 as one side of a channel associated with
138 .Fa fd .
139 The file descriptor is used to send and receive messages,
140 but is not closed by any of the imsg functions.
141 An imsgbuf is initialized with the
142 .Em w
143 member as the output buffer queue,
144 .Em fd
145 with the file descriptor passed to
146 .Fn imsg_init
147 and the other members for internal use only.
148 .Pp
149 The
150 .Fn imsg_clear
151 function frees any data allocated as part of an imsgbuf.
152 .Pp
153 .Fn imsg_create ,
154 .Fn imsg_add
155 and
156 .Fn imsg_close
157 are generic construction routines for messages that are to be sent using an
158 imsgbuf.
159 .Pp
160 .Fn imsg_create
161 creates a new message with header specified by
162 .Fa type ,
163 .Fa peerid
164 and
165 .Fa pid .
166 A
167 .Fa pid
168 of zero uses the process ID returned by
169 .Xr getpid 2
170 when
171 .Fa ibuf
172 was initialized.
173 In addition to this common imsg header,
174 .Fa datalen
175 bytes of space may be reserved for attaching to this imsg.
176 This space is populated using
177 .Fn imsg_add .
178 Additionally, the file descriptor
179 .Fa fd
180 may be passed over the socket to the other process.
181 If
182 .Fa fd
183 is given, it is closed in the sending program after the message is sent.
184 A value of \-1 indicates no file descriptor should be passed.
185 .Fn imsg_create
186 returns a pointer to a new message if it succeeds, NULL otherwise.
187 .Pp
188 .Fn imsg_add
189 appends to
190 .Fa imsg
191 .Fa len
192 bytes of ancillary data pointed to by
193 .Fa buf .
194 It returns
195 .Fa len
196 if it succeeds, \-1 otherwise.
197 .Pp
198 .Fn imsg_close
199 completes creation of
200 .Fa imsg
201 by adding it to
202 .Fa imsgbuf
203 output buffer.
204 .Pp
205 .Fn imsg_compose
206 is a routine which is used to quickly create and queue an imsg.
207 It takes the same parameters as the
208 .Fn imsg_create ,
209 .Fn imsg_add
210 and
211 .Fn imsg_close
212 routines,
213 except that only one ancillary data buffer can be provided.
214 This routine returns 1 if it succeeds, \-1 otherwise.
215 .Pp
216 .Fn imsg_composev
217 is similar to
218 .Fn imsg_compose .
219 It takes the same parameters, except that the ancillary data buffer is specified
220 by
221 .Fa iovec .
222 .Pp
223 .Fn imsg_flush
224 is a function which calls
225 .Fn msgbuf_write
226 in a loop until all imsgs in the output buffer are sent.
227 It returns 0 if it succeeds, \-1 otherwise.
228 .Pp
229 The
230 .Fn imsg_read
231 routine reads pending data with
232 .Xr recvmsg 2
233 and queues it as individual messages on
234 .Fa imsgbuf .
235 It returns the number of bytes read on success, or \-1 on error.
236 A return value of \-1 from
237 .Fn imsg_read
238 invalidates
239 .Fa imsgbuf ,
240 and renders it suitable only for passing to
241 .Fn imsg_clear .
242 .Pp
243 .Fn imsg_get
244 fills in an individual imsg pending on
245 .Fa imsgbuf
246 into the structure pointed to by
247 .Fa imsg .
248 It returns the total size of the message, 0 if no messages are ready, or \-1
249 for an error.
250 Received messages are returned as a
251 .Em struct imsg ,
252 which must be freed by
253 .Fn imsg_free
254 when no longer required.
255 .Em struct imsg
256 has this form:
257 .Bd -literal -offset indent
258 struct imsg {
259         struct imsg_hdr  hdr;
260         int              fd;
261         void            *data;
262 };
263
264 struct imsg_hdr {
265         u_int32_t        type;
266         u_int16_t        len;
267         u_int16_t        flags;
268         u_int32_t        peerid;
269         u_int32_t        pid;
270 };
271 .Ed
272 .Pp
273 The header members are:
274 .Bl -tag -width Ds -offset indent
275 .It type
276 A integer identifier, typically used to express the meaning of the message.
277 .It len
278 The total length of the imsg, including the header and any ancillary data
279 transmitted with the message (pointed to by the
280 .Em data
281 member of the message itself).
282 .It flags
283 Flags used internally by the imsg functions: should not be used by application
284 programs.
285 .It peerid, pid
286 32-bit values specified on message creation and free for any use by the
287 caller, normally used to identify the message sender.
288 .El
289 .Pp
290 In addition,
291 .Em struct imsg
292 has the following:
293 .Bl -tag -width Ds -offset indent
294 .It fd
295 The file descriptor specified when the message was created and passed using the
296 socket control message API, or \-1 if no file descriptor was sent.
297 .It data
298 A pointer to the ancillary data transmitted with the imsg.
299 .El
300 .Pp
301 The IMSG_HEADER_SIZE define is the size of the imsg message header, which
302 may be subtracted from the
303 .Fa len
304 member of
305 .Em struct imsg_hdr
306 to obtain the length of any additional data passed with the message.
307 .Pp
308 MAX_IMSGSIZE is defined as the maximum size of a single imsg, currently
309 16384 bytes.
310 .Sh BUFFERS
311 The imsg API defines functions to manipulate buffers, used internally and during
312 construction of imsgs with
313 .Fn imsg_create .
314 A
315 .Em struct ibuf
316 is a single buffer and a
317 .Em struct msgbuf
318 a queue of output buffers for transmission:
319 .Bd -literal -offset indent
320 struct ibuf {
321         TAILQ_ENTRY(ibuf)        entry;
322         u_char                  *buf;
323         size_t                   size;
324         size_t                   max;
325         size_t                   wpos;
326         size_t                   rpos;
327         int                      fd;
328 };
329
330 struct msgbuf {
331         TAILQ_HEAD(, ibuf)       bufs;
332         u_int32_t                queued;
333         int                      fd;
334 };
335 .Ed
336 .Pp
337 The
338 .Fn ibuf_open
339 function allocates a fixed-length buffer.
340 The buffer may not be resized and may contain a maximum of
341 .Fa len
342 bytes.
343 On success
344 .Fn ibuf_open
345 returns a pointer to the buffer; on failure it returns NULL.
346 .Pp
347 .Fn ibuf_dynamic
348 allocates a resizable buffer of initial length
349 .Fa len
350 and maximum size
351 .Fa max .
352 Buffers allocated with
353 .Fn ibuf_dynamic
354 are automatically grown if necessary when data is added.
355 .Pp
356 .Fn ibuf_add
357 is a routine which appends a block of data to
358 .Fa buf .
359 0 is returned on success and \-1 on failure.
360 .Pp
361 .Fn ibuf_reserve
362 is used to reserve
363 .Fa len
364 bytes in
365 .Fa buf .
366 A pointer to the start of the reserved space is returned, or NULL on error.
367 .Pp
368 .Fn ibuf_seek
369 is a function which returns a pointer to the part of the buffer at offset
370 .Fa pos
371 and of extent
372 .Fa len .
373 NULL is returned if the requested range is outside the part of the buffer
374 in use.
375 .Pp
376 .Fn ibuf_size
377 and
378 .Fn ibuf_left
379 are functions which return the total bytes used and available in
380 .Fa buf
381 respectively.
382 .Pp
383 .Fn ibuf_close
384 appends
385 .Fa buf
386 to
387 .Fa msgbuf
388 ready to be sent.
389 .Pp
390 The
391 .Fn ibuf_write
392 routine transmits as many pending buffers as possible from
393 .Fn msgbuf
394 using
395 .Xr writev 2 .
396 It returns 1 if it succeeds, \-1 on error and 0 when no buffers were
397 pending or an EOF condition on the socket is detected.
398 Temporary resource shortages are returned with errno
399 .Er EAGAIN
400 and require the application to retry again in the future.
401 .Pp
402 .Fn ibuf_free
403 frees
404 .Fa buf
405 and any associated storage.
406 .Pp
407 The
408 .Fn msgbuf_init
409 function initializes
410 .Fa msgbuf
411 so that buffers may be appended to it.
412 The
413 .Em fd
414 member should also be set directly before
415 .Fn msgbuf_write
416 is used.
417 .Pp
418 .Fn msgbuf_clear
419 empties a msgbuf, removing and discarding any queued buffers.
420 .Pp
421 The
422 .Fn msgbuf_write
423 routine calls
424 .Xr sendmsg 2
425 to transmit buffers queued in
426 .Fa msgbuf .
427 It returns 1 if it succeeds, \-1 on error, and 0 when the queue was empty
428 or an EOF condition on the socket is detected.
429 Temporary resource shortages are returned with errno
430 .Er EAGAIN
431 and require the application to retry again in the future.
432 .Pp
433 .Fn msgbuf_drain
434 discards data from buffers queued in
435 .Fa msgbuf
436 until
437 .Fa n
438 bytes have been removed or
439 .Fa msgbuf
440 is empty.
441 .Sh EXAMPLES
442 In a typical program, a channel between two processes is created with
443 .Xr socketpair 2 ,
444 and an
445 .Em imsgbuf
446 created around one file descriptor in each process:
447 .Bd -literal -offset indent
448 struct imsgbuf  parent_ibuf, child_ibuf;
449 int             imsg_fds[2];
450
451 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
452         err(1, "socketpair");
453
454 switch (fork()) {
455 case -1:
456         err(1, "fork");
457 case 0:
458         /* child */
459         close(imsg_fds[0]);
460         imsg_init(&child_ibuf, imsg_fds[1]);
461         exit(child_main(&child_ibuf));
462 }
463
464 /* parent */
465 close(imsg_fds[1]);
466 imsg_init(&parent_ibuf, imsg_fds[0]);
467 exit(parent_main(&parent_ibuf));
468 .Ed
469 .Pp
470 Messages may then be composed and queued on the
471 .Em imsgbuf ,
472 for example using the
473 .Fn imsg_compose
474 function:
475 .Bd -literal -offset indent
476 enum imsg_type {
477         IMSG_A_MESSAGE,
478         IMSG_MESSAGE2
479 };
480
481 int
482 child_main(struct imsgbuf *ibuf)
483 {
484         int     idata;
485         ...
486         idata = 42;
487         imsg_compose(ibuf, IMSG_A_MESSAGE,
488                 0, 0, -1, &idata, sizeof idata);
489         ...
490 }
491 .Ed
492 .Pp
493 A mechanism such as
494 .Xr poll 2
495 or the
496 .Xr event 3
497 library is used to monitor the socket file descriptor.
498 When the socket is ready for writing, queued messages are transmitted with
499 .Fn msgbuf_write :
500 .Bd -literal -offset indent
501         if (msgbuf_write(&ibuf-\*(Gtw) \*(Lt= 0 && errno != EAGAIN) {
502                 /* handle write failure */
503         }
504 .Ed
505 .Pp
506 And when ready for reading, messages are first received using
507 .Fn imsg_read
508 and then extracted with
509 .Fn imsg_get :
510 .Bd -literal -offset indent
511 void
512 dispatch_imsg(struct imsgbuf *ibuf)
513 {
514         struct imsg     imsg;
515         ssize_t         n, datalen;
516         int             idata;
517
518         if ((n = imsg_read(ibuf)) == -1 || n == 0) {
519                 /* handle socket error */
520         }
521
522         for (;;) {
523                 if ((n = imsg_get(ibuf, &imsg)) == -1) {
524                         /* handle read error */
525                 }
526                 if (n == 0)     /* no more messages */
527                         return;
528                 datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
529
530                 switch (imsg.hdr.type) {
531                 case IMSG_A_MESSAGE:
532                         if (datalen \*(Lt sizeof idata) {
533                                 /* handle corrupt message */
534                         }
535                         memcpy(&idata, imsg.data, sizeof idata);
536                         /* handle message received */
537                         break;
538                 ...
539                 }
540
541                 imsg_free(&imsg);
542         }
543 }
544 .Ed
545 .Sh SEE ALSO
546 .Xr socketpair 2 ,
547 .Xr unix 4