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