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"
91 .Fn nvlist_send "int sock" "const nvlist_t *nvl"
93 .Fn nvlist_recv "int sock"
95 .Fn nvlist_xfer "int sock" "nvlist_t *nvl"
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.
239 function destroys the given nvlist.
240 Function does nothing if
243 Function never modifies the
249 function returns any error value that the nvlist accumulated.
250 If the given nvlist is
254 error will be returned.
258 function sets an nvlist to be in the error state.
261 will return the given error value.
262 This function cannot be used to clear the error state from an nvlist.
263 This function does nothing if the nvlist is already in the error state.
269 if the given nvlist is empty and
272 The nvlist must not be in error state.
276 function returns flags used to create the nvlist with the
282 functions clones the given nvlist.
283 The clone shares no resources with its origin.
284 This also means that all file descriptors that are part of the nvlist will be
287 system call before placing them in the clone.
291 dumps nvlist content for debugging purposes to the given file descriptor
296 dumps nvlist content for debugging purposes to the given file stream
301 function returns the size of the given nvlist after converting it to binary
308 function converts the given nvlist to a binary buffer.
309 The function allocates memory for the buffer, which should be freed with the
316 the size of the buffer will be stored there.
319 in case of an error (allocation failure).
320 If the nvlist contains any file descriptors
323 The nvlist must not be in error state.
327 function converts the given buffer to the nvlist.
334 function sends the given nvlist over the socket given by the
337 Note that nvlist that contains file descriptors can only be send over
343 function receives nvlist over the socket given by the
349 function sends the given nvlist over the socket given by the
351 argument and receives nvlist over the same socket.
352 The given nvlist is always destroyed.
356 function iterates over the given nvlist returning names and types of subsequent
360 argument allows the function to figure out which element should be returned
366 for the first call and should not be changed later.
369 means there are no more elements on the nvlist.
372 argument can be NULL.
373 Elements may not be removed from the nvlist while traversing it.
374 The nvlist must not be in error state.
380 if element of the given name exists (besides of its type) or
383 The nvlist must not be in error state.
386 .Fn nvlist_exists_type
389 if element of the given name and the given type exists or
392 The nvlist must not be in error state.
395 .Fn nvlist_exists_null ,
396 .Fn nvlist_exists_bool ,
397 .Fn nvlist_exists_number ,
398 .Fn nvlist_exists_string ,
399 .Fn nvlist_exists_nvlist ,
400 .Fn nvlist_exists_descriptor ,
401 .Fn nvlist_exists_binary
404 if element of the given name and the given type determined by the function name
408 The nvlist must not be in error state.
411 .Fn nvlist_add_null ,
412 .Fn nvlist_add_bool ,
413 .Fn nvlist_add_number ,
414 .Fn nvlist_add_string ,
415 .Fn nvlist_add_stringf ,
416 .Fn nvlist_add_stringv ,
417 .Fn nvlist_add_nvlist ,
418 .Fn nvlist_add_descriptor ,
419 .Fn nvlist_add_binary
420 functions add element to the given nvlist.
421 When adding string or binary buffor the functions will allocate memory
422 and copy the data over.
423 When adding nvlist, the nvlist will be cloned and clone will be added.
424 When adding descriptor, the descriptor will be duplicated using the
426 system call and the new descriptor will be added.
427 If an error occurs while adding new element, internal error is set which can be
433 .Fn nvlist_move_string ,
434 .Fn nvlist_move_nvlist ,
435 .Fn nvlist_move_descriptor ,
436 .Fn nvlist_move_binary
437 functions add new element to the given nvlist, but unlike
438 .Fn nvlist_add_<type>
439 functions they will consume the given resource.
440 If an error occurs while adding new element, the resource is destroyed and
441 internal error is set which can be examined using the
446 .Fn nvlist_get_bool ,
447 .Fn nvlist_get_number ,
448 .Fn nvlist_get_string ,
449 .Fn nvlist_get_nvlist ,
450 .Fn nvlist_get_descriptor ,
451 .Fn nvlist_get_binary
452 functions allow to obtain value of the given name.
453 In case of string, nvlist, descriptor or binary, returned resource should
454 not be modified - it still belongs to the nvlist.
455 If element of the given name does not exist, the program will be aborted.
456 To avoid that the caller should check for existence before trying to obtain
459 extension, which allows to provide default value for a missing element.
460 The nvlist must not be in error state.
463 .Fn nvlist_get_parent
464 function allows to obtain the parent nvlist from the nested nvlist.
467 .Fn nvlist_take_bool ,
468 .Fn nvlist_take_number ,
469 .Fn nvlist_take_string ,
470 .Fn nvlist_take_nvlist ,
471 .Fn nvlist_take_descriptor ,
472 .Fn nvlist_take_binary
473 functions return value associated with the given name and remove the element
475 In case of string and binary values, the caller is responsible for free returned
479 In case of nvlist, the caller is responsible for destroying returned nvlist
483 In case of descriptor, the caller is responsible for closing returned descriptor
487 If element of the given name does not exist, the program will be aborted.
488 To avoid that the caller should check for existence before trying to obtain
491 extension, which allows to provide default value for a missing element.
492 The nvlist must not be in error state.
496 function removes element of the given name from the nvlist (besides of its type)
497 and frees all resources associated with it.
498 If element of the given name does not exist, the program will be aborted.
499 The nvlist must not be in error state.
503 function removes element of the given name and the given type from the nvlist
504 and frees all resources associated with it.
505 If element of the given name and the given type does not exist, the program
507 The nvlist must not be in error state.
510 .Fn nvlist_free_null ,
511 .Fn nvlist_free_bool ,
512 .Fn nvlist_free_number ,
513 .Fn nvlist_free_string ,
514 .Fn nvlist_free_nvlist ,
515 .Fn nvlist_free_descriptor ,
516 .Fn nvlist_free_binary
517 functions remove element of the given name and the given type determined by the
518 function name from the nvlist and free all resources associated with it.
519 If element of the given name and the given type does not exist, the program
521 The nvlist must not be in error state.
523 The following example demonstrates how to prepare an nvlist and send it over
530 fd = open("/tmp/foo", O_RDONLY);
532 err(1, "open(\\"/tmp/foo\\") failed");
534 nvl = nvlist_create(0);
536 * There is no need to check if nvlist_create() succeeded,
537 * as the nvlist_add_<type>() functions can cope.
538 * If it failed, nvlist_send() will fail.
540 nvlist_add_string(nvl, "filename", "/tmp/foo");
541 nvlist_add_number(nvl, "flags", O_RDONLY);
543 * We just want to send the descriptor, so we can give it
544 * for the nvlist to consume (that's why we use nvlist_move
547 nvlist_move_descriptor(nvl, "fd", fd);
548 if (nvlist_send(sock, nvl) < 0) {
550 err(1, "nvlist_send() failed");
555 Receiving nvlist and getting data:
562 nvl = nvlist_recv(sock);
564 err(1, "nvlist_recv() failed");
566 /* For command we take pointer to nvlist's buffer. */
567 command = nvlist_get_string(nvl, "command");
569 * For filename we remove it from the nvlist and take
570 * ownership of the buffer.
572 filename = nvlist_take_string(nvl, "filename");
573 /* The same for the descriptor. */
574 fd = nvlist_take_descriptor(nvl, "fd");
576 printf("command=%s filename=%s fd=%d\n", command, filename, fd);
581 /* command was freed by nvlist_destroy() */
584 Iterating over nvlist:
591 nvl = nvlist_recv(sock);
593 err(1, "nvlist_recv() failed");
596 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
600 printf("%ju", (uintmax_t)nvlist_get_number(nvl, name));
603 printf("%s", nvlist_get_string(nvl, name));
613 Iterating over every nested nvlist:
620 nvl = nvlist_recv(sock);
622 err(1, "nvlist_recv() failed");
626 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
627 if (type == NV_TYPE_NVLIST) {
628 nvl = nvlist_get_nvlist(nvl, name);
632 } while ((nvl = nvlist_get_parent(nvl, &cookie)) != NULL);
651 library was implemented by
652 .An Pawel Jakub Dawidek Aq pawel@dawidek.net
653 under sponsorship from the FreeBSD Foundation.