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