1.\" $OpenBSD: ibuf_add.3,v 1.1 2023/12/12 15:49:21 claudio Exp $ 2.\" 3.\" Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org> 4.\" Copyright (c) 2010 Nicholas Marriott <nicm@openbsd.org> 5.\" 6.\" Permission to use, copy, modify, and distribute this software for any 7.\" purpose with or without fee is hereby granted, provided that the above 8.\" copyright notice and this permission notice appear in all copies. 9.\" 10.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14.\" WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17.\" 18.Dd $Mdocdate: December 12 2023 $ 19.Dt IBUF_ADD 3 20.Os 21.Sh NAME 22.Nm ibuf_add , 23.Nm ibuf_add_ibuf , 24.Nm ibuf_add_h16 , 25.Nm ibuf_add_h32 , 26.Nm ibuf_add_h64 , 27.Nm ibuf_add_n16 , 28.Nm ibuf_add_n32 , 29.Nm ibuf_add_n64 , 30.Nm ibuf_add_n8 , 31.Nm ibuf_add_zero , 32.Nm ibuf_close , 33.Nm ibuf_data , 34.Nm ibuf_dynamic , 35.Nm ibuf_fd_avail , 36.Nm ibuf_fd_get , 37.Nm ibuf_fd_set , 38.Nm ibuf_free , 39.Nm ibuf_from_buffer , 40.Nm ibuf_from_ibuf , 41.Nm ibuf_get , 42.Nm ibuf_get_ibuf , 43.Nm ibuf_get_h16 , 44.Nm ibuf_get_h32 , 45.Nm ibuf_get_h64 , 46.Nm ibuf_get_n16 , 47.Nm ibuf_get_n32 , 48.Nm ibuf_get_n64 , 49.Nm ibuf_get_n8 , 50.Nm ibuf_left , 51.Nm ibuf_open , 52.Nm ibuf_reserve , 53.Nm ibuf_rewind , 54.Nm ibuf_seek , 55.Nm ibuf_set , 56.Nm ibuf_set_h16 , 57.Nm ibuf_set_h32 , 58.Nm ibuf_set_h64 , 59.Nm ibuf_set_n16 , 60.Nm ibuf_set_n32 , 61.Nm ibuf_set_n64 , 62.Nm ibuf_set_n8 , 63.Nm ibuf_size , 64.Nm ibuf_skip , 65.Nm ibuf_truncate , 66.Nm ibuf_write , 67.Nm msgbuf_clear , 68.Nm msgbuf_init , 69.Nm msgbuf_queuelen , 70.Nm msgbuf_write 71.Nd save buffer API for basic IO 72.Sh SYNOPSIS 73.In sys/queue.h 74.In imsg.h 75.Ft int 76.Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len" 77.Ft int 78.Fn ibuf_add_ibuf "struct ibuf *buf" "const struct ibuf *from" 79.Ft int 80.Fn ibuf_add_h16 "struct ibuf *buf" "uint64_t value" 81.Ft int 82.Fn ibuf_add_h32 "struct ibuf *buf" "uint64_t value" 83.Ft int 84.Fn ibuf_add_h64 "struct ibuf *buf" "uint64_t value" 85.Ft int 86.Fn ibuf_add_n16 "struct ibuf *buf" "uint64_t value" 87.Ft int 88.Fn ibuf_add_n32 "struct ibuf *buf" "uint64_t value" 89.Ft int 90.Fn ibuf_add_n64 "struct ibuf *buf" "uint64_t value" 91.Ft int 92.Fn ibuf_add_n8 "struct ibuf *buf" "uint64_t value" 93.Ft int 94.Fn ibuf_add_zero "struct ibuf *buf" "size_t len" 95.Ft void 96.Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf" 97.Ft "void *" 98.Fn ibuf_data "struct ibuf *buf" 99.Ft "struct ibuf *" 100.Fn ibuf_dynamic "size_t len" "size_t max" 101.Ft int 102.Fn ibuf_fd_avail "struct ibuf *buf" 103.Ft int 104.Fn ibuf_fd_get "struct ibuf *buf" 105.Ft void 106.Fn ibuf_fd_set "struct ibuf *buf" "int fd" 107.Ft void 108.Fn ibuf_free "struct ibuf *buf" 109.Ft void 110.Fn ibuf_from_buffer "struct ibuf *buf" "void *data" "size_t len" 111.Ft void 112.Fn ibuf_from_ibuf "struct ibuf *buf" "const ibuf *from" 113.Ft int 114.Fn ibuf_get "struct ibuf *buf" "void *data" "size_t len" 115.Ft int 116.Fn ibuf_get_ibuf "struct ibuf *buf" "size_t len" "struct ibuf *new" 117.Ft int 118.Fn ibuf_get_h16 "struct ibuf *buf" "uint16_t *value" 119.Ft int 120.Fn ibuf_get_h32 "struct ibuf *buf" "uint32_t *value" 121.Ft int 122.Fn ibuf_get_h64 "struct ibuf *buf" "uint64_t *value" 123.Ft int 124.Fn ibuf_get_n16 "struct ibuf *buf" "uint16_t *value" 125.Ft int 126.Fn ibuf_get_n32 "struct ibuf *buf" "uint32_t *value" 127.Ft int 128.Fn ibuf_get_n64 "struct ibuf *buf" "uint64_t *value" 129.Ft int 130.Fn ibuf_get_n8 "struct ibuf *buf" "uint8_t *value" 131.Ft size_t 132.Fn ibuf_left "const struct ibuf *buf" 133.Ft "struct ibuf *" 134.Fn ibuf_open "size_t len" 135.Ft "void *" 136.Fn ibuf_reserve "struct ibuf *buf" "size_t len" 137.Ft void 138.Fn ibuf_rewind "struct ibuf *buf" 139.Ft "void *" 140.Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len" 141.Ft int 142.Fn ibuf_set "struct ibuf *buf" "size_t pos" "const void *data" \ 143 "size_t len" 144.Ft int 145.Fn ibuf_set_h16 "struct ibuf *buf" "size_t pos" "uint64_t value" 146.Ft int 147.Fn ibuf_set_h32 "struct ibuf *buf" "size_t pos" "uint64_t value" 148.Ft int 149.Fn ibuf_set_h64 "struct ibuf *buf" "size_t pos" "uint64_t value" 150.Ft int 151.Fn ibuf_set_n16 "struct ibuf *buf" "size_t pos" "uint64_t value" 152.Ft int 153.Fn ibuf_set_n32 "struct ibuf *buf" "size_t pos" "uint64_t value" 154.Ft int 155.Fn ibuf_set_n64 "struct ibuf *buf" "size_t pos" "uint64_t value" 156.Ft int 157.Fn ibuf_set_n8 "struct ibuf *buf" "size_t pos" "uint64_t value" 158.Ft size_t 159.Fn ibuf_size "const struct ibuf *buf" 160.Ft int 161.Fn ibuf_skip "struct ibuf *buf" "size_t len" 162.Ft int 163.Fn ibuf_truncate "struct ibuf *buf" "size_t len" 164.Ft int 165.Fn ibuf_write "struct msgbuf *msgbuf" 166.Ft void 167.Fn msgbuf_init "struct msgbuf *msgbuf" 168.Ft void 169.Fn msgbuf_clear "struct msgbuf *msgbuf" 170.Ft uint32_t 171.Fn msgbuf_queuelen "struct msgbuf *msgbuf" 172.Ft int 173.Fn msgbuf_write "struct msgbuf *msgbuf" 174.Sh DESCRIPTION 175The ibuf API defines functions to manipulate buffers, used for example to 176construct imsgs with 177.Xr imsg_create 3 . 178A 179.Vt struct ibuf 180is a single buffer. 181It has a maximum size, a read and a write position. 182Buffers should be either constructed with the various 183.Fn ibuf_add 184and 185.Fn ibuf_set 186functions or consumed with the various 187.Fn ibuf_get 188functions. 189A 190.Vt struct msgbuf 191is used to queue the output buffers for transmission. 192.Pp 193.Fn ibuf_add 194appends a block of data to 195.Fa buf . 1960 is returned on success and \-1 on failure. 197.Pp 198.Fn ibuf_add_ibuf 199appends the buffer 200.Fa from 201to 202.Fa buf . 2030 is returned on success and \-1 on failure. 204.Pp 205.Fn ibuf_add_h16 , 206.Fn ibuf_add_h32 , 207and 208.Fn ibuf_add_h64 209add a 2-byte, 4-byte, and 8-byte 210.Fa value 211to 212.Fa buf 213in host byte order. 214This function checks 215.Fa value 216to not overflow. 2170 is returned on success and \-1 on failure. 218.Pp 219.Fn ibuf_add_n8 , 220.Fn ibuf_add_n16 , 221.Fn ibuf_add_n32 , 222and 223.Fn ibuf_add_n64 224add a 1-byte, 2-byte, 4-byte, and 8-byte 225.Fa value 226to 227.Fa buf 228in network byte order. 229This function checks 230.Fa value 231to not overflow. 2320 is returned on success and \-1 on failure. 233.Pp 234.Fn ibuf_add_zero 235appends a block of zeros to 236.Fa buf . 2370 is returned on success and \-1 on failure. 238.Pp 239.Fn ibuf_close 240appends 241.Fa buf 242to 243.Fa msgbuf 244ready to be sent. 245.Pp 246.Fn ibuf_data 247returns the pointer to the internal buffer. 248This function should only be used together with 249.Fn ibuf_size 250to process a previously generated buffer. 251.Pp 252.Fn ibuf_dynamic 253allocates a resizeable buffer of initial length 254.Fa len 255and maximum size 256.Fa max . 257Buffers allocated with 258.Fn ibuf_dynamic 259are automatically grown if necessary when data is added. 260.Pp 261.Fn ibuf_fd_avail , 262.Fn ibuf_fd_get 263and 264.Fn ibuf_fd_set 265are functions to check, get and set the file descriptor assigned to 266.Fa buf . 267After calling 268.Fn ibuf_fd_set 269the file descriptor is part of the 270.Fa buf 271and will be transmitted or closed by the ibuf API. 272Any previously set file descriptor will be closed before assigning a 273new descriptor. 274.Fn ibuf_fd_get 275returns the file descriptor and passes the responsibility to track the 276descriptor back to the program. 277.Fn ibuf_fd_avail 278returns true if there is a file descriptor set on 279.Fa buf . 280.Pp 281.Fn ibuf_free 282frees 283.Fa buf 284and any associated storage, and closes any file descriptor set with 285.Fn ibuf_fd_set . 286If 287.Fa buf 288is a NULL pointer, no action occurs. 289.Pp 290.Fn ibuf_from_buffer 291initializes the passed 292.Fa buf 293to point at 294.Fa data 295and spanning 296.Fa len 297bytes. 298The returned buffer can be read using the various 299.Fn ibuf_get 300functions . 301.Fn ibuf_from_ibuf 302duplicates the 303.Fa from 304ibuf into 305.Fa buf 306without modifying 307.Fa from . 308This allows safely peeking into an ibuf without consuming data. 309.Pp 310.Fn ibuf_get 311consumes a block of data from 312.Fa buf 313spanning 314.Fa len 315bytes. 3160 is returned on success and \-1 on failure. 317.Pp 318.Fn ibuf_get_ibuf 319consumes 320.Fa len 321bytes from the buffer 322.Fa buf 323and returns it in 324.Fa new 325covering this region. 326The data in this buffer is only valid as long as 327.Fa buf 328remains valid . 329There is no need to deallocate 330.Fa new 331using 332.Fn ibuf_free . 3330 is returned on success and \-1 on failure. 334.Pp 335.Fn ibuf_get_h16 , 336.Fn ibuf_get_h32 , 337and 338.Fn ibuf_get_h64 339get a 2-byte, 4-byte, and 8-byte 340.Fa value 341from 342.Fa buf 343without altering byte order. 3440 is returned on success and \-1 on failure. 345.Pp 346.Fn ibuf_get_n8 , 347.Fn ibuf_get_n16 , 348.Fn ibuf_get_n32 , 349and 350.Fn ibuf_get_n64 351get a 1-byte, 2-byte, 4-byte, and 8-byte 352.Fa value 353from 354.Fa buf 355converting the value from network to host byte order. 3560 is returned on success and \-1 on failure. 357.Pp 358The 359.Fn ibuf_open 360function allocates a fixed-length buffer. 361The buffer may not be resized and may contain a maximum of 362.Fa len 363bytes. 364On success 365.Fn ibuf_open 366returns a pointer to the buffer; on failure it returns NULL. 367.Pp 368.Fn ibuf_reserve 369is used to reserve 370.Fa len 371bytes in 372.Fa buf . 373A pointer to the start of the reserved space is returned, or NULL on error. 374.Pp 375.Fn ibuf_rewind 376resets the read offset to the start of the buffer. 377.Pp 378.Fn ibuf_seek 379returns a pointer to the part of the buffer at offset 380.Fa pos 381and of extent 382.Fa len . 383NULL is returned if the requested range is outside the part of the buffer 384in use. 385.Pp 386.Fn ibuf_set 387replaces a part of 388.Fa buf 389at offset 390.Fa pos 391with the 392.Fa data 393of extent 394.Fa len . 3950 is returned on success and \-1 on failure. 396.Pp 397.Fn ibuf_set_h16 , 398.Fn ibuf_set_h32 399and 400.Fn ibuf_set_h64 401replace a 2-byte, 4-byte or 8-byte 402.Fa value 403at offset 404.Fa pos 405in the buffer 406.Fa buf 407in host byte order. 408This function checks 409.Fa value 410to not overflow. 4110 is returned on success and \-1 on failure. 412.Pp 413.Fn ibuf_set_n8 , 414.Fn ibuf_set_n16 , 415.Fn ibuf_set_n32 416and 417.Fn ibuf_set_n64 418replace a 1-byte, 2-byte, 4-byte or 8-byte 419.Fa value 420at offset 421.Fa pos 422in the buffer 423.Fa buf 424in network byte order. 425This function checks 426.Fa value 427to not overflow. 4280 is returned on success and \-1 on failure. 429.Pp 430.Fn ibuf_size 431and 432.Fn ibuf_left 433are functions which return the total bytes used and available in 434.Fa buf , 435respectively. 436.Pp 437.Fn ibuf_skip 438advances the read position in 439.Fa buf 440by 441.Fa len 442bytes. 4430 is returned on success and \-1 on failure. 444.Pp 445.Fn ibuf_truncate 446truncates the buffer to 447.Fa len 448bytes if necessary zero extending the buffer. 4490 is returned on success and \-1 on failure. 450.Pp 451The 452.Fn ibuf_write 453routine transmits as many pending buffers as possible from 454.Fa msgbuf 455using 456.Xr writev 2 . 457It returns 1 if it succeeds, \-1 on error and 0 when no buffers were 458pending or an EOF condition on the socket is detected. 459Temporary resource shortages are returned with errno 460.Er EAGAIN 461and require the application to retry again in the future. 462.Pp 463The 464.Fn msgbuf_init 465function initializes 466.Fa msgbuf 467so that buffers may be appended to it. 468The 469.Fa fd 470member should also be set directly before 471.Fn msgbuf_write 472is used. 473.Pp 474.Fn msgbuf_clear 475empties a msgbuf, removing and discarding any queued buffers. 476.Pp 477.Fn msgbuf_queuelen 478returns the number of messages queued in 479.Fa msgbuf . 480This function returns 0 if no messages are pending for transmission. 481.Pp 482The 483.Fn msgbuf_write 484routine calls 485.Xr sendmsg 2 486to transmit buffers queued in 487.Fa msgbuf . 488It returns 1 if it succeeds, \-1 on error, and 0 when the queue was empty 489or an EOF condition on the socket is detected. 490Temporary resource shortages are returned with errno 491.Er EAGAIN 492and require the application to retry again in the future. 493.Sh SEE ALSO 494.Xr socketpair 2 , 495.Xr imsg_init 3 , 496.Xr unix 4 497