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.\" $FreeBSD$ 31.\" 32.Dd September 16, 2017 33.Dt NV 9 34.Os 35.Sh NAME 36.Nm nvlist_create , 37.Nm nvlist_destroy , 38.Nm nvlist_error , 39.Nm nvlist_set_error , 40.Nm nvlist_empty , 41.Nm nvlist_flags , 42.Nm nvlist_exists , 43.Nm nvlist_free , 44.Nm nvlist_clone , 45.Nm nvlist_dump , 46.Nm nvlist_fdump , 47.Nm nvlist_size , 48.Nm nvlist_pack , 49.Nm nvlist_unpack , 50.Nm nvlist_send , 51.Nm nvlist_recv , 52.Nm nvlist_xfer , 53.Nm nvlist_in_array , 54.Nm nvlist_next , 55.Nm nvlist_add , 56.Nm nvlist_move , 57.Nm nvlist_get , 58.Nm nvlist_take 59.Nd "library for name/value pairs" 60.Sh LIBRARY 61.Lb libnv 62.Sh SYNOPSIS 63.In sys/nv.h 64.Ft "nvlist_t *" 65.Fn nvlist_create "int flags" 66.Ft void 67.Fn nvlist_destroy "nvlist_t *nvl" 68.Ft int 69.Fn nvlist_error "const nvlist_t *nvl" 70.Ft void 71.Fn nvlist_set_error "nvlist_t *nvl" "int error" 72.Ft bool 73.Fn nvlist_empty "const nvlist_t *nvl" 74.Ft int 75.Fn nvlist_flags "const nvlist_t *nvl" 76.Ft bool 77.Fn nvlist_in_array "const nvlist_t *nvl" 78.\" 79.Ft "nvlist_t *" 80.Fn nvlist_clone "const nvlist_t *nvl" 81.\" 82.Ft void 83.Fn nvlist_dump "const nvlist_t *nvl" "int fd" 84.Ft void 85.Fn nvlist_fdump "const nvlist_t *nvl" "FILE *fp" 86.\" 87.Ft size_t 88.Fn nvlist_size "const nvlist_t *nvl" 89.Ft "void *" 90.Fn nvlist_pack "const nvlist_t *nvl" "size_t *sizep" 91.Ft "nvlist_t *" 92.Fn nvlist_unpack "const void *buf" "size_t size" "int flags" 93.\" 94.Ft int 95.Fn nvlist_send "int sock" "const nvlist_t *nvl" 96.Ft "nvlist_t *" 97.Fn nvlist_recv "int sock" "int flags" 98.Ft "nvlist_t *" 99.Fn nvlist_xfer "int sock" "nvlist_t *nvl" "int flags" 100.\" 101.Ft "const char *" 102.Fn nvlist_next "const nvlist_t *nvl" "int *typep" "void **cookiep" 103.\" 104.Ft bool 105.Fn nvlist_exists "const nvlist_t *nvl" "const char *name" 106.Ft bool 107.Fn nvlist_exists_type "const nvlist_t *nvl" "const char *name" "int type" 108.Ft bool 109.Fn nvlist_exists_null "const nvlist_t *nvl" "const char *name" 110.Ft bool 111.Fn nvlist_exists_bool "const nvlist_t *nvl" "const char *name" 112.Ft bool 113.Fn nvlist_exists_number "const nvlist_t *nvl" "const char *name" 114.Ft bool 115.Fn nvlist_exists_string "const nvlist_t *nvl" "const char *name" 116.Ft bool 117.Fn nvlist_exists_nvlist "const nvlist_t *nvl" "const char *name" 118.Ft bool 119.Fn nvlist_exists_descriptor "const nvlist_t *nvl" "const char *name" 120.Ft bool 121.Fn nvlist_exists_binary "const nvlist_t *nvl" "const char *name" 122.Ft bool 123.Fn nvlist_exists_bool_array "const nvlist_t *nvl" "const char *name" 124.Ft bool 125.Fn nvlist_exists_number_array "const nvlist_t *nvl" "const char *name" 126.Ft bool 127.Fn nvlist_exists_string_array "const nvlist_t *nvl" "const char *name" 128.Ft bool 129.Fn nvlist_exists_nvlist_array "const nvlist_t *nvl" "const char *name" 130.Ft bool 131.Fn nvlist_exists_descriptor_array "const nvlist_t *nvl" "const char *name" 132.\" 133.Ft void 134.Fn nvlist_add_null "nvlist_t *nvl" "const char *name" 135.Ft void 136.Fn nvlist_add_bool "nvlist_t *nvl" "const char *name" "bool value" 137.Ft void 138.Fn nvlist_add_number "nvlist_t *nvl" "const char *name" "uint64_t value" 139.Ft void 140.Fn nvlist_add_string "nvlist_t *nvl" "const char *name" "const char *value" 141.Ft void 142.Fn nvlist_add_stringf "nvlist_t *nvl" "const char *name" "const char *valuefmt" "..." 143.Ft void 144.Fn nvlist_add_stringv "nvlist_t *nvl" "const char *name" "const char *valuefmt" "va_list valueap" 145.Ft void 146.Fn nvlist_add_nvlist "nvlist_t *nvl" "const char *name" "const nvlist_t *value" 147.Ft void 148.Fn nvlist_add_descriptor "nvlist_t *nvl" "const char *name" "int value" 149.Ft void 150.Fn nvlist_add_binary "nvlist_t *nvl" "const char *name" "const void *value" "size_t size" 151.Ft void 152.Fn nvlist_add_bool_array "nvlist_t *nvl" "const char *name" "const bool *value" "size_t nitems" 153. 154.Ft void 155.Fn nvlist_add_number_array "nvlist_t *nvl" "const char *name" "const uint64_t *value" "size_t nitems" 156. 157.Ft void 158.Fn nvlist_add_string_array "nvlist_t *nvl" "const char *name" "const char * const * value" "size_t nitems" 159. 160.Ft void 161.Fn nvlist_add_nvlist_array "nvlist_t *nvl" "const char *name" "const nvlist_t * const * value" "size_t nitems" 162. 163.Ft void 164.Fn nvlist_add_descriptor_array "nvlist_t *nvl" "const char *name" "const int *value" "size_t nitems" 165.\" 166.Ft void 167.Fn nvlist_move_string "nvlist_t *nvl" "const char *name" "char *value" 168.Ft void 169.Fn nvlist_move_nvlist "nvlist_t *nvl" "const char *name" "nvlist_t *value" 170.Ft void 171.Fn nvlist_move_descriptor "nvlist_t *nvl" "const char *name" "int value" 172.Ft void 173.Fn nvlist_move_binary "nvlist_t *nvl" "const char *name" "void *value" "size_t size" 174.Ft void 175.Fn nvlist_move_bool_array "nvlist_t *nvl" "const char *name" "bool *value" "size_t nitems" 176. 177.Ft void 178.Fn nvlist_move_number_array "nvlist_t *nvl" "const char *name" "uint64_t *value" "size_t nitems" 179. 180.Ft void 181.Fn nvlist_move_string_array "nvlist_t *nvl" "const char *name" "char **value" "size_t nitems" 182. 183.Ft void 184.Fn nvlist_move_nvlist_array "nvlist_t *nvl" "const char *name" "nvlist_t **value" "size_t nitems" 185. 186.Ft void 187.Fn nvlist_move_descriptor_array "nvlist_t *nvl" "const char *name" "int *value" "size_t nitems" 188.\" 189.Ft bool 190.Fn nvlist_get_bool "const nvlist_t *nvl" "const char *name" 191.Ft uint64_t 192.Fn nvlist_get_number "const nvlist_t *nvl" "const char *name" 193.Ft "const char *" 194.Fn nvlist_get_string "const nvlist_t *nvl" "const char *name" 195.Ft "const nvlist_t *" 196.Fn nvlist_get_nvlist "const nvlist_t *nvl" "const char *name" 197.Ft int 198.Fn nvlist_get_descriptor "const nvlist_t *nvl" "const char *name" 199.Ft "const void *" 200.Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep" 201.Ft "const bool *" 202.Fn nvlist_get_bool_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 203.Ft "const uint64_t *" 204.Fn nvlist_get_number_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 205.Ft "const char * const *" 206.Fn nvlist_get_string_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 207.Ft "const nvlist_t * const *" 208.Fn nvlist_get_nvlist_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 209.Ft "const int *" 210.Fn nvlist_get_descriptor_array "const nvlist_t *nvl" "const char *name" "size_t *nitems" 211.Ft "const nvlist_t *" 212.Fn nvlist_get_parent "const nvlist_t *nvl" "void **cookiep" 213.Ft "const nvlist_t *" 214.Fn nvlist_get_array_next "const nvlist_t *nvl" 215.Ft "const nvlist_t *" 216.Fn nvlist_get_pararr "const nvlist_t *nvl" "void **cookiep" 217.\" 218.Ft bool 219.Fn nvlist_take_bool "nvlist_t *nvl" "const char *name" 220.Ft uint64_t 221.Fn nvlist_take_number "nvlist_t *nvl" "const char *name" 222.Ft "char *" 223.Fn nvlist_take_string "nvlist_t *nvl" "const char *name" 224.Ft "nvlist_t *" 225.Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name" 226.Ft int 227.Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name" 228.Ft "void *" 229.Fn nvlist_take_binary "nvlist_t *nvl" "const char *name" "size_t *sizep" 230.Ft "bool *" 231.Fn nvlist_take_bool_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 232.Ft "uint64_t **" 233.Fn nvlist_take_number_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 234.Ft "char **" 235.Fn nvlist_take_string_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 236.Ft "nvlist_t **" 237.Fn nvlist_take_nvlist_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 238.Ft "int *" 239.Fn nvlist_take_descriptor_array "nvlist_t *nvl" "const char *name" "size_t *nitems" 240.\" 241.Ft void 242.Fn nvlist_free "nvlist_t *nvl" "const char *name" 243.Ft void 244.Fn nvlist_free_type "nvlist_t *nvl" "const char *name" "int type" 245.\" 246.Ft void 247.Fn nvlist_free_null "nvlist_t *nvl" "const char *name" 248.Ft void 249.Fn nvlist_free_bool "nvlist_t *nvl" "const char *name" 250.Ft void 251.Fn nvlist_free_number "nvlist_t *nvl" "const char *name" 252.Ft void 253.Fn nvlist_free_string "nvlist_t *nvl" "const char *name" 254.Ft void 255.Fn nvlist_free_nvlist "nvlist_t *nvl" "const char *name" 256.Ft void 257.Fn nvlist_free_descriptor "nvlist_t *nvl" "const char *name" 258.Ft void 259.Fn nvlist_free_binary "nvlist_t *nvl" "const char *name" 260.Ft void 261.Fn nvlist_free_bool_array "nvlist_t *nvl" "const char *name" 262.Ft void 263.Fn nvlist_free_number_array "nvlist_t *nvl" "const char *name" 264.Ft void 265.Fn nvlist_free_string_array "nvlist_t *nvl" "const char *name" 266.Ft void 267.Fn nvlist_free_nvlist_array "nvlist_t *nvl" "const char *name" 268.Ft void 269.Fn nvlist_free_descriptor_array "nvlist_t *nvl" "const char *name" 270.Sh DESCRIPTION 271The 272.Nm libnv 273library allows to easily manage name value pairs as well as send and receive 274them over sockets. 275A group (list) of name value pairs is called an 276.Nm nvlist . 277The API supports the following data types: 278.Bl -ohang -offset indent 279.It Sy null ( NV_TYPE_NULL ) 280There is no data associated with the name. 281.It Sy bool ( NV_TYPE_BOOL ) 282The value can be either 283.Dv true 284or 285.Dv false . 286.It Sy number ( NV_TYPE_NUMBER ) 287The value is a number stored as 288.Vt uint64_t . 289.It Sy string ( NV_TYPE_STRING ) 290The value is a C string. 291.It Sy nvlist ( NV_TYPE_NVLIST ) 292The value is a nested nvlist. 293.It Sy descriptor ( NV_TYPE_DESCRIPTOR ) 294The value is a file descriptor. 295Note that file descriptors can be sent only over 296.Xr unix 4 297domain sockets. 298.It Sy binary ( NV_TYPE_BINARY ) 299The value is a binary buffer. 300.It Sy bool array ( NV_TYPE_BOOL_ARRAY ) 301The value is an array of boolean values. 302.It Sy number array ( NV_TYPE_NUMBER_ARRAY ) 303The value is an array of numbers, each stored as 304.Vt uint64_t . 305.It Sy string array ( NV_TYPE_STRING_ARRAY ) 306The value is an array of C strings. 307.It Sy nvlist array ( NV_TYPE_NVLIST_ARRAY ) 308The value is an array of nvlists. 309When an nvlist is added to an array, it becomes part of the primary nvlist. 310Traversing these arrays can be done using the 311.Fn nvlist_get_array_next 312and 313.Fn nvlist_get_pararr 314functions. 315.It Sy descriptor array ( NV_TYPE_DESCRIPTOR_ARRAY ) 316The value is an array of files descriptors. 317.El 318.Pp 319The 320.Fn nvlist_create 321function allocates memory and initializes an nvlist. 322.Pp 323The following flag can be provided: 324.Pp 325.Bl -tag -width "NV_FLAG_IGNORE_CASE" -compact -offset indent 326.It Dv NV_FLAG_IGNORE_CASE 327Perform case-insensitive lookups of provided names. 328.It Dv NV_FLAG_NO_UNIQUE 329Names in the nvlist do not have to be unique. 330.El 331.Pp 332The 333.Fn nvlist_destroy 334function destroys the given nvlist. 335Function does nothing if 336.Dv NULL 337nvlist is provided. 338Function never modifies the 339.Va errno 340global variable. 341.Pp 342The 343.Fn nvlist_error 344function returns any error value that the nvlist accumulated. 345If the given nvlist is 346.Dv NULL 347the 348.Er ENOMEM 349error will be returned. 350.Pp 351The 352.Fn nvlist_set_error 353function sets an nvlist to be in the error state. 354Subsequent calls to 355.Fn nvlist_error 356will return the given error value. 357This function cannot be used to clear the error state from an nvlist. 358This function does nothing if the nvlist is already in the error state. 359.Pp 360The 361.Fn nvlist_empty 362function returns 363.Dv true 364if the given nvlist is empty and 365.Dv false 366otherwise. 367The nvlist must not be in error state. 368.Pp 369The 370.Fn nvlist_flags 371function returns flags used to create the nvlist with the 372.Fn nvlist_create 373function. 374.Pp 375The 376.Fn nvlist_in_array 377function returns 378.Dv true 379if 380.Fa nvl 381is part of an array that is a member of another nvlist. 382.Pp 383The 384.Fn nvlist_clone 385functions clones the given nvlist. 386The clone shares no resources with its origin. 387This also means that all file descriptors that are part of the nvlist will be 388duplicated with the 389.Xr dup 2 390system call before placing them in the clone. 391.Pp 392The 393.Fn nvlist_dump 394dumps nvlist content for debugging purposes to the given file descriptor 395.Fa fd . 396.Pp 397The 398.Fn nvlist_fdump 399dumps nvlist content for debugging purposes to the given file stream 400.Fa fp . 401.Pp 402The 403.Fn nvlist_size 404function returns the size of the given nvlist after converting it to binary 405buffer with the 406.Fn nvlist_pack 407function. 408.Pp 409The 410.Fn nvlist_pack 411function converts the given nvlist to a binary buffer. 412The function allocates memory for the buffer, which should be freed with the 413.Xr free 3 414function. 415If the 416.Fa sizep 417argument is not 418.Dv NULL , 419the size of the buffer will be stored there. 420The function returns 421.Dv NULL 422in case of an error (allocation failure). 423If the nvlist contains any file descriptors 424.Dv NULL 425will be returned. 426The nvlist must not be in error state. 427.Pp 428The 429.Fn nvlist_unpack 430function converts the given buffer to the nvlist. 431The 432.Fa flags 433argument defines what type of the top level nvlist is expected to be. 434Flags are set up using the 435.Fn nvlist_create 436function. 437If the nvlist flags do not match the flags passed to 438.Fn nvlist_unpack , 439the nvlist will not be returned. 440Every nested nvlist list should be checked using 441.Fn nvlist_flags 442function. 443The function returns 444.Dv NULL 445in case of an error. 446.Pp 447The 448.Fn nvlist_send 449function sends the given nvlist over the socket given by the 450.Fa sock 451argument. 452Note that nvlist that contains file descriptors can only be send over 453.Xr unix 4 454domain sockets. 455.Pp 456The 457.Fn nvlist_recv 458function receives nvlist over the socket given by the 459.Fa sock 460argument. 461The 462.Fa flags 463argument defines what type of the top level nvlist is expected to be. 464Flags are set up using the 465.Fn nvlist_create 466function. 467If the nvlist flags do not match the flags passed to 468.Fn nvlist_recv , 469the nvlist will not be returned. 470Every nested nvlist list should be checked using 471.Fn nvlist_flags 472function. 473.Pp 474The 475.Fn nvlist_xfer 476function sends the given nvlist over the socket given by the 477.Fa sock 478argument and receives nvlist over the same socket. 479The 480.Fa flags 481argument defines what type of the top level nvlist is expected to be. 482Flags are set up using the 483.Fn nvlist_create 484function. 485If the nvlist flags do not match the flags passed to 486.Fn nvlist_xfer , 487the nvlist will not be returned. 488Every nested nvlist list should be checked using 489.Fn nvlist_flags 490function. 491The given nvlist is always destroyed. 492.Pp 493The 494.Fn nvlist_next 495function iterates over the given nvlist returning names and types of subsequent 496elements. 497The 498.Fa cookiep 499argument allows the function to figure out which element should be returned 500next. 501The 502.Va *cookiep 503should be set to 504.Dv NULL 505for the first call and should not be changed later. 506Returning 507.Dv NULL 508means there are no more elements on the nvlist. 509The 510.Fa typep 511argument can be NULL. 512Elements may not be removed from the nvlist while traversing it. 513The nvlist must not be in error state. 514Note that 515.Fn nvlist_next 516will handle 517.Va cookiep 518being set to 519.Dv NULL . 520In this case first element is returned or 521.Dv NULL 522if nvlist is empty. 523This behavior simplifies removing the first element from the list. 524.Pp 525The 526.Fn nvlist_exists 527function returns 528.Dv true 529if element of the given name exists (besides of its type) or 530.Dv false 531otherwise. 532The nvlist must not be in error state. 533.Pp 534The 535.Fn nvlist_exists_type 536function returns 537.Dv true 538if element of the given name and the given type exists or 539.Dv false 540otherwise. 541The nvlist must not be in error state. 542.Pp 543The 544.Fn nvlist_exists_null , 545.Fn nvlist_exists_bool , 546.Fn nvlist_exists_number , 547.Fn nvlist_exists_string , 548.Fn nvlist_exists_nvlist , 549.Fn nvlist_exists_descriptor , 550.Fn nvlist_exists_binary , 551.Fn nvlist_exists_bool_array , 552.Fn nvlist_exists_number_array , 553.Fn nvlist_exists_string_array , 554.Fn nvlist_exists_nvlist_array , 555.Fn nvlist_exists_descriptor_array 556functions return 557.Dv true 558if element of the given name and the given type determined by the function name 559exists or 560.Dv false 561otherwise. 562The nvlist must not be in error state. 563.Pp 564The 565.Fn nvlist_add_null , 566.Fn nvlist_add_bool , 567.Fn nvlist_add_number , 568.Fn nvlist_add_string , 569.Fn nvlist_add_stringf , 570.Fn nvlist_add_stringv , 571.Fn nvlist_add_nvlist , 572.Fn nvlist_add_descriptor , 573.Fn nvlist_add_binary , 574.Fn nvlist_add_bool_array , 575.Fn nvlist_add_number_array , 576.Fn nvlist_add_string_array , 577.Fn nvlist_add_nvlist_array , 578.Fn nvlist_add_descriptor_array 579functions add element to the given nvlist. 580When adding string or binary buffor the functions will allocate memory 581and copy the data over. 582When adding nvlist, the nvlist will be cloned and clone will be added. 583When adding descriptor, the descriptor will be duplicated using the 584.Xr dup 2 585system call and the new descriptor will be added. 586The array functions will fail if there are any 587.Dv NULL 588elements in the array, or if the array pointer is 589.Dv NULL . 590If an error occurs while adding new element, internal error is set which can be 591examined using the 592.Fn nvlist_error 593function. 594.Pp 595The 596.Fn nvlist_move_string , 597.Fn nvlist_move_nvlist , 598.Fn nvlist_move_descriptor , 599.Fn nvlist_move_binary , 600.Fn nvlist_move_bool_array , 601.Fn nvlist_move_number_array , 602.Fn nvlist_move_string_array , 603.Fn nvlist_move_nvlist_array , 604.Fn nvlist_move_descriptor_array 605functions add new element to the given nvlist, but unlike 606.Fn nvlist_add_<type> 607functions they will consume the given resource. 608In the case of strings, descriptors, or nvlists every elements must be 609unique, or it could cause a double free. 610The array functions will fail if there are any 611.Dv NULL 612elements, or if the array pointer is 613.Dv NULL . 614If an error occurs while adding new element, the resource is destroyed and 615internal error is set which can be examined using the 616.Fn nvlist_error 617function. 618.Pp 619The 620.Fn nvlist_get_bool , 621.Fn nvlist_get_number , 622.Fn nvlist_get_string , 623.Fn nvlist_get_nvlist , 624.Fn nvlist_get_descriptor , 625.Fn nvlist_get_binary , 626.Fn nvlist_get_bool_array , 627.Fn nvlist_get_number_array , 628.Fn nvlist_get_string_array , 629.Fn nvlist_get_nvlist_array , 630.Fn nvlist_get_descriptor_array 631functions return the value that corresponds to the given key name. 632In the case of strings, nvlists, descriptors, binary, or arrays, the returned 633resource should not be modified - they still belong to the nvlist. 634If an element of the given name does not exist, the program will be aborted. 635To avoid this, the caller should check for the existence of the name before 636trying to obtain the value, or use the 637.Xr dnvlist 3 638extension, which can provide a default value in the case of a missing element. 639The nvlist must not be in error state. 640.Pp 641The 642.Fn nvlist_get_parent 643function returns the parent nvlist of the nested nvlist. 644.Pp 645The 646.Fn nvlist_get_array_next 647function returns the next element from the array or 648.Dv NULL 649if the nvlist is not in array or it is the last element. 650Note that 651.Fn nvlist_get_array_next 652only works if you added the nvlist array using the 653.Fn nvlist_move_nvlist_array 654or 655.Fn nvlist_add_nvlist_array 656functions. 657.Pp 658The 659.Fn nvlist_get_pararr 660function returns the next element in the array, or if not available 661the parent of the nested nvlist. 662.Pp 663The 664.Fn nvlist_take_bool , 665.Fn nvlist_take_number , 666.Fn nvlist_take_string , 667.Fn nvlist_take_nvlist , 668.Fn nvlist_take_descriptor , 669.Fn nvlist_take_binary , 670.Fn nvlist_take_bool_array , 671.Fn nvlist_take_number_array , 672.Fn nvlist_take_string_array , 673.Fn nvlist_take_nvlist_array , 674.Fn nvlist_take_descriptor_array 675functions return value associated with the given name and remove the element 676from the nvlist. 677In case of string and binary values, the caller is responsible for free returned 678memory using the 679.Xr free 3 680function. 681In case of nvlist, the caller is responsible for destroying returned nvlist 682using the 683.Fn nvlist_destroy 684function. 685In case of descriptor, the caller is responsible for closing returned descriptor 686using the 687.Fn close 2 688system call. 689If an element of the given name does not exist, the program will be aborted. 690To avoid that the caller should check for the existence of the given name 691before trying to obtain the value, or use the 692.Xr dnvlist 3 693extension, which can provide a default value in the case of a missing element. 694In the case of an array of strings or binary values, the caller is responsible 695for freeing every element of the array using the 696.Xr free 3 697function. 698In the case of an array of nvlists, the caller is responsible for destroying 699every element of array using the 700.Fn nvlist_destroy 701function. 702In the case of descriptors, the caller is responsible for closing every 703element of array using the 704.Fn close 2 705system call. 706In every case involving an array, the caller must also free the pointer to 707the array using the 708.Xr free 3 709function. 710The nvlist must not be in error state. 711.Pp 712The 713.Fn nvlist_free 714function removes element of the given name from the nvlist (besides of its type) 715and frees all resources associated with it. 716If element of the given name does not exist, the program will be aborted. 717The nvlist must not be in error state. 718.Pp 719The 720.Fn nvlist_free_type 721function removes element of the given name and the given type from the nvlist 722and frees all resources associated with it. 723If element of the given name and the given type does not exist, the program 724will be aborted. 725The nvlist must not be in error state. 726.Pp 727The 728.Fn nvlist_free_null , 729.Fn nvlist_free_bool , 730.Fn nvlist_free_number , 731.Fn nvlist_free_string , 732.Fn nvlist_free_nvlist , 733.Fn nvlist_free_descriptor , 734.Fn nvlist_free_binary , 735.Fn nvlist_free_bool_array , 736.Fn nvlist_free_number_array , 737.Fn nvlist_free_string_array , 738.Fn nvlist_free_nvlist_array , 739.Fn nvlist_free_descriptor_array 740functions remove element of the given name and the given type determined by the 741function name from the nvlist and free all resources associated with it. 742If element of the given name and the given type does not exist, the program 743will be aborted. 744The nvlist must not be in error state. 745.Sh EXAMPLES 746The following example demonstrates how to prepare an nvlist and send it over 747.Xr unix 4 748domain socket. 749.Bd -literal 750nvlist_t *nvl; 751int fd; 752 753fd = open("/tmp/foo", O_RDONLY); 754if (fd < 0) 755 err(1, "open(\\"/tmp/foo\\") failed"); 756 757nvl = nvlist_create(0); 758/* 759 * There is no need to check if nvlist_create() succeeded, 760 * as the nvlist_add_<type>() functions can cope. 761 * If it failed, nvlist_send() will fail. 762 */ 763nvlist_add_string(nvl, "filename", "/tmp/foo"); 764nvlist_add_number(nvl, "flags", O_RDONLY); 765/* 766 * We just want to send the descriptor, so we can give it 767 * for the nvlist to consume (that's why we use nvlist_move 768 * not nvlist_add). 769 */ 770nvlist_move_descriptor(nvl, "fd", fd); 771if (nvlist_send(sock, nvl) < 0) { 772 nvlist_destroy(nvl); 773 err(1, "nvlist_send() failed"); 774} 775nvlist_destroy(nvl); 776.Ed 777.Pp 778Receiving nvlist and getting data: 779.Bd -literal 780nvlist_t *nvl; 781const char *command; 782char *filename; 783int fd; 784 785nvl = nvlist_recv(sock, 0); 786if (nvl == NULL) 787 err(1, "nvlist_recv() failed"); 788 789/* For command we take pointer to nvlist's buffer. */ 790command = nvlist_get_string(nvl, "command"); 791/* 792 * For filename we remove it from the nvlist and take 793 * ownership of the buffer. 794 */ 795filename = nvlist_take_string(nvl, "filename"); 796/* The same for the descriptor. */ 797fd = nvlist_take_descriptor(nvl, "fd"); 798 799printf("command=%s filename=%s fd=%d\n", command, filename, fd); 800 801nvlist_destroy(nvl); 802free(filename); 803close(fd); 804/* command was freed by nvlist_destroy() */ 805.Ed 806.Pp 807Iterating over nvlist: 808.Bd -literal 809nvlist_t *nvl; 810const char *name; 811void *cookie; 812int type; 813 814nvl = nvlist_recv(sock, 0); 815if (nvl == NULL) 816 err(1, "nvlist_recv() failed"); 817 818cookie = NULL; 819while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) { 820 printf("%s=", name); 821 switch (type) { 822 case NV_TYPE_NUMBER: 823 printf("%ju", (uintmax_t)nvlist_get_number(nvl, name)); 824 break; 825 case NV_TYPE_STRING: 826 printf("%s", nvlist_get_string(nvl, name)); 827 break; 828 default: 829 printf("N/A"); 830 break; 831 } 832 printf("\\n"); 833} 834.Ed 835.Pp 836Iterating over every nested nvlist: 837.Bd -literal 838nvlist_t *nvl; 839const char *name; 840void *cookie; 841int type; 842 843nvl = nvlist_recv(sock, 0); 844if (nvl == NULL) 845 err(1, "nvlist_recv() failed"); 846 847cookie = NULL; 848do { 849 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) { 850 if (type == NV_TYPE_NVLIST) { 851 nvl = nvlist_get_nvlist(nvl, name); 852 cookie = NULL; 853 } 854 } 855} while ((nvl = nvlist_get_parent(nvl, &cookie)) != NULL); 856.Ed 857.Pp 858Iterating over every nested nvlist and every nvlist element: 859.Bd -literal 860nvlist_t *nvl; 861const nvlist_t * const *array; 862const char *name; 863void *cookie; 864int type; 865 866nvl = nvlist_recv(sock, 0); 867if (nvl == null) 868 err(1, "nvlist_recv() failed"); 869 870cookie = null; 871do { 872 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) { 873 if (type == NV_TYPE_NVLIST) { 874 nvl = nvlist_get_nvlist(nvl, name); 875 cookie = NULL; 876 } else if (type == NV_TYPE_NVLIST_ARRAY) { 877 nvl = nvlist_get_nvlist_array(nvl, name, NULL)[0]; 878 cookie = NULL; 879 } 880 } 881} while ((nvl = nvlist_get_pararr(nvl, &cookie)) != NULL); 882.Ed 883.Pp 884Or alternatively: 885.Bd -literal 886nvlist_t *nvl, *tmp; 887const nvlist_t * const *array; 888const char *name; 889void *cookie; 890int type; 891 892nvl = nvlist_recv(sock, 0); 893if (nvl == null) 894 err(1, "nvlist_recv() failed"); 895 896cooke = NULL; 897tmp = nvl; 898do { 899 do { 900 nvl = tmp; 901 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) { 902 if (type == NV_TYPE_NVLIST) { 903 nvl = nvlist_get_nvlist(nvl, 904 name); 905 cookie = NULL; 906 } else if (type == NV_TYPE_NVLIST_ARRAY) { 907 nvl = nvlist_get_nvlist_array(nvl, name, 908 NULL)[0]; 909 cookie = NULL; 910 } 911 } 912 cookie = NULL; 913 } while ((tmp = nvlist_get_array_next(nvl)) != NULL); 914} while ((tmp = nvlist_get_parent(nvl, &cookie)) != NULL); 915.Ed 916.Sh SEE ALSO 917.Xr close 2 , 918.Xr dup 2 , 919.Xr open 2 , 920.Xr err 3 , 921.Xr free 3 , 922.Xr printf 3 , 923.Xr unix 4 924.Sh HISTORY 925The 926.Nm libnv 927library appeared in 928.Fx 11.0 . 929.Sh AUTHORS 930.An -nosplit 931The 932.Nm libnv 933library was implemented by 934.An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net 935under sponsorship from the FreeBSD Foundation. 936