2 .\" Copyright (c) 2013 The FreeBSD Foundation
3 .\" All rights reserved.
5 .\" This documentation was written by Pawel Jakub Dawidek under sponsorship
6 .\" the FreeBSD Foundation.
8 .\" Redistribution and use in source and binary forms, with or without
9 .\" modification, are permitted provided that the following conditions
11 .\" 1. Redistributions of source code must retain the above copyright
12 .\" notice, this list of conditions and the following disclaimer.
13 .\" 2. Redistributions in binary form must reproduce the above copyright
14 .\" notice, this list of conditions and the following disclaimer in the
15 .\" documentation and/or other materials provided with the distribution.
17 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 .Nm nvlist_set_error ,
57 .Nd "library for name/value pairs"
63 .Fn nvlist_create "int flags"
65 .Fn nvlist_destroy "nvlist_t *nvl"
67 .Fn nvlist_error "const nvlist_t *nvl"
69 .Fn nvlist_set_error "nvlist_t *nvl, int error"
71 .Fn nvlist_empty "const nvlist_t *nvl"
73 .Fn nvlist_flags "const nvlist_t *nvl"
76 .Fn nvlist_clone "const nvlist_t *nvl"
79 .Fn nvlist_dump "const nvlist_t *nvl, int fd"
81 .Fn nvlist_fdump "const nvlist_t *nvl, FILE *fp"
84 .Fn nvlist_size "const nvlist_t *nvl"
86 .Fn nvlist_pack "const nvlist_t *nvl" "size_t *sizep"
88 .Fn nvlist_unpack "const void *buf" "size_t size" "int flags"
91 .Fn nvlist_send "int sock" "const nvlist_t *nvl"
93 .Fn nvlist_recv "int sock" "int flags"
95 .Fn nvlist_xfer "int sock" "nvlist_t *nvl" "int flags"
98 .Fn nvlist_next "const nvlist_t *nvl" "int *typep" "void **cookiep"
101 .Fn nvlist_exists "const nvlist_t *nvl" "const char *name"
103 .Fn nvlist_exists_type "const nvlist_t *nvl" "const char *name" "int type"
105 .Fn nvlist_exists_null "const nvlist_t *nvl" "const char *name"
107 .Fn nvlist_exists_bool "const nvlist_t *nvl" "const char *name"
109 .Fn nvlist_exists_number "const nvlist_t *nvl" "const char *name"
111 .Fn nvlist_exists_string "const nvlist_t *nvl" "const char *name"
113 .Fn nvlist_exists_nvlist "const nvlist_t *nvl" "const char *name"
115 .Fn nvlist_exists_descriptor "const nvlist_t *nvl" "const char *name"
117 .Fn nvlist_exists_binary "const nvlist_t *nvl" "const char *name"
120 .Fn nvlist_add_null "nvlist_t *nvl" "const char *name"
122 .Fn nvlist_add_bool "nvlist_t *nvl" "const char *name" "bool value"
124 .Fn nvlist_add_number "nvlist_t *nvl" "const char *name" "uint64_t value"
126 .Fn nvlist_add_string "nvlist_t *nvl" "const char *name" "const char *value"
128 .Fn nvlist_add_stringf "nvlist_t *nvl" "const char *name" "const char *valuefmt" "..."
130 .Fn nvlist_add_stringv "nvlist_t *nvl" "const char *name" "const char *valuefmt" "va_list valueap"
132 .Fn nvlist_add_nvlist "nvlist_t *nvl" "const char *name" "const nvlist_t *value"
134 .Fn nvlist_add_descriptor "nvlist_t *nvl" "const char *name" "int value"
136 .Fn nvlist_add_binary "nvlist_t *nvl" "const char *name" "const void *value" "size_t size"
139 .Fn nvlist_move_string "nvlist_t *nvl" "const char *name" "char *value"
141 .Fn nvlist_move_nvlist "nvlist_t *nvl" "const char *name" "nvlist_t *value"
143 .Fn nvlist_move_descriptor "nvlist_t *nvl" "const char *name" "int value"
145 .Fn nvlist_move_binary "nvlist_t *nvl" "const char *name" "void *value" "size_t size"
148 .Fn nvlist_get_bool "const nvlist_t *nvl" "const char *name"
150 .Fn nvlist_get_number "const nvlist_t *nvl" "const char *name"
152 .Fn nvlist_get_string "const nvlist_t *nvl" "const char *name"
153 .Ft "const nvlist_t *"
154 .Fn nvlist_get_nvlist "const nvlist_t *nvl" "const char *name"
156 .Fn nvlist_get_descriptor "const nvlist_t *nvl" "const char *name"
158 .Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep"
159 .Ft "const nvlist_t *"
160 .Fn nvlist_get_parent "const nvlist_t *nvl" "void **cookiep"
163 .Fn nvlist_take_bool "nvlist_t *nvl" "const char *name"
165 .Fn nvlist_take_number "nvlist_t *nvl" "const char *name"
167 .Fn nvlist_take_string "nvlist_t *nvl" "const char *name"
169 .Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name"
171 .Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name"
173 .Fn nvlist_take_binary "nvlist_t *nvl" "const char *name" "size_t *sizep"
176 .Fn nvlist_free "nvlist_t *nvl" "const char *name"
178 .Fn nvlist_free_type "nvlist_t *nvl" "const char *name" "int type"
181 .Fn nvlist_free_null "nvlist_t *nvl" "const char *name"
183 .Fn nvlist_free_bool "nvlist_t *nvl" "const char *name"
185 .Fn nvlist_free_number "nvlist_t *nvl" "const char *name"
187 .Fn nvlist_free_string "nvlist_t *nvl" "const char *name"
189 .Fn nvlist_free_nvlist "nvlist_t *nvl" "const char *name"
191 .Fn nvlist_free_descriptor "nvlist_t *nvl" "const char *name"
193 .Fn nvlist_free_binary "nvlist_t *nvl" "const char *name"
197 library allows to easily manage name value pairs as well as send and receive
199 A group (list) of name value pairs is called an
201 The API supports the following data types:
202 .Bl -ohang -offset indent
203 .It Sy null ( NV_TYPE_NULL )
204 There is no data associated with the name.
205 .It Sy bool ( NV_TYPE_BOOL )
206 The value can be either
210 .It Sy number ( NV_TYPE_NUMBER )
211 The value is a number stored as
213 .It Sy string ( NV_TYPE_STRING )
214 The value is a C string.
215 .It Sy nvlist ( NV_TYPE_NVLIST )
216 The value is a nested nvlist.
217 .It Sy descriptor ( NV_TYPE_DESCRIPTOR )
218 The value is a file descriptor.
219 Note that file descriptors can be sent only over
222 .It Sy binary ( NV_TYPE_BINARY )
223 The value is a binary buffer.
228 function allocates memory and initializes an nvlist.
230 The following flag can be provided:
232 .Bl -tag -width "NV_FLAG_IGNORE_CASE" -compact -offset indent
233 .It Dv NV_FLAG_IGNORE_CASE
234 Perform case-insensitive lookups of provided names.
235 .It Dv NV_FLAG_NO_UNIQUE
236 Names in the nvlist do not have to be unique.
241 function destroys the given nvlist.
242 Function does nothing if
245 Function never modifies the
251 function returns any error value that the nvlist accumulated.
252 If the given nvlist is
256 error will be returned.
260 function sets an nvlist to be in the error state.
263 will return the given error value.
264 This function cannot be used to clear the error state from an nvlist.
265 This function does nothing if the nvlist is already in the error state.
271 if the given nvlist is empty and
274 The nvlist must not be in error state.
278 function returns flags used to create the nvlist with the
284 functions clones the given nvlist.
285 The clone shares no resources with its origin.
286 This also means that all file descriptors that are part of the nvlist will be
289 system call before placing them in the clone.
293 dumps nvlist content for debugging purposes to the given file descriptor
298 dumps nvlist content for debugging purposes to the given file stream
303 function returns the size of the given nvlist after converting it to binary
310 function converts the given nvlist to a binary buffer.
311 The function allocates memory for the buffer, which should be freed with the
318 the size of the buffer will be stored there.
321 in case of an error (allocation failure).
322 If the nvlist contains any file descriptors
325 The nvlist must not be in error state.
329 function converts the given buffer to the nvlist.
332 argument defines what type of the top level nvlist is expected to be.
333 Flags are set up using the
336 If the nvlist flags do not match the flags passed to
338 the nvlist will not be returned.
339 Every nested nvlist list should be checked using
348 function sends the given nvlist over the socket given by the
351 Note that nvlist that contains file descriptors can only be send over
357 function receives nvlist over the socket given by the
362 argument defines what type of the top level nvlist is expected to be.
363 Flags are set up using the
366 If the nvlist flags do not match the flags passed to
368 the nvlist will not be returned.
369 Every nested nvlist list should be checked using
375 function sends the given nvlist over the socket given by the
377 argument and receives nvlist over the same socket.
380 argument defines what type of the top level nvlist is expected to be.
381 Flags are set up using the
384 If the nvlist flags do not match the flags passed to
386 the nvlist will not be returned.
387 Every nested nvlist list should be checked using
390 The given nvlist is always destroyed.
394 function iterates over the given nvlist returning names and types of subsequent
398 argument allows the function to figure out which element should be returned
404 for the first call and should not be changed later.
407 means there are no more elements on the nvlist.
410 argument can be NULL.
411 Elements may not be removed from the nvlist while traversing it.
412 The nvlist must not be in error state.
418 if element of the given name exists (besides of its type) or
421 The nvlist must not be in error state.
424 .Fn nvlist_exists_type
427 if element of the given name and the given type exists or
430 The nvlist must not be in error state.
433 .Fn nvlist_exists_null ,
434 .Fn nvlist_exists_bool ,
435 .Fn nvlist_exists_number ,
436 .Fn nvlist_exists_string ,
437 .Fn nvlist_exists_nvlist ,
438 .Fn nvlist_exists_descriptor ,
439 .Fn nvlist_exists_binary
442 if element of the given name and the given type determined by the function name
446 The nvlist must not be in error state.
449 .Fn nvlist_add_null ,
450 .Fn nvlist_add_bool ,
451 .Fn nvlist_add_number ,
452 .Fn nvlist_add_string ,
453 .Fn nvlist_add_stringf ,
454 .Fn nvlist_add_stringv ,
455 .Fn nvlist_add_nvlist ,
456 .Fn nvlist_add_descriptor ,
457 .Fn nvlist_add_binary
458 functions add element to the given nvlist.
459 When adding string or binary buffor the functions will allocate memory
460 and copy the data over.
461 When adding nvlist, the nvlist will be cloned and clone will be added.
462 When adding descriptor, the descriptor will be duplicated using the
464 system call and the new descriptor will be added.
465 If an error occurs while adding new element, internal error is set which can be
471 .Fn nvlist_move_string ,
472 .Fn nvlist_move_nvlist ,
473 .Fn nvlist_move_descriptor ,
474 .Fn nvlist_move_binary
475 functions add new element to the given nvlist, but unlike
476 .Fn nvlist_add_<type>
477 functions they will consume the given resource.
478 If an error occurs while adding new element, the resource is destroyed and
479 internal error is set which can be examined using the
484 .Fn nvlist_get_bool ,
485 .Fn nvlist_get_number ,
486 .Fn nvlist_get_string ,
487 .Fn nvlist_get_nvlist ,
488 .Fn nvlist_get_descriptor ,
489 .Fn nvlist_get_binary
490 functions allow to obtain value of the given name.
491 In case of string, nvlist, descriptor or binary, returned resource should
492 not be modified - it still belongs to the nvlist.
493 If element of the given name does not exist, the program will be aborted.
494 To avoid that the caller should check for existence before trying to obtain
497 extension, which allows to provide default value for a missing element.
498 The nvlist must not be in error state.
501 .Fn nvlist_get_parent
502 function allows to obtain the parent nvlist from the nested nvlist.
505 .Fn nvlist_take_bool ,
506 .Fn nvlist_take_number ,
507 .Fn nvlist_take_string ,
508 .Fn nvlist_take_nvlist ,
509 .Fn nvlist_take_descriptor ,
510 .Fn nvlist_take_binary
511 functions return value associated with the given name and remove the element
513 In case of string and binary values, the caller is responsible for free returned
517 In case of nvlist, the caller is responsible for destroying returned nvlist
521 In case of descriptor, the caller is responsible for closing returned descriptor
525 If element of the given name does not exist, the program will be aborted.
526 To avoid that the caller should check for existence before trying to obtain
529 extension, which allows to provide default value for a missing element.
530 The nvlist must not be in error state.
534 function removes element of the given name from the nvlist (besides of its type)
535 and frees all resources associated with it.
536 If element of the given name does not exist, the program will be aborted.
537 The nvlist must not be in error state.
541 function removes element of the given name and the given type from the nvlist
542 and frees all resources associated with it.
543 If element of the given name and the given type does not exist, the program
545 The nvlist must not be in error state.
548 .Fn nvlist_free_null ,
549 .Fn nvlist_free_bool ,
550 .Fn nvlist_free_number ,
551 .Fn nvlist_free_string ,
552 .Fn nvlist_free_nvlist ,
553 .Fn nvlist_free_descriptor ,
554 .Fn nvlist_free_binary
555 functions remove element of the given name and the given type determined by the
556 function name from the nvlist and free all resources associated with it.
557 If element of the given name and the given type does not exist, the program
559 The nvlist must not be in error state.
561 The following example demonstrates how to prepare an nvlist and send it over
568 fd = open("/tmp/foo", O_RDONLY);
570 err(1, "open(\\"/tmp/foo\\") failed");
572 nvl = nvlist_create(0);
574 * There is no need to check if nvlist_create() succeeded,
575 * as the nvlist_add_<type>() functions can cope.
576 * If it failed, nvlist_send() will fail.
578 nvlist_add_string(nvl, "filename", "/tmp/foo");
579 nvlist_add_number(nvl, "flags", O_RDONLY);
581 * We just want to send the descriptor, so we can give it
582 * for the nvlist to consume (that's why we use nvlist_move
585 nvlist_move_descriptor(nvl, "fd", fd);
586 if (nvlist_send(sock, nvl) < 0) {
588 err(1, "nvlist_send() failed");
593 Receiving nvlist and getting data:
600 nvl = nvlist_recv(sock, 0);
602 err(1, "nvlist_recv() failed");
604 /* For command we take pointer to nvlist's buffer. */
605 command = nvlist_get_string(nvl, "command");
607 * For filename we remove it from the nvlist and take
608 * ownership of the buffer.
610 filename = nvlist_take_string(nvl, "filename");
611 /* The same for the descriptor. */
612 fd = nvlist_take_descriptor(nvl, "fd");
614 printf("command=%s filename=%s fd=%d\n", command, filename, fd);
619 /* command was freed by nvlist_destroy() */
622 Iterating over nvlist:
629 nvl = nvlist_recv(sock, 0);
631 err(1, "nvlist_recv() failed");
634 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
638 printf("%ju", (uintmax_t)nvlist_get_number(nvl, name));
641 printf("%s", nvlist_get_string(nvl, name));
651 Iterating over every nested nvlist:
658 nvl = nvlist_recv(sock, 0);
660 err(1, "nvlist_recv() failed");
664 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
665 if (type == NV_TYPE_NVLIST) {
666 nvl = nvlist_get_nvlist(nvl, name);
670 } while ((nvl = nvlist_get_parent(nvl, &cookie)) != NULL);
689 library was implemented by
690 .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net
691 under sponsorship from the FreeBSD Foundation.