xref: /freebsd/lib/libopenbsd/imsg_init.3 (revision 837fe32558013664753f81ee12f7153deafb592c)
170623c80SCraig Rodrigues.\" $OpenBSD: imsg_init.3,v 1.13 2015/07/11 16:23:59 deraadt Exp $
270623c80SCraig Rodrigues.\"
370623c80SCraig Rodrigues.\" Copyright (c) 2010 Nicholas Marriott <nicm@openbsd.org>
470623c80SCraig Rodrigues.\"
570623c80SCraig Rodrigues.\" Permission to use, copy, modify, and distribute this software for any
670623c80SCraig Rodrigues.\" purpose with or without fee is hereby granted, provided that the above
770623c80SCraig Rodrigues.\" copyright notice and this permission notice appear in all copies.
870623c80SCraig Rodrigues.\"
970623c80SCraig Rodrigues.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1070623c80SCraig Rodrigues.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1170623c80SCraig Rodrigues.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1270623c80SCraig Rodrigues.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1370623c80SCraig Rodrigues.\" WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
1470623c80SCraig Rodrigues.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
1570623c80SCraig Rodrigues.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1670623c80SCraig Rodrigues.\"
1770623c80SCraig Rodrigues.\" $FreeBSD$
1870623c80SCraig Rodrigues.\"
1970623c80SCraig Rodrigues.Dd $Mdocdate: July 11 2015 $
2070623c80SCraig Rodrigues.Dt IMSG_INIT 3
2170623c80SCraig Rodrigues.Os
2270623c80SCraig Rodrigues.Sh NAME
2370623c80SCraig Rodrigues.Nm imsg_init ,
2470623c80SCraig Rodrigues.Nm imsg_read ,
2570623c80SCraig Rodrigues.Nm imsg_get ,
2670623c80SCraig Rodrigues.Nm imsg_compose ,
2770623c80SCraig Rodrigues.Nm imsg_composev ,
2870623c80SCraig Rodrigues.Nm imsg_create ,
2970623c80SCraig Rodrigues.Nm imsg_add ,
3070623c80SCraig Rodrigues.Nm imsg_close ,
3170623c80SCraig Rodrigues.Nm imsg_free ,
3270623c80SCraig Rodrigues.Nm imsg_flush ,
3370623c80SCraig Rodrigues.Nm imsg_clear ,
3470623c80SCraig Rodrigues.Nm ibuf_open ,
3570623c80SCraig Rodrigues.Nm ibuf_dynamic ,
3670623c80SCraig Rodrigues.Nm ibuf_add ,
3770623c80SCraig Rodrigues.Nm ibuf_reserve ,
3870623c80SCraig Rodrigues.Nm ibuf_seek ,
3970623c80SCraig Rodrigues.Nm ibuf_size ,
4070623c80SCraig Rodrigues.Nm ibuf_left ,
4170623c80SCraig Rodrigues.Nm ibuf_close ,
4270623c80SCraig Rodrigues.Nm ibuf_write ,
4370623c80SCraig Rodrigues.Nm ibuf_free ,
4470623c80SCraig Rodrigues.Nm msgbuf_init ,
4570623c80SCraig Rodrigues.Nm msgbuf_clear ,
4670623c80SCraig Rodrigues.Nm msgbuf_write ,
4770623c80SCraig Rodrigues.Nm msgbuf_drain
4870623c80SCraig Rodrigues.Nd IPC messaging functions
4970623c80SCraig Rodrigues.Sh SYNOPSIS
5070623c80SCraig Rodrigues.In sys/types.h
5170623c80SCraig Rodrigues.In sys/queue.h
5270623c80SCraig Rodrigues.In sys/uio.h
5370623c80SCraig Rodrigues.In imsg.h
5470623c80SCraig Rodrigues.Ft void
5570623c80SCraig Rodrigues.Fn imsg_init "struct imsgbuf *ibuf" "int fd"
5670623c80SCraig Rodrigues.Ft ssize_t
5770623c80SCraig Rodrigues.Fn imsg_read "struct imsgbuf *ibuf"
5870623c80SCraig Rodrigues.Ft ssize_t
5970623c80SCraig Rodrigues.Fn imsg_get "struct imsgbuf *ibuf" "struct imsg *imsg"
6070623c80SCraig Rodrigues.Ft int
6170623c80SCraig Rodrigues.Fn imsg_compose "struct imsgbuf *ibuf" "u_int32_t type" "uint32_t peerid" \
6270623c80SCraig Rodrigues    "pid_t pid" "int fd" "const void *data" "u_int16_t datalen"
6370623c80SCraig Rodrigues.Ft int
6470623c80SCraig Rodrigues.Fn imsg_composev "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \
6570623c80SCraig Rodrigues    "pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt"
6670623c80SCraig Rodrigues.Ft "struct ibuf *"
6770623c80SCraig Rodrigues.Fn imsg_create "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \
6870623c80SCraig Rodrigues    "pid_t pid" "u_int16_t datalen"
6970623c80SCraig Rodrigues.Ft int
7070623c80SCraig Rodrigues.Fn imsg_add "struct ibuf *buf" "const void *data" "u_int16_t datalen"
7170623c80SCraig Rodrigues.Ft void
7270623c80SCraig Rodrigues.Fn imsg_close "struct imsgbuf *ibuf" "struct ibuf *msg"
7370623c80SCraig Rodrigues.Ft void
7470623c80SCraig Rodrigues.Fn imsg_free "struct imsg *imsg"
7570623c80SCraig Rodrigues.Ft int
7670623c80SCraig Rodrigues.Fn imsg_flush "struct imsgbuf *ibuf"
7770623c80SCraig Rodrigues.Ft void
7870623c80SCraig Rodrigues.Fn imsg_clear "struct imsgbuf *ibuf"
7970623c80SCraig Rodrigues.Ft "struct ibuf *"
8070623c80SCraig Rodrigues.Fn ibuf_open "size_t len"
8170623c80SCraig Rodrigues.Ft "struct ibuf *"
8270623c80SCraig Rodrigues.Fn ibuf_dynamic "size_t len" "size_t max"
8370623c80SCraig Rodrigues.Ft int
8470623c80SCraig Rodrigues.Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len"
8570623c80SCraig Rodrigues.Ft "void *"
8670623c80SCraig Rodrigues.Fn ibuf_reserve "struct ibuf *buf" "size_t len"
8770623c80SCraig Rodrigues.Ft "void *"
8870623c80SCraig Rodrigues.Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len"
8970623c80SCraig Rodrigues.Ft size_t
9070623c80SCraig Rodrigues.Fn ibuf_size "struct ibuf *buf"
9170623c80SCraig Rodrigues.Ft size_t
9270623c80SCraig Rodrigues.Fn ibuf_left "struct ibuf *buf"
9370623c80SCraig Rodrigues.Ft void
9470623c80SCraig Rodrigues.Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf"
9570623c80SCraig Rodrigues.Ft int
9670623c80SCraig Rodrigues.Fn ibuf_write "struct msgbuf *msgbuf"
9770623c80SCraig Rodrigues.Ft void
9870623c80SCraig Rodrigues.Fn ibuf_free "struct ibuf *buf"
9970623c80SCraig Rodrigues.Ft void
10070623c80SCraig Rodrigues.Fn msgbuf_init "struct msgbuf *msgbuf"
10170623c80SCraig Rodrigues.Ft void
10270623c80SCraig Rodrigues.Fn msgbuf_clear "struct msgbuf *msgbuf"
10370623c80SCraig Rodrigues.Ft int
10470623c80SCraig Rodrigues.Fn msgbuf_write "struct msgbuf *msgbuf"
10570623c80SCraig Rodrigues.Ft void
10670623c80SCraig Rodrigues.Fn msgbuf_drain "struct msgbuf *msgbuf" "size_t n"
10770623c80SCraig Rodrigues.Sh DESCRIPTION
10870623c80SCraig RodriguesThe
10970623c80SCraig Rodrigues.Nm imsg
11070623c80SCraig Rodriguesfunctions provide a simple mechanism for communication between processes
11170623c80SCraig Rodriguesusing sockets.
11270623c80SCraig RodriguesEach transmitted message is guaranteed to be presented to the receiving program
11370623c80SCraig Rodrigueswhole.
11470623c80SCraig RodriguesThey are commonly used in privilege separated processes, where processes with
11570623c80SCraig Rodriguesdifferent rights are required to cooperate.
11670623c80SCraig Rodrigues.Pp
11770623c80SCraig RodriguesA program using these functions should be linked with
11870623c80SCraig Rodrigues.Em -lutil .
11970623c80SCraig Rodrigues.Pp
12070623c80SCraig RodriguesThe basic
12170623c80SCraig Rodrigues.Nm
12270623c80SCraig Rodriguesstructure is the
12370623c80SCraig Rodrigues.Em imsgbuf ,
12470623c80SCraig Rodrigueswhich wraps a file descriptor and represents one side of a channel on which
12570623c80SCraig Rodriguesmessages are sent and received:
12670623c80SCraig Rodrigues.Bd -literal -offset indent
12770623c80SCraig Rodriguesstruct imsgbuf {
12870623c80SCraig Rodrigues	TAILQ_HEAD(, imsg_fd)	fds;
12970623c80SCraig Rodrigues	struct ibuf_read	r;
13070623c80SCraig Rodrigues	struct msgbuf		w;
13170623c80SCraig Rodrigues	int			fd;
13270623c80SCraig Rodrigues	pid_t			pid;
13370623c80SCraig Rodrigues};
13470623c80SCraig Rodrigues.Ed
13570623c80SCraig Rodrigues.Pp
13670623c80SCraig Rodrigues.Fn imsg_init
13770623c80SCraig Rodriguesis a routine which initializes
13870623c80SCraig Rodrigues.Fa ibuf
13970623c80SCraig Rodriguesas one side of a channel associated with
14070623c80SCraig Rodrigues.Fa fd .
14170623c80SCraig RodriguesThe file descriptor is used to send and receive messages,
14270623c80SCraig Rodriguesbut is not closed by any of the imsg functions.
14370623c80SCraig RodriguesAn imsgbuf is initialized with the
14470623c80SCraig Rodrigues.Em w
14570623c80SCraig Rodriguesmember as the output buffer queue,
14670623c80SCraig Rodrigues.Em fd
14770623c80SCraig Rodrigueswith the file descriptor passed to
14870623c80SCraig Rodrigues.Fn imsg_init
14970623c80SCraig Rodriguesand the other members for internal use only.
15070623c80SCraig Rodrigues.Pp
15170623c80SCraig RodriguesThe
15270623c80SCraig Rodrigues.Fn imsg_clear
15370623c80SCraig Rodriguesfunction frees any data allocated as part of an imsgbuf.
15470623c80SCraig Rodrigues.Pp
15570623c80SCraig Rodrigues.Fn imsg_create ,
15670623c80SCraig Rodrigues.Fn imsg_add
15770623c80SCraig Rodriguesand
15870623c80SCraig Rodrigues.Fn imsg_close
15970623c80SCraig Rodriguesare generic construction routines for messages that are to be sent using an
16070623c80SCraig Rodriguesimsgbuf.
16170623c80SCraig Rodrigues.Pp
16270623c80SCraig Rodrigues.Fn imsg_create
16370623c80SCraig Rodriguescreates a new message with header specified by
16470623c80SCraig Rodrigues.Fa type ,
16570623c80SCraig Rodrigues.Fa peerid
16670623c80SCraig Rodriguesand
16770623c80SCraig Rodrigues.Fa pid .
16870623c80SCraig RodriguesA
16970623c80SCraig Rodrigues.Fa pid
17070623c80SCraig Rodriguesof zero uses the process ID returned by
17170623c80SCraig Rodrigues.Xr getpid 2
17270623c80SCraig Rodrigueswhen
17370623c80SCraig Rodrigues.Fa ibuf
17470623c80SCraig Rodrigueswas initialized.
17570623c80SCraig RodriguesIn addition to this common imsg header,
17670623c80SCraig Rodrigues.Fa datalen
17770623c80SCraig Rodriguesbytes of space may be reserved for attaching to this imsg.
17870623c80SCraig RodriguesThis space is populated using
17970623c80SCraig Rodrigues.Fn imsg_add .
18070623c80SCraig RodriguesAdditionally, the file descriptor
18170623c80SCraig Rodrigues.Fa fd
18270623c80SCraig Rodriguesmay be passed over the socket to the other process.
18370623c80SCraig RodriguesIf
18470623c80SCraig Rodrigues.Fa fd
18570623c80SCraig Rodriguesis given, it is closed in the sending program after the message is sent.
18670623c80SCraig RodriguesA value of \-1 indicates no file descriptor should be passed.
18770623c80SCraig Rodrigues.Fn imsg_create
18870623c80SCraig Rodriguesreturns a pointer to a new message if it succeeds, NULL otherwise.
18970623c80SCraig Rodrigues.Pp
19070623c80SCraig Rodrigues.Fn imsg_add
19170623c80SCraig Rodriguesappends to
19270623c80SCraig Rodrigues.Fa imsg
19370623c80SCraig Rodrigues.Fa len
19470623c80SCraig Rodriguesbytes of ancillary data pointed to by
19570623c80SCraig Rodrigues.Fa buf .
19670623c80SCraig RodriguesIt returns
19770623c80SCraig Rodrigues.Fa len
19870623c80SCraig Rodriguesif it succeeds, \-1 otherwise.
19970623c80SCraig Rodrigues.Pp
20070623c80SCraig Rodrigues.Fn imsg_close
20170623c80SCraig Rodriguescompletes creation of
20270623c80SCraig Rodrigues.Fa imsg
20370623c80SCraig Rodriguesby adding it to
20470623c80SCraig Rodrigues.Fa imsgbuf
20570623c80SCraig Rodriguesoutput buffer.
20670623c80SCraig Rodrigues.Pp
20770623c80SCraig Rodrigues.Fn imsg_compose
20870623c80SCraig Rodriguesis a routine which is used to quickly create and queue an imsg.
20970623c80SCraig RodriguesIt takes the same parameters as the
21070623c80SCraig Rodrigues.Fn imsg_create ,
21170623c80SCraig Rodrigues.Fn imsg_add
21270623c80SCraig Rodriguesand
21370623c80SCraig Rodrigues.Fn imsg_close
21470623c80SCraig Rodriguesroutines,
21570623c80SCraig Rodriguesexcept that only one ancillary data buffer can be provided.
21670623c80SCraig RodriguesThis routine returns 1 if it succeeds, \-1 otherwise.
21770623c80SCraig Rodrigues.Pp
21870623c80SCraig Rodrigues.Fn imsg_composev
21970623c80SCraig Rodriguesis similar to
22070623c80SCraig Rodrigues.Fn imsg_compose .
22170623c80SCraig RodriguesIt takes the same parameters, except that the ancillary data buffer is specified
22270623c80SCraig Rodriguesby
22370623c80SCraig Rodrigues.Fa iovec .
22470623c80SCraig Rodrigues.Pp
22570623c80SCraig Rodrigues.Fn imsg_flush
22670623c80SCraig Rodriguesis a function which calls
22770623c80SCraig Rodrigues.Fn msgbuf_write
22870623c80SCraig Rodriguesin a loop until all imsgs in the output buffer are sent.
22970623c80SCraig RodriguesIt returns 0 if it succeeds, \-1 otherwise.
23070623c80SCraig Rodrigues.Pp
23170623c80SCraig RodriguesThe
23270623c80SCraig Rodrigues.Fn imsg_read
23370623c80SCraig Rodriguesroutine reads pending data with
23470623c80SCraig Rodrigues.Xr recvmsg 2
23570623c80SCraig Rodriguesand queues it as individual messages on
23670623c80SCraig Rodrigues.Fa imsgbuf .
23770623c80SCraig RodriguesIt returns the number of bytes read on success, or \-1 on error.
23870623c80SCraig RodriguesA return value of \-1 from
23970623c80SCraig Rodrigues.Fn imsg_read
24070623c80SCraig Rodriguesinvalidates
24170623c80SCraig Rodrigues.Fa imsgbuf ,
24270623c80SCraig Rodriguesand renders it suitable only for passing to
24370623c80SCraig Rodrigues.Fn imsg_clear .
24470623c80SCraig Rodrigues.Pp
24570623c80SCraig Rodrigues.Fn imsg_get
24670623c80SCraig Rodriguesfills in an individual imsg pending on
24770623c80SCraig Rodrigues.Fa imsgbuf
24870623c80SCraig Rodriguesinto the structure pointed to by
24970623c80SCraig Rodrigues.Fa imsg .
25070623c80SCraig RodriguesIt returns the total size of the message, 0 if no messages are ready, or \-1
25170623c80SCraig Rodriguesfor an error.
25270623c80SCraig RodriguesReceived messages are returned as a
25370623c80SCraig Rodrigues.Em struct imsg ,
25470623c80SCraig Rodrigueswhich must be freed by
25570623c80SCraig Rodrigues.Fn imsg_free
25670623c80SCraig Rodrigueswhen no longer required.
25770623c80SCraig Rodrigues.Em struct imsg
25870623c80SCraig Rodrigueshas this form:
25970623c80SCraig Rodrigues.Bd -literal -offset indent
26070623c80SCraig Rodriguesstruct imsg {
26170623c80SCraig Rodrigues	struct imsg_hdr	 hdr;
26270623c80SCraig Rodrigues	int		 fd;
26370623c80SCraig Rodrigues	void		*data;
26470623c80SCraig Rodrigues};
26570623c80SCraig Rodrigues
26670623c80SCraig Rodriguesstruct imsg_hdr {
26770623c80SCraig Rodrigues	u_int32_t	 type;
26870623c80SCraig Rodrigues	u_int16_t	 len;
26970623c80SCraig Rodrigues	u_int16_t	 flags;
27070623c80SCraig Rodrigues	u_int32_t	 peerid;
27170623c80SCraig Rodrigues	u_int32_t	 pid;
27270623c80SCraig Rodrigues};
27370623c80SCraig Rodrigues.Ed
27470623c80SCraig Rodrigues.Pp
27570623c80SCraig RodriguesThe header members are:
27670623c80SCraig Rodrigues.Bl -tag -width Ds -offset indent
27770623c80SCraig Rodrigues.It type
27870623c80SCraig RodriguesA integer identifier, typically used to express the meaning of the message.
27970623c80SCraig Rodrigues.It len
28070623c80SCraig RodriguesThe total length of the imsg, including the header and any ancillary data
28170623c80SCraig Rodriguestransmitted with the message (pointed to by the
28270623c80SCraig Rodrigues.Em data
28370623c80SCraig Rodriguesmember of the message itself).
28470623c80SCraig Rodrigues.It flags
28570623c80SCraig RodriguesFlags used internally by the imsg functions: should not be used by application
28670623c80SCraig Rodriguesprograms.
28770623c80SCraig Rodrigues.It peerid, pid
28870623c80SCraig Rodrigues32-bit values specified on message creation and free for any use by the
28970623c80SCraig Rodriguescaller, normally used to identify the message sender.
29070623c80SCraig Rodrigues.El
29170623c80SCraig Rodrigues.Pp
29270623c80SCraig RodriguesIn addition,
29370623c80SCraig Rodrigues.Em struct imsg
29470623c80SCraig Rodrigueshas the following:
29570623c80SCraig Rodrigues.Bl -tag -width Ds -offset indent
29670623c80SCraig Rodrigues.It fd
29770623c80SCraig RodriguesThe file descriptor specified when the message was created and passed using the
29870623c80SCraig Rodriguessocket control message API, or \-1 if no file descriptor was sent.
29970623c80SCraig Rodrigues.It data
30070623c80SCraig RodriguesA pointer to the ancillary data transmitted with the imsg.
30170623c80SCraig Rodrigues.El
30270623c80SCraig Rodrigues.Pp
30370623c80SCraig RodriguesThe IMSG_HEADER_SIZE define is the size of the imsg message header, which
30470623c80SCraig Rodriguesmay be subtracted from the
30570623c80SCraig Rodrigues.Fa len
30670623c80SCraig Rodriguesmember of
30770623c80SCraig Rodrigues.Em struct imsg_hdr
30870623c80SCraig Rodriguesto obtain the length of any additional data passed with the message.
30970623c80SCraig Rodrigues.Pp
31070623c80SCraig RodriguesMAX_IMSGSIZE is defined as the maximum size of a single imsg, currently
31170623c80SCraig Rodrigues16384 bytes.
31270623c80SCraig Rodrigues.Sh BUFFERS
31370623c80SCraig RodriguesThe imsg API defines functions to manipulate buffers, used internally and during
31470623c80SCraig Rodriguesconstruction of imsgs with
31570623c80SCraig Rodrigues.Fn imsg_create .
31670623c80SCraig RodriguesA
31770623c80SCraig Rodrigues.Em struct ibuf
31870623c80SCraig Rodriguesis a single buffer and a
31970623c80SCraig Rodrigues.Em struct msgbuf
32070623c80SCraig Rodriguesa queue of output buffers for transmission:
32170623c80SCraig Rodrigues.Bd -literal -offset indent
32270623c80SCraig Rodriguesstruct ibuf {
32370623c80SCraig Rodrigues	TAILQ_ENTRY(ibuf)	 entry;
32470623c80SCraig Rodrigues	u_char			*buf;
32570623c80SCraig Rodrigues	size_t			 size;
32670623c80SCraig Rodrigues	size_t			 max;
32770623c80SCraig Rodrigues	size_t			 wpos;
32870623c80SCraig Rodrigues	size_t			 rpos;
32970623c80SCraig Rodrigues	int			 fd;
33070623c80SCraig Rodrigues};
33170623c80SCraig Rodrigues
33270623c80SCraig Rodriguesstruct msgbuf {
33370623c80SCraig Rodrigues	TAILQ_HEAD(, ibuf)	 bufs;
33470623c80SCraig Rodrigues	u_int32_t		 queued;
33570623c80SCraig Rodrigues	int			 fd;
33670623c80SCraig Rodrigues};
33770623c80SCraig Rodrigues.Ed
33870623c80SCraig Rodrigues.Pp
33970623c80SCraig RodriguesThe
34070623c80SCraig Rodrigues.Fn ibuf_open
34170623c80SCraig Rodriguesfunction allocates a fixed-length buffer.
34270623c80SCraig RodriguesThe buffer may not be resized and may contain a maximum of
34370623c80SCraig Rodrigues.Fa len
34470623c80SCraig Rodriguesbytes.
34570623c80SCraig RodriguesOn success
34670623c80SCraig Rodrigues.Fn ibuf_open
34770623c80SCraig Rodriguesreturns a pointer to the buffer; on failure it returns NULL.
34870623c80SCraig Rodrigues.Pp
34970623c80SCraig Rodrigues.Fn ibuf_dynamic
350*837fe325SEitan Adlerallocates a resizable buffer of initial length
35170623c80SCraig Rodrigues.Fa len
35270623c80SCraig Rodriguesand maximum size
35370623c80SCraig Rodrigues.Fa max .
35470623c80SCraig RodriguesBuffers allocated with
35570623c80SCraig Rodrigues.Fn ibuf_dynamic
35670623c80SCraig Rodriguesare automatically grown if necessary when data is added.
35770623c80SCraig Rodrigues.Pp
35870623c80SCraig Rodrigues.Fn ibuf_add
35970623c80SCraig Rodriguesis a routine which appends a block of data to
36070623c80SCraig Rodrigues.Fa buf .
36170623c80SCraig Rodrigues0 is returned on success and \-1 on failure.
36270623c80SCraig Rodrigues.Pp
36370623c80SCraig Rodrigues.Fn ibuf_reserve
36470623c80SCraig Rodriguesis used to reserve
36570623c80SCraig Rodrigues.Fa len
36670623c80SCraig Rodriguesbytes in
36770623c80SCraig Rodrigues.Fa buf .
36870623c80SCraig RodriguesA pointer to the start of the reserved space is returned, or NULL on error.
36970623c80SCraig Rodrigues.Pp
37070623c80SCraig Rodrigues.Fn ibuf_seek
37170623c80SCraig Rodriguesis a function which returns a pointer to the part of the buffer at offset
37270623c80SCraig Rodrigues.Fa pos
37370623c80SCraig Rodriguesand of extent
37470623c80SCraig Rodrigues.Fa len .
37570623c80SCraig RodriguesNULL is returned if the requested range is outside the part of the buffer
37670623c80SCraig Rodriguesin use.
37770623c80SCraig Rodrigues.Pp
37870623c80SCraig Rodrigues.Fn ibuf_size
37970623c80SCraig Rodriguesand
38070623c80SCraig Rodrigues.Fn ibuf_left
38170623c80SCraig Rodriguesare functions which return the total bytes used and available in
38270623c80SCraig Rodrigues.Fa buf
38370623c80SCraig Rodriguesrespectively.
38470623c80SCraig Rodrigues.Pp
38570623c80SCraig Rodrigues.Fn ibuf_close
38670623c80SCraig Rodriguesappends
38770623c80SCraig Rodrigues.Fa buf
38870623c80SCraig Rodriguesto
38970623c80SCraig Rodrigues.Fa msgbuf
39070623c80SCraig Rodriguesready to be sent.
39170623c80SCraig Rodrigues.Pp
39270623c80SCraig RodriguesThe
39370623c80SCraig Rodrigues.Fn ibuf_write
39470623c80SCraig Rodriguesroutine transmits as many pending buffers as possible from
39570623c80SCraig Rodrigues.Fn msgbuf
39670623c80SCraig Rodriguesusing
39770623c80SCraig Rodrigues.Xr writev 2 .
39870623c80SCraig RodriguesIt returns 1 if it succeeds, \-1 on error and 0 when no buffers were
39970623c80SCraig Rodriguespending or an EOF condition on the socket is detected.
40070623c80SCraig RodriguesTemporary resource shortages are returned with errno
40170623c80SCraig Rodrigues.Er EAGAIN
40270623c80SCraig Rodriguesand require the application to retry again in the future.
40370623c80SCraig Rodrigues.Pp
40470623c80SCraig Rodrigues.Fn ibuf_free
40570623c80SCraig Rodriguesfrees
40670623c80SCraig Rodrigues.Fa buf
40770623c80SCraig Rodriguesand any associated storage.
40870623c80SCraig Rodrigues.Pp
40970623c80SCraig RodriguesThe
41070623c80SCraig Rodrigues.Fn msgbuf_init
41170623c80SCraig Rodriguesfunction initializes
41270623c80SCraig Rodrigues.Fa msgbuf
41370623c80SCraig Rodriguesso that buffers may be appended to it.
41470623c80SCraig RodriguesThe
41570623c80SCraig Rodrigues.Em fd
41670623c80SCraig Rodriguesmember should also be set directly before
41770623c80SCraig Rodrigues.Fn msgbuf_write
41870623c80SCraig Rodriguesis used.
41970623c80SCraig Rodrigues.Pp
42070623c80SCraig Rodrigues.Fn msgbuf_clear
42170623c80SCraig Rodriguesempties a msgbuf, removing and discarding any queued buffers.
42270623c80SCraig Rodrigues.Pp
42370623c80SCraig RodriguesThe
42470623c80SCraig Rodrigues.Fn msgbuf_write
42570623c80SCraig Rodriguesroutine calls
42670623c80SCraig Rodrigues.Xr sendmsg 2
42770623c80SCraig Rodriguesto transmit buffers queued in
42870623c80SCraig Rodrigues.Fa msgbuf .
42970623c80SCraig RodriguesIt returns 1 if it succeeds, \-1 on error, and 0 when the queue was empty
43070623c80SCraig Rodriguesor an EOF condition on the socket is detected.
43170623c80SCraig RodriguesTemporary resource shortages are returned with errno
43270623c80SCraig Rodrigues.Er EAGAIN
43370623c80SCraig Rodriguesand require the application to retry again in the future.
43470623c80SCraig Rodrigues.Pp
43570623c80SCraig Rodrigues.Fn msgbuf_drain
43670623c80SCraig Rodriguesdiscards data from buffers queued in
43770623c80SCraig Rodrigues.Fa msgbuf
43870623c80SCraig Rodriguesuntil
43970623c80SCraig Rodrigues.Fa n
44070623c80SCraig Rodriguesbytes have been removed or
44170623c80SCraig Rodrigues.Fa msgbuf
44270623c80SCraig Rodriguesis empty.
44370623c80SCraig Rodrigues.Sh EXAMPLES
44470623c80SCraig RodriguesIn a typical program, a channel between two processes is created with
44570623c80SCraig Rodrigues.Xr socketpair 2 ,
44670623c80SCraig Rodriguesand an
44770623c80SCraig Rodrigues.Em imsgbuf
44870623c80SCraig Rodriguescreated around one file descriptor in each process:
44970623c80SCraig Rodrigues.Bd -literal -offset indent
45070623c80SCraig Rodriguesstruct imsgbuf	parent_ibuf, child_ibuf;
45170623c80SCraig Rodriguesint		imsg_fds[2];
45270623c80SCraig Rodrigues
45370623c80SCraig Rodriguesif (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
45470623c80SCraig Rodrigues	err(1, "socketpair");
45570623c80SCraig Rodrigues
45670623c80SCraig Rodriguesswitch (fork()) {
45770623c80SCraig Rodriguescase -1:
45870623c80SCraig Rodrigues	err(1, "fork");
45970623c80SCraig Rodriguescase 0:
46070623c80SCraig Rodrigues	/* child */
46170623c80SCraig Rodrigues	close(imsg_fds[0]);
46270623c80SCraig Rodrigues	imsg_init(&child_ibuf, imsg_fds[1]);
46370623c80SCraig Rodrigues	exit(child_main(&child_ibuf));
46470623c80SCraig Rodrigues}
46570623c80SCraig Rodrigues
46670623c80SCraig Rodrigues/* parent */
46770623c80SCraig Rodriguesclose(imsg_fds[1]);
46870623c80SCraig Rodriguesimsg_init(&parent_ibuf, imsg_fds[0]);
46970623c80SCraig Rodriguesexit(parent_main(&parent_ibuf));
47070623c80SCraig Rodrigues.Ed
47170623c80SCraig Rodrigues.Pp
47270623c80SCraig RodriguesMessages may then be composed and queued on the
47370623c80SCraig Rodrigues.Em imsgbuf ,
47470623c80SCraig Rodriguesfor example using the
47570623c80SCraig Rodrigues.Fn imsg_compose
47670623c80SCraig Rodriguesfunction:
47770623c80SCraig Rodrigues.Bd -literal -offset indent
47870623c80SCraig Rodriguesenum imsg_type {
47970623c80SCraig Rodrigues	IMSG_A_MESSAGE,
48070623c80SCraig Rodrigues	IMSG_MESSAGE2
48170623c80SCraig Rodrigues};
48270623c80SCraig Rodrigues
48370623c80SCraig Rodriguesint
48470623c80SCraig Rodrigueschild_main(struct imsgbuf *ibuf)
48570623c80SCraig Rodrigues{
48670623c80SCraig Rodrigues	int	idata;
48770623c80SCraig Rodrigues	...
48870623c80SCraig Rodrigues	idata = 42;
48970623c80SCraig Rodrigues	imsg_compose(ibuf, IMSG_A_MESSAGE,
49070623c80SCraig Rodrigues		0, 0, -1, &idata, sizeof idata);
49170623c80SCraig Rodrigues	...
49270623c80SCraig Rodrigues}
49370623c80SCraig Rodrigues.Ed
49470623c80SCraig Rodrigues.Pp
49570623c80SCraig RodriguesA mechanism such as
49670623c80SCraig Rodrigues.Xr poll 2
49770623c80SCraig Rodriguesor the
49870623c80SCraig Rodrigues.Xr event 3
49970623c80SCraig Rodrigueslibrary is used to monitor the socket file descriptor.
50070623c80SCraig RodriguesWhen the socket is ready for writing, queued messages are transmitted with
50170623c80SCraig Rodrigues.Fn msgbuf_write :
50270623c80SCraig Rodrigues.Bd -literal -offset indent
50370623c80SCraig Rodrigues	if (msgbuf_write(&ibuf-\*(Gtw) \*(Lt= 0 && errno != EAGAIN) {
50470623c80SCraig Rodrigues		/* handle write failure */
50570623c80SCraig Rodrigues	}
50670623c80SCraig Rodrigues.Ed
50770623c80SCraig Rodrigues.Pp
50870623c80SCraig RodriguesAnd when ready for reading, messages are first received using
50970623c80SCraig Rodrigues.Fn imsg_read
51070623c80SCraig Rodriguesand then extracted with
51170623c80SCraig Rodrigues.Fn imsg_get :
51270623c80SCraig Rodrigues.Bd -literal -offset indent
51370623c80SCraig Rodriguesvoid
51470623c80SCraig Rodriguesdispatch_imsg(struct imsgbuf *ibuf)
51570623c80SCraig Rodrigues{
51670623c80SCraig Rodrigues	struct imsg	imsg;
51770623c80SCraig Rodrigues	ssize_t         n, datalen;
51870623c80SCraig Rodrigues	int		idata;
51970623c80SCraig Rodrigues
52070623c80SCraig Rodrigues	if ((n = imsg_read(ibuf)) == -1 || n == 0) {
52170623c80SCraig Rodrigues		/* handle socket error */
52270623c80SCraig Rodrigues	}
52370623c80SCraig Rodrigues
52470623c80SCraig Rodrigues	for (;;) {
52570623c80SCraig Rodrigues		if ((n = imsg_get(ibuf, &imsg)) == -1) {
52670623c80SCraig Rodrigues			/* handle read error */
52770623c80SCraig Rodrigues		}
52870623c80SCraig Rodrigues		if (n == 0)	/* no more messages */
52970623c80SCraig Rodrigues			return;
53070623c80SCraig Rodrigues		datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
53170623c80SCraig Rodrigues
53270623c80SCraig Rodrigues		switch (imsg.hdr.type) {
53370623c80SCraig Rodrigues		case IMSG_A_MESSAGE:
53470623c80SCraig Rodrigues			if (datalen \*(Lt sizeof idata) {
53570623c80SCraig Rodrigues				/* handle corrupt message */
53670623c80SCraig Rodrigues			}
53770623c80SCraig Rodrigues			memcpy(&idata, imsg.data, sizeof idata);
53870623c80SCraig Rodrigues			/* handle message received */
53970623c80SCraig Rodrigues			break;
54070623c80SCraig Rodrigues		...
54170623c80SCraig Rodrigues		}
54270623c80SCraig Rodrigues
54370623c80SCraig Rodrigues		imsg_free(&imsg);
54470623c80SCraig Rodrigues	}
54570623c80SCraig Rodrigues}
54670623c80SCraig Rodrigues.Ed
54770623c80SCraig Rodrigues.Sh SEE ALSO
54870623c80SCraig Rodrigues.Xr socketpair 2 ,
54970623c80SCraig Rodrigues.Xr unix 4
550