1.\" 2.\" Copyright (c) 2013 The FreeBSD Foundation 3.\" Copyright (c) 2013-2015 Mariusz Zaborski <oshogbo@FreeBSD.org> 4.\" All rights reserved. 5.\" 6.\" This documentation was written by Pawel Jakub Dawidek under sponsorship 7.\" the FreeBSD Foundation. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" SUCH DAMAGE. 29.\" 30.Dd January 3, 2025 31.Dt NV 9 32.Os 33.Sh NAME 34.Nm nvlist_create , 35.Nm nvlist_destroy , 36.Nm nvlist_error , 37.Nm nvlist_set_error , 38.Nm nvlist_empty , 39.Nm nvlist_flags , 40.Nm nvlist_exists , 41.Nm nvlist_free , 42.Nm nvlist_clone , 43.Nm nvlist_dump , 44.Nm nvlist_fdump , 45.Nm nvlist_size , 46.Nm nvlist_pack , 47.Nm nvlist_unpack , 48.Nm nvlist_send , 49.Nm nvlist_recv , 50.Nm nvlist_xfer , 51.Nm nvlist_in_array , 52.Nm nvlist_next , 53.Nm nvlist_add , 54.Nm nvlist_move , 55.Nm nvlist_get , 56.Nm nvlist_take , 57.Nm nvlist_append 58.Nd "library for name/value pairs" 59.Sh LIBRARY 60.Lb libnv 61.Sh SYNOPSIS 62.In sys/nv.h 63.Ft "nvlist_t *" 64.Fn nvlist_create "int flags" 65.Ft void 66.Fn nvlist_destroy "nvlist_t *nvl" 67.Ft int 68.Fn nvlist_error "const nvlist_t *nvl" 69.Ft void 70.Fn nvlist_set_error "nvlist_t *nvl" "int error" 71.Ft bool 72.Fn nvlist_empty "const nvlist_t *nvl" 73.Ft int 74.Fn nvlist_flags "const nvlist_t *nvl" 75.Ft bool 76.Fn nvlist_in_array "const nvlist_t *nvl" 77.\" 78.Ft "nvlist_t *" 79.Fn nvlist_clone "const nvlist_t *nvl" 80.\" 81.Ft void 82.Fn nvlist_dump "const nvlist_t *nvl" "int fd" 83.Ft void 84.Fn nvlist_fdump "const nvlist_t *nvl" "FILE *fp" 85.\" 86.Ft size_t 87.Fn nvlist_size "const nvlist_t *nvl" 88.Ft "void *" 89.Fn nvlist_pack "const nvlist_t *nvl" "size_t *sizep" 90.Ft "nvlist_t *" 91.Fn nvlist_unpack "const void *buf" "size_t size" "int flags" 92.\" 93.Ft int 94.Fn nvlist_send "int sock" "const nvlist_t *nvl" 95.Ft "nvlist_t *" 96.Fn nvlist_recv "int sock" "int flags" 97.Ft "nvlist_t *" 98.Fn nvlist_xfer "int sock" "nvlist_t *nvl" "int flags" 99.\" 100.Ft "const char *" 101.Fn nvlist_next "const nvlist_t *nvl" "int *typep" "void **cookiep" 102.\" 103.Ft bool 104.Fn nvlist_exists "const nvlist_t *nvl" "const char *name" 105.Ft bool 106.Fn nvlist_exists_type "const nvlist_t *nvl" "const char *name" "int type" 107.Ft bool 108.Fn nvlist_exists_null "const nvlist_t *nvl" "const char *name" 109.Ft bool 110.Fn nvlist_exists_bool "const nvlist_t *nvl" "const char *name" 111.Ft bool 112.Fn nvlist_exists_number "const nvlist_t *nvl" "const char *name" 113.Ft bool 114.Fn nvlist_exists_string "const nvlist_t *nvl" "const char *name" 115.Ft bool 116.Fn nvlist_exists_nvlist "const nvlist_t *nvl" "const char *name" 117.Ft bool 118.Fn nvlist_exists_descriptor "const nvlist_t *nvl" "const char *name" 119.Ft bool 120.Fn nvlist_exists_binary "const nvlist_t *nvl" "const char *name" 121.Ft bool 122.Fn nvlist_exists_bool_array "const nvlist_t *nvl" "const char *name" 123.Ft bool 124.Fn nvlist_exists_number_array "const nvlist_t *nvl" "const char *name" 125.Ft bool 126.Fn nvlist_exists_string_array "const nvlist_t *nvl" "const char *name" 127.Ft bool 128.Fn nvlist_exists_nvlist_array "const nvlist_t *nvl" "const char *name" 129.Ft bool 130.Fn nvlist_exists_descriptor_array "const nvlist_t *nvl" "const char *name" 131.\" 132.Ft void 133.Fn nvlist_add_null "nvlist_t *nvl" "const char *name" 134.Ft void 135.Fn nvlist_add_bool "nvlist_t *nvl" "const char *name" "bool value" 136.Ft void 137.Fn nvlist_add_number "nvlist_t *nvl" "const char *name" "uint64_t value" 138.Ft void 139.Fn nvlist_add_string "nvlist_t *nvl" "const char *name" "const char *value" 140.Ft void 141.Fn nvlist_add_stringf "nvlist_t *nvl" "const char *name" "const char *valuefmt" "..." 142.Ft void 143.Fn nvlist_add_stringv "nvlist_t *nvl" "const char *name" "const char *valuefmt" "va_list valueap" 144.Ft void 145.Fn nvlist_add_nvlist "nvlist_t *nvl" "const char *name" "const nvlist_t *value" 146.Ft void 147.Fn nvlist_add_descriptor "nvlist_t *nvl" "const char *name" "int value" 148.Ft void 149.Fn nvlist_add_binary "nvlist_t *nvl" "const char *name" "const void *value" "size_t size" 150.Ft void 151.Fn nvlist_add_bool_array "nvlist_t *nvl" "const char *name" "const bool *value" "size_t nitems" 152. 153.Ft void 154.Fn nvlist_add_number_array "nvlist_t *nvl" "const char *name" "const uint64_t *value" "size_t nitems" 155. 156.Ft void 157.Fn nvlist_add_string_array "nvlist_t *nvl" "const char *name" "const char * const * value" "size_t nitems" 158. 159.Ft void 160.Fn nvlist_add_nvlist_array "nvlist_t *nvl" "const char *name" "const nvlist_t * const * value" "size_t nitems" 161. 162.Ft void 163.Fn nvlist_add_descriptor_array "nvlist_t *nvl" "const char *name" "const int *value" "size_t nitems" 164.\" 165.Ft void 166.Fn nvlist_move_string "nvlist_t *nvl" "const char *name" "char *value" 167.Ft void 168.Fn nvlist_move_nvlist "nvlist_t *nvl" "const char *name" "nvlist_t *value" 169.Ft void 170.Fn nvlist_move_descriptor "nvlist_t *nvl" "const char *name" "int value" 171.Ft void 172.Fn nvlist_move_binary "nvlist_t *nvl" "const char *name" "void *value" "size_t size" 173.Ft void 174.Fn nvlist_move_bool_array "nvlist_t *nvl" "const char *name" "bool *value" "size_t nitems" 175. 176.Ft void 177.Fn nvlist_move_number_array "nvlist_t *nvl" "const char *name" "uint64_t *value" "size_t nitems" 178. 179.Ft void 180.Fn nvlist_move_string_array "nvlist_t *nvl" "const char *name" "char **value" "size_t nitems" 181. 182.Ft void 183.Fn nvlist_move_nvlist_array "nvlist_t *nvl" "const char *name" "nvlist_t **value" "size_t nitems" 184. 185.Ft void 186.Fn nvlist_move_descriptor_array "nvlist_t *nvl" "const char *name" "int *value" "size_t nitems" 187.\" 188.Ft bool 189.Fn nvlist_get_bool "const nvlist_t *nvl" "const char *name" 190.Ft uint64_t 191.Fn nvlist_get_number "const nvlist_t *nvl" "const char *name" 192.Ft "const char *" 193.Fn nvlist_get_string "const nvlist_t *nvl" "const char *name" 194.Ft "const nvlist_t *" 195.Fn nvlist_get_nvlist "const nvlist_t *nvl" "const char *name" 196.Ft int 197.Fn nvlist_get_descriptor "const nvlist_t *nvl" "const char *name" 198.Ft "const void *" 199.Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep" 200.Ft "const bool *" 201.Fn nvlist_get_bool_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 202.Ft "const uint64_t *" 203.Fn nvlist_get_number_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 204.Ft "const char * const *" 205.Fn nvlist_get_string_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 206.Ft "const nvlist_t * const *" 207.Fn nvlist_get_nvlist_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 208.Ft "const int *" 209.Fn nvlist_get_descriptor_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 210.Ft "const nvlist_t *" 211.Fn nvlist_get_parent "const nvlist_t *nvl" "void **cookiep" 212.Ft "const nvlist_t *" 213.Fn nvlist_get_array_next "const nvlist_t *nvl" 214.Ft "const nvlist_t *" 215.Fn nvlist_get_pararr "const nvlist_t *nvl" "void **cookiep" 216.\" 217.Ft bool 218.Fn nvlist_take_bool "nvlist_t *nvl" "const char *name" 219.Ft uint64_t 220.Fn nvlist_take_number "nvlist_t *nvl" "const char *name" 221.Ft "char *" 222.Fn nvlist_take_string "nvlist_t *nvl" "const char *name" 223.Ft "nvlist_t *" 224.Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name" 225.Ft int 226.Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name" 227.Ft "void *" 228.Fn nvlist_take_binary "nvlist_t *nvl" "const char *name" "size_t *sizep" 229.Ft "bool *" 230.Fn nvlist_take_bool_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 231.Ft "uint64_t **" 232.Fn nvlist_take_number_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 233.Ft "char **" 234.Fn nvlist_take_string_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 235.Ft "nvlist_t **" 236.Fn nvlist_take_nvlist_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 237.Ft "int *" 238.Fn nvlist_take_descriptor_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 239.\" 240.Ft void 241.Fn nvlist_append_bool_array "nvlist_t *nvl" "const char *name" "const bool value" 242.Ft void 243.Fn nvlist_append_number_array "nvlist_t *nvl" "const char *name" "const uint64_t value" 244.Ft void 245.Fn nvlist_append_string_array "nvlist_t *nvl" "const char *name" "const char * const value" 246.Ft void 247.Fn nvlist_append_nvlist_array "nvlist_t *nvl" "const char *name" "const nvlist_t * const value" 248.Ft void 249.Fn nvlist_append_descriptor_array "nvlist_t *nvl" "const char *name" "int value" 250.\" 251.Ft void 252.Fn nvlist_free "nvlist_t *nvl" "const char *name" 253.Ft void 254.Fn nvlist_free_type "nvlist_t *nvl" "const char *name" "int type" 255.\" 256.Ft void 257.Fn nvlist_free_null "nvlist_t *nvl" "const char *name" 258.Ft void 259.Fn nvlist_free_bool "nvlist_t *nvl" "const char *name" 260.Ft void 261.Fn nvlist_free_number "nvlist_t *nvl" "const char *name" 262.Ft void 263.Fn nvlist_free_string "nvlist_t *nvl" "const char *name" 264.Ft void 265.Fn nvlist_free_nvlist "nvlist_t *nvl" "const char *name" 266.Ft void 267.Fn nvlist_free_descriptor "nvlist_t *nvl" "const char *name" 268.Ft void 269.Fn nvlist_free_binary "nvlist_t *nvl" "const char *name" 270.Ft void 271.Fn nvlist_free_bool_array "nvlist_t *nvl" "const char *name" 272.Ft void 273.Fn nvlist_free_number_array "nvlist_t *nvl" "const char *name" 274.Ft void 275.Fn nvlist_free_string_array "nvlist_t *nvl" "const char *name" 276.Ft void 277.Fn nvlist_free_nvlist_array "nvlist_t *nvl" "const char *name" 278.Ft void 279.Fn nvlist_free_descriptor_array "nvlist_t *nvl" "const char *name" 280.Sh DESCRIPTION 281The 282.Nm libnv 283library permits creating and managing name value pairs as well as 284sending and receiving 285them over sockets. 286A group (list) of name value pairs is called an 287.Nm nvlist . 288The API supports the following data types for values: 289.Bl -ohang -offset indent 290.It Sy null ( NV_TYPE_NULL ) 291There is no data associated with the name. 292.It Sy bool ( NV_TYPE_BOOL ) 293The value can be either 294.Dv true 295or 296.Dv false . 297.It Sy number ( NV_TYPE_NUMBER ) 298The value is a number stored as 299.Vt uint64_t . 300.It Sy string ( NV_TYPE_STRING ) 301The value is a C string. 302.It Sy nvlist ( NV_TYPE_NVLIST ) 303The value is a nested nvlist. 304.It Sy descriptor ( NV_TYPE_DESCRIPTOR ) 305The value is a file descriptor. 306Note that file descriptors can be sent only over 307.Xr unix 4 308domain sockets. 309.It Sy binary ( NV_TYPE_BINARY ) 310The value is a binary buffer. 311.It Sy bool array ( NV_TYPE_BOOL_ARRAY ) 312The value is an array of boolean values. 313.It Sy number array ( NV_TYPE_NUMBER_ARRAY ) 314The value is an array of numbers, each stored as 315.Vt uint64_t . 316.It Sy string array ( NV_TYPE_STRING_ARRAY ) 317The value is an array of C strings. 318.It Sy nvlist array ( NV_TYPE_NVLIST_ARRAY ) 319The value is an array of nvlists. 320When an nvlist is added to an array, it becomes part of the primary nvlist. 321Traversing these arrays can be done using the 322.Fn nvlist_get_array_next 323and 324.Fn nvlist_get_pararr 325functions. 326.It Sy descriptor array ( NV_TYPE_DESCRIPTOR_ARRAY ) 327The value is an array of files descriptors. 328.El 329.Pp 330The 331.Fn nvlist_create 332function allocates memory and initializes an nvlist. 333.Pp 334The following flags can be provided: 335.Pp 336.Bl -tag -width "NV_FLAG_IGNORE_CASE" -compact -offset indent 337.It Dv NV_FLAG_IGNORE_CASE 338Perform case-insensitive lookups of provided names. 339.It Dv NV_FLAG_NO_UNIQUE 340Names in the nvlist do not have to be unique. 341.El 342.Pp 343The 344.Fn nvlist_destroy 345function destroys the given nvlist. 346This function does nothing if 347.Fa nvl 348is 349.Dv NULL . 350This function never modifies 351.Va errno . 352.Pp 353The 354.Fn nvlist_error 355function returns the first error set on 356.Fa nvl . 357If 358.Fa nvl 359is not in the error state, 360this function returns zero. 361If 362.Fa nvl 363is 364.Dv NULL , 365.Er ENOMEM 366is returned. 367.Pp 368The 369.Fn nvlist_set_error 370function sets an the error value for 371.Fa nvl . 372Subsequent calls to 373.Fn nvlist_error 374will return 375.Fa error . 376This function cannot be used to clear the error state from an nvlist. 377This function does nothing if the nvlist is already in the error state. 378.Pp 379The 380.Fn nvlist_empty 381function returns 382.Dv true 383if 384.Fa nvl 385is empty and 386.Dv false 387otherwise. 388The nvlist must not be in the error state. 389.Pp 390The 391.Fn nvlist_flags 392function returns the flags used to create 393.Fa nvl 394with the 395.Fn nvlist_create , 396.Fn nvlist_recv , 397.Fn nvlist_unpack , 398or 399.Fn nvlist_xfer 400functions. 401.Pp 402The 403.Fn nvlist_in_array 404function returns 405.Dv true 406if 407.Fa nvl 408is part of an array that is a member of another nvlist. 409.Pp 410The 411.Fn nvlist_clone 412function clones 413.Fa nvl . 414The clone shares no resources with its origin. 415This also means that all file descriptors that are part of the nvlist will be 416duplicated with the 417.Xr dup 2 418system call before placing them in the clone. 419.Pp 420The 421.Fn nvlist_dump 422function dumps nvlist content for debugging purposes to the file descriptor 423.Fa fd . 424.Pp 425The 426.Fn nvlist_fdump 427dumps nvlist content for debugging purposes to the file stream 428.Fa fp . 429.Pp 430The 431.Fn nvlist_size 432function returns the size of the binary buffer that would be generated by the 433.Fn nvlist_pack 434function. 435.Pp 436The 437.Fn nvlist_pack 438function converts the given nvlist to a binary buffer. 439The function allocates memory for the buffer which should be freed with the 440.Xr free 3 441function. 442If the 443.Fa sizep 444argument is not 445.Dv NULL , 446the size of the buffer is stored there. 447This function returns 448.Dv NULL 449in case of an error (allocation failure). 450If the nvlist contains any file descriptors 451.Dv NULL 452will be returned. 453The nvlist must not be in the error state. 454.Pp 455The 456.Fn nvlist_unpack 457function converts a binary buffer to a new nvlist. 458The 459.Fa flags 460argument has the same meaning as the 461.Fa flags 462argument passed to 463.Fn nvlist_create . 464If 465.Fa flags 466do not match the flags used to create the initial nvlist before it was packed, 467this function will fail. 468The flags of nested nvlists are not validated by this function. 469The caller is responsible for validating the flags on any nested nvlists using 470.Fn nvlist_flags . 471This function returns the new nvlist on success or 472.Dv NULL 473in case of an error. 474.Pp 475The 476.Fn nvlist_send 477function sends 478.Fa nvl 479over the socket 480.Fa sock . 481Note that nvlists that contain file descriptors can only be sent over 482.Xr unix 4 483domain sockets. 484.Pp 485The 486.Fn nvlist_recv 487function receives an nvlist over the socket 488.Fa sock . 489As with 490.Fn nvlist_unpack , 491the 492.Fa flags 493argument is used to construct the new nvlist and must match the flags used 494to construct the original nvlist written to 495.Fa sock 496by the peer. 497The flags of nested nvlists are not validated by this function. 498The caller is responsible for validating the flags on any nested nvlists using 499.Fn nvlist_flags . 500This function returns the new nvlist on success or 501.Dv NULL 502in case of an error. 503.Pp 504The 505.Fn nvlist_xfer 506function sends 507.Fa nvl 508over the socket 509.Fa sock 510argument and then receives a new nvlist over the same socket. 511The 512.Fa flags 513argument applies to the new nvlist similar to 514.Fn nvlist_recv . 515The nvlist 516.Fa nvl 517is always destroyed. 518This function returns the new nvlist on success or 519.Dv NULL 520in case of an error. 521.Pp 522The 523.Fn nvlist_next 524function iterates over 525.Fa nvl 526returning the names and types of subsequent 527elements. 528The 529.Fa cookiep 530argument determines which element is returned. 531If 532.Va *cookiep 533is 534.Dv NULL , 535the values for the first element in the list are returned. 536Otherwise, 537.Va *cookiep 538should contain the result of a prior call to 539.Fn nvlist_next 540in which case values for the next element from 541.Fa nvl 542are returned. 543This function returns 544.Dv NULL 545when there are no more elements on 546.Fa nvl . 547The 548.Fa typep 549argument can be 550.Dv NULL . 551Elements may not be removed from 552.Fa nvl 553the nvlist while traversing it. 554.Fa nvl 555must not be in the error state. 556Additional actions can be performed on an element identified by a cookie 557via the 558.Xr cnv 9 559API . 560.Pp 561The 562.Fn nvlist_exists 563function returns 564.Dv true 565if an element named 566.Fa name 567exists in 568.Fa nvl 569(regardless of type) or 570.Dv false 571otherwise. 572The nvlist must not be in the error state. 573.Pp 574The 575.Fn nvlist_exists_type 576function returns 577.Dv true 578if an element named 579.Fa name 580of type 581.Fa type 582exists or 583.Dv false 584otherwise. 585The nvlist must not be in the error state. 586.Pp 587The 588.Fn nvlist_exists_null , 589.Fn nvlist_exists_bool , 590.Fn nvlist_exists_number , 591.Fn nvlist_exists_string , 592.Fn nvlist_exists_nvlist , 593.Fn nvlist_exists_descriptor , 594.Fn nvlist_exists_binary , 595.Fn nvlist_exists_bool_array , 596.Fn nvlist_exists_number_array , 597.Fn nvlist_exists_string_array , 598.Fn nvlist_exists_nvlist_array , 599.Fn nvlist_exists_descriptor_array 600functions return 601.Dv true 602if element named 603.Fa name 604with the type determined by the function name 605exists or 606.Dv false 607otherwise. 608The nvlist must not be in the error state. 609.Pp 610The 611.Fn nvlist_add_null , 612.Fn nvlist_add_bool , 613.Fn nvlist_add_number , 614.Fn nvlist_add_string , 615.Fn nvlist_add_stringf , 616.Fn nvlist_add_stringv , 617.Fn nvlist_add_nvlist , 618.Fn nvlist_add_descriptor , 619.Fn nvlist_add_binary , 620.Fn nvlist_add_bool_array , 621.Fn nvlist_add_number_array , 622.Fn nvlist_add_string_array , 623.Fn nvlist_add_nvlist_array , 624.Fn nvlist_add_descriptor_array 625functions add an element to 626.Fa nvl . 627When adding a string or binary buffer, these functions allocate memory 628and copy the data. 629When adding an nvlist, the 630.Fa value 631nvlist is cloned and the clone is added to 632.Fa nvl . 633When adding a file descriptor, the descriptor is duplicated via the 634.Xr dup 2 635system call and the new file descriptor is added. 636The array functions fail if there are any 637.Dv NULL 638elements in the array, or if the array pointer is 639.Dv NULL . 640If an error occurs while adding a new element, 641an internal error is set which can be 642examined using the 643.Fn nvlist_error 644function. 645.Pp 646The 647.Fn nvlist_move_string , 648.Fn nvlist_move_nvlist , 649.Fn nvlist_move_descriptor , 650.Fn nvlist_move_binary , 651.Fn nvlist_move_bool_array , 652.Fn nvlist_move_number_array , 653.Fn nvlist_move_string_array , 654.Fn nvlist_move_nvlist_array , 655.Fn nvlist_move_descriptor_array 656functions add an element to 657.Fa nvl , 658but unlike the 659.Fn nvlist_add_<type> 660functions they consume the given resource. 661For string, file descriptor, binary buffer, or nvlist values, 662no value should be moved into an nvlist multiple times; 663doing so will cause that value to be freed multiple times. 664Note that strings or binary buffers must be allocated with 665.Xr malloc 3 , 666and the pointers will be released via 667.Xr free 3 668when 669.Fa nvl 670is destroyed. 671The array functions fail if there are any 672.Dv NULL 673elements, or if the array pointer is 674.Dv NULL . 675If an error occurs while adding new element, the resource is destroyed and 676an internal error is set which can be examined using the 677.Fn nvlist_error 678function. 679.Pp 680The 681.Fn nvlist_get_bool , 682.Fn nvlist_get_number , 683.Fn nvlist_get_string , 684.Fn nvlist_get_nvlist , 685.Fn nvlist_get_descriptor , 686.Fn nvlist_get_binary , 687.Fn nvlist_get_bool_array , 688.Fn nvlist_get_number_array , 689.Fn nvlist_get_string_array , 690.Fn nvlist_get_nvlist_array , 691.Fn nvlist_get_descriptor_array 692functions return the value of the first element in 693.Fa nvl 694named 695.Fa name . 696For string, nvlist, file descriptor, binary buffer, or array values, 697the returned resource must not be modified - it still belongs to 698.Fa nvl . 699.Pp 700If an element named 701.Fa name 702does not exist, the program aborts. 703To avoid this, the caller should check for the existence of the element before 704trying to obtain the value or use the 705.Xr dnv 9 706extension which provides a default value in the case of a missing element. 707.Pp 708The nvlist must not be in the error state. 709.Pp 710The 711.Fn nvlist_get_parent 712function returns the parent nvlist of 713.Fa nvl . 714.Pp 715The 716.Fn nvlist_get_array_next 717function returns the next element after 718.Fa nvl 719from an array of nvlists. 720If 721.Fa nvl 722is not in an array of nvlists or it is the last element, 723this function returns 724.Dv NULL . 725An nvlist is only in an nvlist array if it was added to an nvlist array using 726.Fn nvlist_add_nvlist_array , 727.Fn nvlist_append_nvlist_array , 728or 729.Fn nvlist_move_nvlist_array . 730.Pp 731The 732.Fn nvlist_get_pararr 733function returns the next element after 734.Fn nvl 735from an array of nvlists. 736If 737.Fn nvl 738is the last element in an array of nvlists, 739the parent nvlist of 740.Fa nvl is 741returned. 742If 743.Fn nvl 744is not in an array of nvlists, 745.Dv NULL 746is returned. 747.Pp 748The 749.Fn nvlist_take_bool , 750.Fn nvlist_take_number , 751.Fn nvlist_take_string , 752.Fn nvlist_take_nvlist , 753.Fn nvlist_take_descriptor , 754.Fn nvlist_take_binary , 755.Fn nvlist_take_bool_array , 756.Fn nvlist_take_number_array , 757.Fn nvlist_take_string_array , 758.Fn nvlist_take_nvlist_array , 759.Fn nvlist_take_descriptor_array 760functions return the value of the element named 761.Fa name 762and remove the element from 763.Fa nvl . 764For string and binary buffer values, the caller is responsible for freeing 765the returned value using the 766.Xr free 3 767function. 768For nvlist values, the caller is responsible for destroying the returned nvlist 769using the 770.Fn nvlist_destroy 771function. 772For file descriptor values, the caller is responsible for closing the 773returned descriptor 774using the 775.Fn close 2 776system call. 777For array values, the caller is responsible for destroying every element of 778the array based on the element type. 779In addition, the caller must also free the pointer to the array using the 780.Xr free 3 781function. 782.Pp 783If an element named 784.Fa name 785does not exist, the program aborts. 786To avoid this, the caller should check for the existence of the element before 787trying to obtain the value or use the 788.Xr dnv 9 789extension which provides a default value in the case of a missing element. 790.Pp 791The nvlist must not be in the error state. 792.Pp 793The 794.Fn nvlist_append_bool_array , 795.Fn nvlist_append_number_array , 796.Fn nvlist_append_string_array , 797.Fn nvlist_append_nvlist_array , 798.Fn nvlist_append_descriptor_array 799functions append an element to an existing array using the same semantics 800as the add functions (that is, the element will be copied when applicable). 801If the array named 802.Fa name 803does not exist, then it will be created 804as if using the 805.Fn nvlist_add_<type>_array 806function. 807If an error occurs while appending a new element, 808an internal error is set on 809.Fa nvl . 810.Pp 811The 812.Fn nvlist_free 813function removes the first element named 814.Fa name 815from 816.Fa nvl 817(regardless of type) 818and frees all resources associated with it. 819If no element named 820.Fa name 821exists, the program aborts. 822The nvlist must not be in the error state. 823.Pp 824The 825.Fn nvlist_free_type 826function removes the first element named 827.Fa name 828of type 829.Fa type 830from 831.Fa nvl 832and frees all resources associated with it. 833If no element named 834.Fa name 835of type 836.Fa type 837exists, the program aborts. 838The nvlist must not be in the error state. 839.Pp 840The 841.Fn nvlist_free_null , 842.Fn nvlist_free_bool , 843.Fn nvlist_free_number , 844.Fn nvlist_free_string , 845.Fn nvlist_free_nvlist , 846.Fn nvlist_free_descriptor , 847.Fn nvlist_free_binary , 848.Fn nvlist_free_bool_array , 849.Fn nvlist_free_number_array , 850.Fn nvlist_free_string_array , 851.Fn nvlist_free_nvlist_array , 852.Fn nvlist_free_descriptor_array 853functions remove the first element named 854.Fa name 855with the type determined by the function name from 856.Fa nvl 857free all resources associated with it. 858If no element named 859.Fa name 860with the appropriate type exists, the program aborts. 861The nvlist must not be in the error state. 862.Ss Notes 863The 864.Fn nvlist_pack 865and 866.Fn nvlist_unpack 867functions handle byte-order conversions, so binary buffers can be 868packed and unpacked on hosts with different endianness. 869.Pp 870The 871.Fn nvlist_recv , 872.Fn nvlist_send , 873and 874.Fn nvlist_xfer 875functions can transfer nvlists between hosts with different endianness. 876.Ss Kernel Considerations 877The 878.Nm nv , 879.Nm cnv , 880and 881.Nm dnv 882APIs can be used in the kernel with the following differences: 883.Bl -bullet 884.It 885File descriptor and file descriptor array value types are not supported. 886.It 887.Fn nvlist_recv , 888.Fn nvlist_send , 889and 890.Fn nvlist_xfer 891are not supported. 892.It 893All memory allocations use the 894.Dv M_NVLIST 895memory type with 896.Xr malloc 9 897and 898.Xr free 9 . 899As a result, any allocated buffers moved into an nvlist must be allocated with 900.Dv M_NVLIST , 901and buffers returned by functions such as 902.Fn nvlist_pack 903must be freed with 904.Dv M_NVLIST . 905.El 906.Sh EXAMPLES 907The following example demonstrates how to prepare an nvlist and send it over a 908.Xr unix 4 909domain socket. 910.Bd -literal 911nvlist_t *nvl; 912int fd; 913 914fd = open("/tmp/foo", O_RDONLY); 915if (fd < 0) 916 err(1, "open(\\"/tmp/foo\\") failed"); 917 918nvl = nvlist_create(0); 919 920/* 921 * There is no need to check if nvlist_create() succeeded 922 * as the nvlist_add_<type>() functions can cope. 923 * If it failed, nvlist_send() will fail. 924 */ 925nvlist_add_string(nvl, "filename", "/tmp/foo"); 926nvlist_add_number(nvl, "flags", O_RDONLY); 927 928/* 929 * We just want to send the descriptor, so we can give it 930 * for the nvlist to consume (that is why we use nvlist_move 931 * not nvlist_add). 932 */ 933nvlist_move_descriptor(nvl, "fd", fd); 934if (nvlist_send(sock, nvl) < 0) { 935 nvlist_destroy(nvl); 936 err(1, "nvlist_send() failed"); 937} 938nvlist_destroy(nvl); 939.Ed 940.Pp 941Receiving an nvlist and retrieving element values: 942.Bd -literal 943nvlist_t *nvl; 944const char *command; 945char *filename; 946int fd; 947 948nvl = nvlist_recv(sock, 0); 949if (nvl == NULL) 950 err(1, "nvlist_recv() failed"); 951 952/* For command we accept a pointer to the nvlist's internal buffer. */ 953command = nvlist_get_string(nvl, "command"); 954 955/* 956 * For filename we remove it from the nvlist and take 957 * ownership of the buffer. 958 */ 959filename = nvlist_take_string(nvl, "filename"); 960 961/* The same for the file descriptor. */ 962fd = nvlist_take_descriptor(nvl, "fd"); 963 964printf("command=%s filename=%s fd=%d\n", command, filename, fd); 965 966/* command is freed by nvlist_destroy() */ 967nvlist_destroy(nvl); 968free(filename); 969close(fd); 970.Ed 971.Pp 972Iterating over an nvlist: 973.Bd -literal 974nvlist_t *nvl; 975const char *name; 976void *cookie; 977int type; 978 979nvl = nvlist_recv(sock, 0); 980if (nvl == NULL) 981 err(1, "nvlist_recv() failed"); 982 983cookie = NULL; 984while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) { 985 printf("%s=", name); 986 switch (type) { 987 case NV_TYPE_NUMBER: 988 printf("%ju", (uintmax_t)nvlist_get_number(nvl, name)); 989 break; 990 case NV_TYPE_STRING: 991 printf("%s", nvlist_get_string(nvl, name)); 992 break; 993 default: 994 printf("N/A"); 995 break; 996 } 997 printf("\\n"); 998} 999.Ed 1000.Pp 1001Iterating over every nested nvlist: 1002.Bd -literal 1003nvlist_t *nvl; 1004const char *name; 1005void *cookie; 1006int type; 1007 1008nvl = nvlist_recv(sock, 0); 1009if (nvl == NULL) 1010 err(1, "nvlist_recv() failed"); 1011 1012cookie = NULL; 1013do { 1014 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) { 1015 if (type == NV_TYPE_NVLIST) { 1016 nvl = nvlist_get_nvlist(nvl, name); 1017 cookie = NULL; 1018 } 1019 } 1020} while ((nvl = nvlist_get_parent(nvl, &cookie)) != NULL); 1021.Ed 1022.Pp 1023Iterating over every nested nvlist and every nvlist element: 1024.Bd -literal 1025nvlist_t *nvl; 1026const nvlist_t * const *array; 1027const char *name; 1028void *cookie; 1029int type; 1030 1031nvl = nvlist_recv(sock, 0); 1032if (nvl == null) 1033 err(1, "nvlist_recv() failed"); 1034 1035cookie = NULL; 1036do { 1037 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) { 1038 if (type == NV_TYPE_NVLIST) { 1039 nvl = nvlist_get_nvlist(nvl, name); 1040 cookie = NULL; 1041 } else if (type == NV_TYPE_NVLIST_ARRAY) { 1042 nvl = nvlist_get_nvlist_array(nvl, name, NULL)[0]; 1043 cookie = NULL; 1044 } 1045 } 1046} while ((nvl = nvlist_get_pararr(nvl, &cookie)) != NULL); 1047.Ed 1048.Pp 1049Or alternatively: 1050.Bd -literal 1051nvlist_t *nvl, *tmp; 1052const nvlist_t * const *array; 1053const char *name; 1054void *cookie; 1055int type; 1056 1057nvl = nvlist_recv(sock, 0); 1058if (nvl == null) 1059 err(1, "nvlist_recv() failed"); 1060 1061cooke = NULL; 1062tmp = nvl; 1063do { 1064 do { 1065 nvl = tmp; 1066 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) { 1067 if (type == NV_TYPE_NVLIST) { 1068 nvl = nvlist_get_nvlist(nvl, name); 1069 cookie = NULL; 1070 } else if (type == NV_TYPE_NVLIST_ARRAY) { 1071 nvl = nvlist_get_nvlist_array(nvl, name, 1072 NULL)[0]; 1073 cookie = NULL; 1074 } 1075 } 1076 cookie = NULL; 1077 } while ((tmp = nvlist_get_array_next(nvl)) != NULL); 1078} while ((tmp = nvlist_get_parent(nvl, &cookie)) != NULL); 1079.Ed 1080.Sh SEE ALSO 1081.Xr close 2 , 1082.Xr dup 2 , 1083.Xr open 2 , 1084.Xr err 3 , 1085.Xr free 3 , 1086.Xr printf 3 , 1087.Xr unix 4 1088.Sh HISTORY 1089The 1090.Nm libnv 1091library appeared in 1092.Fx 11.0 . 1093.Sh AUTHORS 1094.An -nosplit 1095The 1096.Nm libnv 1097library was implemented by 1098.An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net 1099under sponsorship from the FreeBSD Foundation. 1100