IBUF_ADD(3)

NAME
ibuf_add, ibuf_add_h16, ibuf_add_h32, ibuf_add_h64, ibuf_add_ibuf, ibuf_add_n16, ibuf_add_n32, ibuf_add_n64, ibuf_add_n8, ibuf_add_strbuf, ibuf_add_zero, ibuf_close, ibuf_data, ibuf_dynamic, ibuf_fd_avail, ibuf_fd_get, ibuf_fd_set, ibuf_free, ibuf_from_buffer, ibuf_from_ibuf, ibuf_get, ibuf_get_ibuf, ibuf_get_h16, ibuf_get_h32, ibuf_get_h64, ibuf_get_n16, ibuf_get_n32, ibuf_get_n64, ibuf_get_n8, ibuf_get_strbuf, ibuf_get_string, ibuf_left, ibuf_open, ibuf_read, ibuf_reserve, ibuf_rewind, ibuf_seek, ibuf_set, ibuf_set_h16, ibuf_set_h32, ibuf_set_h64, ibuf_set_n16, ibuf_set_n32, ibuf_set_n64, ibuf_set_n8, ibuf_set_maxsize, ibuf_size, ibuf_skip, ibuf_truncate, ibuf_write, msgbuf_clear, msgbuf_concat, msgbuf_free, msgbuf_get, msgbuf_new, msgbuf_new_reader, msgbuf_queuelen, msgbuf_read, msgbuf_write, ibufq_concat, ibufq_flush, ibufq_free, ibufq_new, ibufq_pop, ibufq_push, ibufq_queuelen - save buffer API for basic IO

SYNOPSIS
#include <imsg.h>
#define IBUF_READ_SIZE 65535
int
ibuf_add(struct ibuf *buf, const void *data, size_t len);
int
ibuf_add_h16(struct ibuf *buf, uint64_t value);
int
ibuf_add_h32(struct ibuf *buf, uint64_t value);
int
ibuf_add_h64(struct ibuf *buf, uint64_t value);
int
ibuf_add_ibuf(struct ibuf *buf, const struct ibuf *from);
int
ibuf_add_n16(struct ibuf *buf, uint64_t value);
int
ibuf_add_n32(struct ibuf *buf, uint64_t value);
int
ibuf_add_n64(struct ibuf *buf, uint64_t value);
int
ibuf_add_n8(struct ibuf *buf, uint64_t value);
int
ibuf_add_strbuf(struct ibuf *buf, const char *str, size_t len);
int
ibuf_add_zero(struct ibuf *buf, size_t len);
void
ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf);
void *
ibuf_data(struct ibuf *buf);
struct ibuf *
ibuf_dynamic(size_t len, size_t max);
int
ibuf_fd_avail(struct ibuf *buf);
int
ibuf_fd_get(struct ibuf *buf);
void
ibuf_fd_set(struct ibuf *buf, int fd);
void
ibuf_free(struct ibuf *buf);
void
ibuf_from_buffer(struct ibuf *buf, void *data, size_t len);
void
ibuf_from_ibuf(struct ibuf *buf, const ibuf *from);
int
ibuf_get(struct ibuf *buf, void *data, size_t len);
int
ibuf_get_ibuf(struct ibuf *buf, size_t len, struct ibuf *new);
int
ibuf_get_h16(struct ibuf *buf, uint16_t *value);
int
ibuf_get_h32(struct ibuf *buf, uint32_t *value);
int
ibuf_get_h64(struct ibuf *buf, uint64_t *value);
int
ibuf_get_n16(struct ibuf *buf, uint16_t *value);
int
ibuf_get_n32(struct ibuf *buf, uint32_t *value);
int
ibuf_get_n64(struct ibuf *buf, uint64_t *value);
int
ibuf_get_n8(struct ibuf *buf, uint8_t *value);
int
ibuf_get_strbuf(struct ibuf *buf, char *str, size_t len);
char *
ibuf_get_string(struct ibuf *buf, size_t len);
size_t
ibuf_left(const struct ibuf *buf);
struct ibuf *
ibuf_open(size_t len);
int
ibuf_read(int fd, struct msgbuf *msgbuf);
void *
ibuf_reserve(struct ibuf *buf, size_t len);
void
ibuf_rewind(struct ibuf *buf);
void *
ibuf_seek(struct ibuf *buf, size_t pos, size_t len);
int
ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len);
int
ibuf_set_h16(struct ibuf *buf, size_t pos, uint64_t value);
int
ibuf_set_h32(struct ibuf *buf, size_t pos, uint64_t value);
int
ibuf_set_h64(struct ibuf *buf, size_t pos, uint64_t value);
int
ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value);
int
ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value);
int
ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value);
int
ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value);
int
ibuf_set_maxsize(struct ibuf *buf, size_t max);
size_t
ibuf_size(const struct ibuf *buf);
int
ibuf_skip(struct ibuf *buf, size_t len);
int
ibuf_truncate(struct ibuf *buf, size_t len);
int
ibuf_write(int fd, struct msgbuf *msgbuf);
void
msgbuf_clear(struct msgbuf *msgbuf);
void
msgbuf_concat(struct msgbuf *msgbuf, struct ibufqueue *from);
void
msgbuf_free(struct msgbuf *msgbuf);
struct ibuf *
msgbuf_get(struct msgbuf *msgbuf);
struct msgbuf *
msgbuf_new(void);
struct msgbuf *
msgbuf_new_reader(size_t hdrsz, struct ibuf *(*readhdr)(struct ibuf *, void *, int *), void *arg);
uint32_t
msgbuf_queuelen(struct msgbuf *msgbuf);
int
msgbuf_read(int fd, struct msgbuf *msgbuf);
int
msgbuf_write(int fd, struct msgbuf *msgbuf);
void
ibufq_concat(struct ibufqueue *to, struct ibufqueue *from);
void
ibufq_flush(struct ibufqueue *bufq);
void
ibufq_free(struct ibufqueue *bufq);
struct ibufqueue *
ibufq_new(void);
struct ibuf *
ibufq_pop(struct ibufqueue *bufq);
void
ibufq_push(struct ibufqueue *bufq, struct ibuf *buf);
uint32_t
ibufq_queuelen(struct ibufqueue *bufq);

DESCRIPTION
The ibuf API defines functions to manipulate buffers, used for example to construct imsgs with imsg_create(3). A struct ibuf is a single buffer. It has a maximum size, a read and a write position. Buffers should be either constructed with the various ibuf_add() and ibuf_set() functions or consumed with the various ibuf_get() functions. A struct msgbuf is used to queue the output buffers for transmission.

ibuf_add() appends a block of data to buf. 0 is returned on success and -1 on failure.

ibuf_add_h16(), ibuf_add_h32(), and ibuf_add_h64() add a 2-byte, 4-byte, and 8-byte value to buf in host byte order. This function checks value to not overflow. 0 is returned on success and -1 on failure.

ibuf_add_ibuf() appends the buffer from to buf. 0 is returned on success and -1 on failure.

ibuf_add_n8(), ibuf_add_n16(), ibuf_add_n32(), and ibuf_add_n64() add a 1-byte, 2-byte, 4-byte, and 8-byte value to buf in network byte order. This function checks value to not overflow. 0 is returned on success and -1 on failure.

ibuf_add_strbuf() appends a fixed-size buffer containing a string, zero-padded to len, which must be large enough to allow at least one NUL. 0 is returned on success and -1 on failure.

ibuf_add_zero() appends a block of zeros to buf. 0 is returned on success and -1 on failure.

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

ibuf_data() returns the pointer to the internal buffer. This function should only be used together with ibuf_size() to process a previously generated buffer.

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

ibuf_fd_avail(), ibuf_fd_get() and ibuf_fd_set() are functions to check, get and set the file descriptor assigned to buf. After calling ibuf_fd_set() the file descriptor is part of the buf and will be transmitted or closed by the ibuf API. Any previously set file descriptor will be closed before assigning a new descriptor. ibuf_fd_get() returns the file descriptor and passes the responsibility to track the descriptor back to the program. ibuf_fd_avail() returns true if there is a file descriptor set on buf.

ibuf_free() frees buf and any associated storage, and closes any file descriptor set with ibuf_fd_set(). If buf is a NULL pointer, no action occurs.

ibuf_from_buffer() initializes the passed buf to point at data and spanning len bytes. The returned buffer can be read using the various ibuf_get() functions. ibuf_from_ibuf() duplicates the from ibuf into buf without modifying from. This allows safely peeking into an ibuf without consuming data.

ibuf_get() consumes a block of data from buf spanning len bytes. 0 is returned on success and -1 on failure.

ibuf_get_ibuf() consumes len bytes from the buffer buf and returns it in new covering this region. The data in this buffer is only valid as long as buf remains valid. There is no need to deallocate new using ibuf_free(). 0 is returned on success and -1 on failure.

ibuf_get_h16(), ibuf_get_h32(), and ibuf_get_h64() get a 2-byte, 4-byte, and 8-byte value from buf without altering byte order. 0 is returned on success and -1 on failure.

ibuf_get_n8(), ibuf_get_n16(), ibuf_get_n32(), and ibuf_get_n64() get a 1-byte, 2-byte, 4-byte, and 8-byte value from buf converting the value from network to host byte order. 0 is returned on success and -1 on failure.

ibuf_get_strbuf() copies len bytes from the buffer buf into str, ensuring that it is NUL-terminated. 0 is returned on success and -1 on failure.

ibuf_get_string() consumes len bytes from the buffer buf and returns the result of passing the bytes and len to strndup(3). The returned pointer should be passed to free(3) when it is no longer needed. On error NULL is returned.

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.

The ibuf_read() routine receives pending messages using read(2). It calls the readhdr() callback to obtain a struct ibuf of the appropriate size. It returns 1 on success, 0 if the connection was closed and -1 on error and the global variable errno is set to indicate the error. The errors EINTR and EAGAIN are treated as follows: EINTR will automatically retry the read operation while EAGAIN will be ignored with a 1 return. The application will then retry the operation at a later stage.

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_rewind() resets the read offset to the start of the buffer.

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

ibuf_set() replaces a part of buf at offset pos with the data of extent len. 0 is returned on success and -1 on failure.

ibuf_set_h16(), ibuf_set_h32() and ibuf_set_h64() replace a 2-byte, 4-byte or 8-byte value at offset pos in the buffer buf in host byte order. This function checks value to not overflow. 0 is returned on success and -1 on failure.

ibuf_set_n8(), ibuf_set_n16(), ibuf_set_n32() and ibuf_set_n64() replace a 1-byte, 2-byte, 4-byte or 8-byte value at offset pos in the buffer buf in network byte order. This function checks value to not overflow. 0 is returned on success and -1 on failure.

ibuf_set_maxsize() reduces the maximum payload of buf to max. 0 is returned on success and -1 on failure.

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

ibuf_skip() advances the read position in buf by len bytes. 0 is returned on success and -1 on failure.

ibuf_truncate() truncates the buffer to len bytes if necessary zero extending the buffer. 0 is returned on success and -1 on failure.

The ibuf_write() routine transmits as many pending buffers as possible from msgbuf using writev(2). It returns 0 if it succeeds, -1 on error and the global variable errno is set to indicate the error. The errors EINTR, EAGAIN, and ENOBUFS are treated as follows: EINTR will automatically retry the write operation while the other errors are ignored with a 0 return. The application will then retry the operation at a later stage.

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

msgbuf_concat() moves all queued buffers from the ibufqueue from to the msgbuf. Afterwards the ibufqueue from is empty.

msgbuf_free() function frees the msgbuf allocated by msgbuf_new() or msgbuf_new_reader(). msgbuf_get() returns the next pending message. It should be called in a loop until NULL is returned. The ibuf returned must be freed by calling ibuf_free.

msgbuf_new() allocates a new message buffer structure which can be used with ibuf_write() or msbuf_write(). On error NULL is returned.

msgbuf_new_reader() allocates a new message buffer structure which can additionally be used with ibuf_read() and msgbuf_read(). The hdrsz argument defines the size of the ibuf passed to the readhdr callback. The readhdr callback parses the header and returns a new struct ibuf of the size of the full message. It can take ownership of the file descriptor passed in its int * argument. It should return NULL on error and set the global variable errno appropriately. The arg pointer is passed to the readhdr callback. On error msgbuf_new_reader() returns NULL.

msgbuf_queuelen() returns the number of messages queued in msgbuf. This function returns 0 if no messages are pending for transmission.

The msgbuf_read() routine receives pending messages using recvmsg(2) and supports file descriptor passing. The function calls the readhdr() callback function to get the total size of message. It returns 1 on success, 0 if the connection was closed and -1 on error and the global variable errno is set to indicate the error. The errors EINTR and EAGAIN are treated as follows: EINTR will automatically retry the read operation while EAGAIN will be ignored with a 1 return. The application will then retry the operation at a later stage.

The msgbuf_write() routine calls sendmsg(2) to transmit buffers queued in msgbuf and supports file descriptor passing. It returns 0 if it succeeds, -1 on error and the global variable errno is set to indicate the error. The errors EINTR, EAGAIN, and ENOBUFS are treated as follows: EINTR will automatically retry the write operation while the other errors are ignored with a 0 return. The application will then retry the operation at a later stage.

The ibufqueue API can be used to implement additional buffer queues. This can be useful in multithreaded applications to pass ibufs between different threads.

ibufq_new() allocates a new ibufqueue. On error NULL is returned.

ibufq_free() frees a previously allocated ibufqueue. All queued ibufs are flushed before.

ibufq_flush() frees any queued buffer.

ibufq_push() and ibufq_pop() queue and dequeue ibufs onto the ibufqueue bufq.

ibufq_queuelen() returns the number of buffers enqueued on bufq.

ibufq_concat() moves all buffers from from to to.

SEE ALSO
socketpair(2), imsg_add(3), unix(4)