Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
IMSG_INIT(3)		    Library Functions Manual		  IMSG_INIT(3)

NAME
       imsg_init,    imsg_read,	   imsg_get,	imsg_compose,	imsg_composev,
       imsg_create, imsg_add, imsg_close, imsg_free,  imsg_flush,  imsg_clear,
       ibuf_open,  ibuf_dynamic, ibuf_add, ibuf_reserve, ibuf_seek, ibuf_size,
       ibuf_left,    ibuf_close,    ibuf_write,	   ibuf_free,	  msgbuf_init,
       msgbuf_clear, msgbuf_write, msgbuf_drain	-- IPC messaging functions

LIBRARY
       OpenBSD Utilities Library (libopenbsd, -lopenbsd)

SYNOPSIS
       #include	<sys/types.h>
       #include	<sys/queue.h>
       #include	<sys/uio.h>
       #include	<imsg.h>

       void
       imsg_init(struct	imsgbuf	*ibuf, int fd);

       ssize_t
       imsg_read(struct	imsgbuf	*ibuf);

       ssize_t
       imsg_get(struct imsgbuf *ibuf, struct imsg *imsg);

       int
       imsg_compose(struct  imsgbuf  *ibuf,  u_int32_t	type, uint32_t peerid,
	   pid_t pid, int fd, const void *data,	u_int16_t datalen);

       int
       imsg_composev(struct imsgbuf *ibuf, u_int32_t type,  u_int32_t  peerid,
	   pid_t pid, int fd, const struct iovec *iov, int iovcnt);

       struct ibuf *
       imsg_create(struct  imsgbuf  *ibuf,  u_int32_t  type, u_int32_t peerid,
	   pid_t pid, u_int16_t	datalen);

       int
       imsg_add(struct ibuf *buf, const	void *data, u_int16_t datalen);

       void
       imsg_close(struct imsgbuf *ibuf,	struct ibuf *msg);

       void
       imsg_free(struct	imsg *imsg);

       int
       imsg_flush(struct imsgbuf *ibuf);

       void
       imsg_clear(struct imsgbuf *ibuf);

       struct ibuf *
       ibuf_open(size_t	len);

       struct ibuf *
       ibuf_dynamic(size_t len,	size_t max);

       int
       ibuf_add(struct ibuf *buf, const	void *data, size_t len);

       void *
       ibuf_reserve(struct ibuf	*buf, size_t len);

       void *
       ibuf_seek(struct	ibuf *buf, size_t pos, size_t len);

       size_t
       ibuf_size(struct	ibuf *buf);

       size_t
       ibuf_left(struct	ibuf *buf);

       void
       ibuf_close(struct msgbuf	*msgbuf, struct	ibuf *buf);

       int
       ibuf_write(struct msgbuf	*msgbuf);

       void
       ibuf_free(struct	ibuf *buf);

       void
       msgbuf_init(struct msgbuf *msgbuf);

       void
       msgbuf_clear(struct msgbuf *msgbuf);

       int
       msgbuf_write(struct msgbuf *msgbuf);

       void
       msgbuf_drain(struct msgbuf *msgbuf, size_t n);

DESCRIPTION
       The imsg	functions provide a simple mechanism for communication between
       processes using sockets.	 Each transmitted message is guaranteed	to  be
       presented  to  the  receiving program whole.  They are commonly used in
       privilege separated processes, where processes  with  different	rights
       are required to cooperate.

       A program using these functions should be linked	with -lutil.

       The  basic  imsg_init  structure	is the imsgbuf,	which wraps a file de-
       scriptor	and represents one side	of a channel  on  which	 messages  are
       sent and	received:

	     struct imsgbuf {
		     TAILQ_HEAD(, imsg_fd)   fds;
		     struct ibuf_read	     r;
		     struct msgbuf	     w;
		     int		     fd;
		     pid_t		     pid;
	     };

       imsg_init()  is a routine which initializes ibuf	as one side of a chan-
       nel associated with fd.	The file descriptor is used to	send  and  re-
       ceive  messages,	 but  is  not closed by	any of the imsg	functions.  An
       imsgbuf is initialized with the w member	as the output buffer queue, fd
       with the	file descriptor	passed to imsg_init() and  the	other  members
       for internal use	only.

       The  imsg_clear() function frees	any data allocated as part of an imsg-
       buf.

       imsg_create(), imsg_add() and  imsg_close()  are	 generic  construction
       routines	for messages that are to be sent using an imsgbuf.

       imsg_create()  creates  a  new  message	with header specified by type,
       peerid and pid.	A  pid	of  zero  uses	the  process  ID  returned  by
       getpid(2)  when	ibuf was initialized.  In addition to this common imsg
       header, datalen bytes of	space may be reserved for  attaching  to  this
       imsg.   This  space  is	populated using	imsg_add().  Additionally, the
       file descriptor fd may be passed	over the socket	to the other  process.
       If  fd  is given, it is closed in the sending program after the message
       is sent.	 A value of -1 indicates no file descriptor should be  passed.
       imsg_create()  returns  a pointer to a new message if it	succeeds, NULL
       otherwise.

       imsg_add() appends to imsg len bytes of ancillary data  pointed	to  by
       buf.  It	returns	len if it succeeds, -1 otherwise.

       imsg_close()  completes creation	of imsg	by adding it to	imsgbuf	output
       buffer.

       imsg_compose() is a routine which is used to quickly create  and	 queue
       an imsg.	 It takes the same parameters as the imsg_create(), imsg_add()
       and  imsg_close()  routines, except that	only one ancillary data	buffer
       can be provided.	 This routine returns 1	if it succeeds,	-1 otherwise.

       imsg_composev() is similar to imsg_compose().  It takes the same	 para-
       meters, except that the ancillary data buffer is	specified by iovec.

       imsg_flush()  is	 a function which calls	msgbuf_write() in a loop until
       all imsgs in the	output buffer are sent.	 It returns 0 if it  succeeds,
       -1 otherwise.

       The  imsg_read()	 routine reads pending data with recvmsg(2) and	queues
       it as individual	messages on imsgbuf.  It returns the number  of	 bytes
       read on success,	or -1 on error.	 A return value	of -1 from imsg_read()
       invalidates  imsgbuf,  and  renders  it	suitable  only	for passing to
       imsg_clear().

       imsg_get() fills	in an individual imsg  pending	on  imsgbuf  into  the
       structure  pointed  to  by imsg.	 It returns the	total size of the mes-
       sage, 0 if no messages are ready, or -1 for an  error.	Received  mes-
       sages are returned as a struct imsg, which must be freed	by imsg_free()
       when no longer required.	 struct	imsg has this form:

	     struct imsg {
		     struct imsg_hdr  hdr;
		     int	      fd;
		     void	     *data;
	     };

	     struct imsg_hdr {
		     u_int32_t	      type;
		     u_int16_t	      len;
		     u_int16_t	      flags;
		     u_int32_t	      peerid;
		     u_int32_t	      pid;
	     };

       The header members are:

	     type    A integer identifier, typically used to express the mean-
		     ing of the	message.

	     len     The  total	 length	 of the	imsg, including	the header and
		     any ancillary data	transmitted with the message  (pointed
		     to	by the data member of the message itself).

	     flags   Flags  used  internally by	the imsg functions: should not
		     be	used by	application programs.

	     peerid, pid
		     32-bit values specified on	message	creation and free  for
		     any use by	the caller, normally used to identify the mes-
		     sage sender.

       In addition, struct imsg	has the	following:

	     fd	     The  file	descriptor specified when the message was cre-
		     ated and passed using the socket control message API,  or
		     -1	if no file descriptor was sent.

	     data    A	pointer	 to  the  ancillary  data transmitted with the
		     imsg.

       The IMSG_HEADER_SIZE define is the size of  the	imsg  message  header,
       which  may  be subtracted from the len member of	struct imsg_hdr	to ob-
       tain the	length of any additional data passed with the message.

       MAX_IMSGSIZE is defined as the maximum size of a	single imsg, currently
       16384 bytes.

BUFFERS
       The imsg	API defines functions to manipulate buffers,  used  internally
       and  during construction	of imsgs with imsg_create().  A	struct ibuf is
       a single	buffer and a struct msgbuf  a  queue  of  output  buffers  for
       transmission:

	     struct ibuf {
		     TAILQ_ENTRY(ibuf)	      entry;
		     u_char		     *buf;
		     size_t		      size;
		     size_t		      max;
		     size_t		      wpos;
		     size_t		      rpos;
		     int		      fd;
	     };

	     struct msgbuf {
		     TAILQ_HEAD(, ibuf)	      bufs;
		     u_int32_t		      queued;
		     int		      fd;
	     };

       The  ibuf_open()	 function allocates a fixed-length buffer.  The	buffer
       may not be resized and may contain a maximum of len bytes.  On  success
       ibuf_open()  returns  a	pointer	 to  the buffer; on failure it returns
       NULL.

       ibuf_dynamic() allocates	a resizeable buffer of initial length len  and
       maximum	size max.  Buffers allocated with ibuf_dynamic() are automati-
       cally grown if necessary	when data is added.

       ibuf_add() is a routine which appends a block of	data to	buf.  0	is re-
       turned on success and -1	on failure.

       ibuf_reserve() is used to reserve len bytes in buf.  A pointer  to  the
       start of	the reserved space is returned,	or NULL	on error.

       ibuf_seek()  is	a  function which returns a pointer to the part	of the
       buffer at offset	pos and	of extent len.	NULL is	returned  if  the  re-
       quested range is	outside	the part of the	buffer in use.

       ibuf_size()  and	ibuf_left() are	functions which	return the total bytes
       used and	available in buf respectively.

       ibuf_close() appends buf	to msgbuf ready	to be sent.

       The ibuf_write()	routine	transmits as many pending buffers as  possible
       from  msgbuf() using writev(2).	It returns 1 if	it succeeds, -1	on er-
       ror and 0 when no buffers were pending  or  an  EOF  condition  on  the
       socket is detected.  Temporary resource shortages are returned with er-
       rno EAGAIN and require the application to retry again in	the future.

       ibuf_free() frees buf and any associated	storage.

       The  msgbuf_init()  function  initializes msgbuf	so that	buffers	may be
       appended	to it.	The fd member  should  also  be	 set  directly	before
       msgbuf_write() is used.

       msgbuf_clear()  empties	a  msgbuf,  removing and discarding any	queued
       buffers.

       The msgbuf_write() routine calls	sendmsg(2) to transmit buffers	queued
       in  msgbuf.   It	 returns 1 if it succeeds, -1 on error,	and 0 when the
       queue was empty or an EOF condition on the socket is detected.	Tempo-
       rary  resource shortages	are returned with errno	EAGAIN and require the
       application to retry again in the future.

       msgbuf_drain() discards data from buffers  queued  in  msgbuf  until  n
       bytes have been removed or msgbuf is empty.

EXAMPLES
       In  a  typical program, a channel between two processes is created with
       socketpair(2), and an imsgbuf created around  one  file	descriptor  in
       each process:

	     struct imsgbuf  parent_ibuf, child_ibuf;
	     int	     imsg_fds[2];

	     if	(socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
		     err(1, "socketpair");

	     switch (fork()) {
	     case -1:
		     err(1, "fork");
	     case 0:
		     /*	child */
		     close(imsg_fds[0]);
		     imsg_init(&child_ibuf, imsg_fds[1]);
		     exit(child_main(&child_ibuf));
	     }

	     /*	parent */
	     close(imsg_fds[1]);
	     imsg_init(&parent_ibuf, imsg_fds[0]);
	     exit(parent_main(&parent_ibuf));

       Messages	 may  then  be composed	and queued on the imsgbuf, for example
       using the imsg_compose()	function:

	     enum imsg_type {
		     IMSG_A_MESSAGE,
		     IMSG_MESSAGE2
	     };

	     int
	     child_main(struct imsgbuf *ibuf)
	     {
		     int     idata;
		     ...
		     idata = 42;
		     imsg_compose(ibuf,	IMSG_A_MESSAGE,
			     0,	0, -1, &idata, sizeof idata);
		     ...
	     }

       A mechanism such	as poll(2) or the event(3) library is used to  monitor
       the  socket  file  descriptor.	When  the socket is ready for writing,
       queued messages are transmitted with msgbuf_write():

		     if	(msgbuf_write(&ibuf->w)	<= 0 &&	errno != EAGAIN) {
			     /*	handle write failure */
		     }

       And  when  ready	 for  reading,	messages  are  first  received	 using
       imsg_read() and then extracted with imsg_get():

	     void
	     dispatch_imsg(struct imsgbuf *ibuf)
	     {
		     struct imsg     imsg;
		     ssize_t	     n,	datalen;
		     int	     idata;

		     if	((n = imsg_read(ibuf)) == -1 ||	n == 0)	{
			     /*	handle socket error */
		     }

		     for (;;) {
			     if	((n = imsg_get(ibuf, &imsg)) ==	-1) {
				     /*	handle read error */
			     }
			     if	(n == 0)     /*	no more	messages */
				     return;
			     datalen = imsg.hdr.len - IMSG_HEADER_SIZE;

			     switch (imsg.hdr.type) {
			     case IMSG_A_MESSAGE:
				     if	(datalen < sizeof idata) {
					     /*	handle corrupt message */
				     }
				     memcpy(&idata, imsg.data, sizeof idata);
				     /*	handle message received	*/
				     break;
			     ...
			     }

			     imsg_free(&imsg);
		     }
	     }

SEE ALSO
       socketpair(2), unix(4)

FreeBSD	Ports 14.quarterly	 July 11, 2015			  IMSG_INIT(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=imsg_init&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help