2 .\" Copyright (c) 2013 The FreeBSD Foundation
3 .\" Copyright (c) 2013-2015 Mariusz Zaborski <oshogbo@FreeBSD.org>
4 .\" All rights reserved.
6 .\" This documentation was written by Pawel Jakub Dawidek under sponsorship
7 .\" the FreeBSD Foundation.
9 .\" Redistribution and use in source and binary forms, with or without
10 .\" modification, are permitted provided that the following conditions
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.
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
32 .Dd September 16, 2017
39 .Nm nvlist_set_error ,
59 .Nd "library for name/value pairs"
65 .Fn nvlist_create "int flags"
67 .Fn nvlist_destroy "nvlist_t *nvl"
69 .Fn nvlist_error "const nvlist_t *nvl"
71 .Fn nvlist_set_error "nvlist_t *nvl" "int error"
73 .Fn nvlist_empty "const nvlist_t *nvl"
75 .Fn nvlist_flags "const nvlist_t *nvl"
77 .Fn nvlist_in_array "const nvlist_t *nvl"
80 .Fn nvlist_clone "const nvlist_t *nvl"
83 .Fn nvlist_dump "const nvlist_t *nvl" "int fd"
85 .Fn nvlist_fdump "const nvlist_t *nvl" "FILE *fp"
88 .Fn nvlist_size "const nvlist_t *nvl"
90 .Fn nvlist_pack "const nvlist_t *nvl" "size_t *sizep"
92 .Fn nvlist_unpack "const void *buf" "size_t size" "int flags"
95 .Fn nvlist_send "int sock" "const nvlist_t *nvl"
97 .Fn nvlist_recv "int sock" "int flags"
99 .Fn nvlist_xfer "int sock" "nvlist_t *nvl" "int flags"
102 .Fn nvlist_next "const nvlist_t *nvl" "int *typep" "void **cookiep"
105 .Fn nvlist_exists "const nvlist_t *nvl" "const char *name"
107 .Fn nvlist_exists_type "const nvlist_t *nvl" "const char *name" "int type"
109 .Fn nvlist_exists_null "const nvlist_t *nvl" "const char *name"
111 .Fn nvlist_exists_bool "const nvlist_t *nvl" "const char *name"
113 .Fn nvlist_exists_number "const nvlist_t *nvl" "const char *name"
115 .Fn nvlist_exists_string "const nvlist_t *nvl" "const char *name"
117 .Fn nvlist_exists_nvlist "const nvlist_t *nvl" "const char *name"
119 .Fn nvlist_exists_descriptor "const nvlist_t *nvl" "const char *name"
121 .Fn nvlist_exists_binary "const nvlist_t *nvl" "const char *name"
123 .Fn nvlist_exists_bool_array "const nvlist_t *nvl" "const char *name"
125 .Fn nvlist_exists_number_array "const nvlist_t *nvl" "const char *name"
127 .Fn nvlist_exists_string_array "const nvlist_t *nvl" "const char *name"
129 .Fn nvlist_exists_nvlist_array "const nvlist_t *nvl" "const char *name"
131 .Fn nvlist_exists_descriptor_array "const nvlist_t *nvl" "const char *name"
134 .Fn nvlist_add_null "nvlist_t *nvl" "const char *name"
136 .Fn nvlist_add_bool "nvlist_t *nvl" "const char *name" "bool value"
138 .Fn nvlist_add_number "nvlist_t *nvl" "const char *name" "uint64_t value"
140 .Fn nvlist_add_string "nvlist_t *nvl" "const char *name" "const char *value"
142 .Fn nvlist_add_stringf "nvlist_t *nvl" "const char *name" "const char *valuefmt" "..."
144 .Fn nvlist_add_stringv "nvlist_t *nvl" "const char *name" "const char *valuefmt" "va_list valueap"
146 .Fn nvlist_add_nvlist "nvlist_t *nvl" "const char *name" "const nvlist_t *value"
148 .Fn nvlist_add_descriptor "nvlist_t *nvl" "const char *name" "int value"
150 .Fn nvlist_add_binary "nvlist_t *nvl" "const char *name" "const void *value" "size_t size"
152 .Fn nvlist_add_bool_array "nvlist_t *nvl" "const char *name" "const bool *value" "size_t nitems"
155 .Fn nvlist_add_number_array "nvlist_t *nvl" "const char *name" "const uint64_t *value" "size_t nitems"
158 .Fn nvlist_add_string_array "nvlist_t *nvl" "const char *name" "const char * const * value" "size_t nitems"
161 .Fn nvlist_add_nvlist_array "nvlist_t *nvl" "const char *name" "const nvlist_t * const * value" "size_t nitems"
164 .Fn nvlist_add_descriptor_array "nvlist_t *nvl" "const char *name" "const int *value" "size_t nitems"
167 .Fn nvlist_move_string "nvlist_t *nvl" "const char *name" "char *value"
169 .Fn nvlist_move_nvlist "nvlist_t *nvl" "const char *name" "nvlist_t *value"
171 .Fn nvlist_move_descriptor "nvlist_t *nvl" "const char *name" "int value"
173 .Fn nvlist_move_binary "nvlist_t *nvl" "const char *name" "void *value" "size_t size"
175 .Fn nvlist_move_bool_array "nvlist_t *nvl" "const char *name" "bool *value" "size_t nitems"
178 .Fn nvlist_move_number_array "nvlist_t *nvl" "const char *name" "uint64_t *value" "size_t nitems"
181 .Fn nvlist_move_string_array "nvlist_t *nvl" "const char *name" "char **value" "size_t nitems"
184 .Fn nvlist_move_nvlist_array "nvlist_t *nvl" "const char *name" "nvlist_t **value" "size_t nitems"
187 .Fn nvlist_move_descriptor_array "nvlist_t *nvl" "const char *name" "int *value" "size_t nitems"
190 .Fn nvlist_get_bool "const nvlist_t *nvl" "const char *name"
192 .Fn nvlist_get_number "const nvlist_t *nvl" "const char *name"
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"
198 .Fn nvlist_get_descriptor "const nvlist_t *nvl" "const char *name"
200 .Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep"
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"
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"
219 .Fn nvlist_take_bool "nvlist_t *nvl" "const char *name"
221 .Fn nvlist_take_number "nvlist_t *nvl" "const char *name"
223 .Fn nvlist_take_string "nvlist_t *nvl" "const char *name"
225 .Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name"
227 .Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name"
229 .Fn nvlist_take_binary "nvlist_t *nvl" "const char *name" "size_t *sizep"
231 .Fn nvlist_take_bool_array "nvlist_t *nvl" "const char *name" "size_t *nitems"
233 .Fn nvlist_take_number_array "nvlist_t *nvl" "const char *name" "size_t *nitems"
235 .Fn nvlist_take_string_array "nvlist_t *nvl" "const char *name" "size_t *nitems"
237 .Fn nvlist_take_nvlist_array "nvlist_t *nvl" "const char *name" "size_t *nitems"
239 .Fn nvlist_take_descriptor_array "nvlist_t *nvl" "const char *name" "size_t *nitems"
242 .Fn nvlist_free "nvlist_t *nvl" "const char *name"
244 .Fn nvlist_free_type "nvlist_t *nvl" "const char *name" "int type"
247 .Fn nvlist_free_null "nvlist_t *nvl" "const char *name"
249 .Fn nvlist_free_bool "nvlist_t *nvl" "const char *name"
251 .Fn nvlist_free_number "nvlist_t *nvl" "const char *name"
253 .Fn nvlist_free_string "nvlist_t *nvl" "const char *name"
255 .Fn nvlist_free_nvlist "nvlist_t *nvl" "const char *name"
257 .Fn nvlist_free_descriptor "nvlist_t *nvl" "const char *name"
259 .Fn nvlist_free_binary "nvlist_t *nvl" "const char *name"
261 .Fn nvlist_free_bool_array "nvlist_t *nvl" "const char *name"
263 .Fn nvlist_free_number_array "nvlist_t *nvl" "const char *name"
265 .Fn nvlist_free_string_array "nvlist_t *nvl" "const char *name"
267 .Fn nvlist_free_nvlist_array "nvlist_t *nvl" "const char *name"
269 .Fn nvlist_free_descriptor_array "nvlist_t *nvl" "const char *name"
273 library allows to easily manage name value pairs as well as send and receive
275 A group (list) of name value pairs is called an
277 The API supports the following data types:
278 .Bl -ohang -offset indent
279 .It Sy null ( NV_TYPE_NULL )
280 There is no data associated with the name.
281 .It Sy bool ( NV_TYPE_BOOL )
282 The value can be either
286 .It Sy number ( NV_TYPE_NUMBER )
287 The value is a number stored as
289 .It Sy string ( NV_TYPE_STRING )
290 The value is a C string.
291 .It Sy nvlist ( NV_TYPE_NVLIST )
292 The value is a nested nvlist.
293 .It Sy descriptor ( NV_TYPE_DESCRIPTOR )
294 The value is a file descriptor.
295 Note that file descriptors can be sent only over
298 .It Sy binary ( NV_TYPE_BINARY )
299 The value is a binary buffer.
300 .It Sy bool array ( NV_TYPE_BOOL_ARRAY )
301 The value is an array of boolean values.
302 .It Sy number array ( NV_TYPE_NUMBER_ARRAY )
303 The value is an array of numbers, each stored as
305 .It Sy string array ( NV_TYPE_STRING_ARRAY )
306 The value is an array of C strings.
307 .It Sy nvlist array ( NV_TYPE_NVLIST_ARRAY )
308 The value is an array of nvlists.
309 When an nvlist is added to an array, it becomes part of the primary nvlist.
310 Traversing these arrays can be done using the
311 .Fn nvlist_get_array_next
313 .Fn nvlist_get_pararr
315 .It Sy descriptor array ( NV_TYPE_DESCRIPTOR_ARRAY )
316 The value is an array of files descriptors.
321 function allocates memory and initializes an nvlist.
323 The following flag can be provided:
325 .Bl -tag -width "NV_FLAG_IGNORE_CASE" -compact -offset indent
326 .It Dv NV_FLAG_IGNORE_CASE
327 Perform case-insensitive lookups of provided names.
328 .It Dv NV_FLAG_NO_UNIQUE
329 Names in the nvlist do not have to be unique.
334 function destroys the given nvlist.
335 Function does nothing if
338 Function never modifies the
344 function returns any error value that the nvlist accumulated.
345 If the given nvlist is
349 error will be returned.
353 function sets an nvlist to be in the error state.
356 will return the given error value.
357 This function cannot be used to clear the error state from an nvlist.
358 This function does nothing if the nvlist is already in the error state.
364 if the given nvlist is empty and
367 The nvlist must not be in error state.
371 function returns flags used to create the nvlist with the
381 is part of an array that is a member of another nvlist.
385 functions clones the given nvlist.
386 The clone shares no resources with its origin.
387 This also means that all file descriptors that are part of the nvlist will be
390 system call before placing them in the clone.
394 dumps nvlist content for debugging purposes to the given file descriptor
399 dumps nvlist content for debugging purposes to the given file stream
404 function returns the size of the given nvlist after converting it to binary
411 function converts the given nvlist to a binary buffer.
412 The function allocates memory for the buffer, which should be freed with the
419 the size of the buffer will be stored there.
422 in case of an error (allocation failure).
423 If the nvlist contains any file descriptors
426 The nvlist must not be in error state.
430 function converts the given buffer to the nvlist.
433 argument defines what type of the top level nvlist is expected to be.
434 Flags are set up using the
437 If the nvlist flags do not match the flags passed to
439 the nvlist will not be returned.
440 Every nested nvlist list should be checked using
449 function sends the given nvlist over the socket given by the
452 Note that nvlist that contains file descriptors can only be send over
458 function receives nvlist over the socket given by the
463 argument defines what type of the top level nvlist is expected to be.
464 Flags are set up using the
467 If the nvlist flags do not match the flags passed to
469 the nvlist will not be returned.
470 Every nested nvlist list should be checked using
476 function sends the given nvlist over the socket given by the
478 argument and receives nvlist over the same socket.
481 argument defines what type of the top level nvlist is expected to be.
482 Flags are set up using the
485 If the nvlist flags do not match the flags passed to
487 the nvlist will not be returned.
488 Every nested nvlist list should be checked using
491 The given nvlist is always destroyed.
495 function iterates over the given nvlist returning names and types of subsequent
499 argument allows the function to figure out which element should be returned
505 for the first call and should not be changed later.
508 means there are no more elements on the nvlist.
511 argument can be NULL.
512 Elements may not be removed from the nvlist while traversing it.
513 The nvlist must not be in error state.
520 In this case first element is returned or
523 This behavior simplifies removing the first element from the list.
529 if element of the given name exists (besides of its type) or
532 The nvlist must not be in error state.
535 .Fn nvlist_exists_type
538 if element of the given name and the given type exists or
541 The nvlist must not be in error state.
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
558 if element of the given name and the given type determined by the function name
562 The nvlist must not be in error state.
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
579 functions add element to the given nvlist.
580 When adding string or binary buffor the functions will allocate memory
581 and copy the data over.
582 When adding nvlist, the nvlist will be cloned and clone will be added.
583 When adding descriptor, the descriptor will be duplicated using the
585 system call and the new descriptor will be added.
586 The array functions will fail if there are any
588 elements in the array, or if the array pointer is
590 If an error occurs while adding new element, internal error is set which can be
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
605 functions add new element to the given nvlist, but unlike
606 .Fn nvlist_add_<type>
607 functions they will consume the given resource.
608 In the case of strings, descriptors, or nvlists every elements must be
609 unique, or it could cause a double free.
610 The array functions will fail if there are any
612 elements, or if the array pointer is
614 If an error occurs while adding new element, the resource is destroyed and
615 internal error is set which can be examined using the
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
631 functions return the value that corresponds to the given key name.
632 In the case of strings, nvlists, descriptors, binary, or arrays, the returned
633 resource should not be modified - they still belong to the nvlist.
634 If an element of the given name does not exist, the program will be aborted.
635 To avoid this, the caller should check for the existence of the name before
636 trying to obtain the value, or use the
638 extension, which can provide a default value in the case of a missing element.
639 The nvlist must not be in error state.
642 .Fn nvlist_get_parent
643 function returns the parent nvlist of the nested nvlist.
646 .Fn nvlist_get_array_next
647 function returns the next element from the array or
649 if the nvlist is not in array or it is the last element.
651 .Fn nvlist_get_array_next
652 only works if you added the nvlist array using the
653 .Fn nvlist_move_nvlist_array
655 .Fn nvlist_add_nvlist_array
659 .Fn nvlist_get_pararr
660 function returns the next element in the array, or if not available
661 the parent of the nested nvlist.
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
675 functions return value associated with the given name and remove the element
677 In case of string and binary values, the caller is responsible for free returned
681 In case of nvlist, the caller is responsible for destroying returned nvlist
685 In case of descriptor, the caller is responsible for closing returned descriptor
689 If an element of the given name does not exist, the program will be aborted.
690 To avoid that the caller should check for the existence of the given name
691 before trying to obtain the value, or use the
693 extension, which can provide a default value in the case of a missing element.
694 In the case of an array of strings or binary values, the caller is responsible
695 for freeing every element of the array using the
698 In the case of an array of nvlists, the caller is responsible for destroying
699 every element of array using the
702 In the case of descriptors, the caller is responsible for closing every
703 element of array using the
706 In every case involving an array, the caller must also free the pointer to
710 The nvlist must not be in error state.
714 function removes element of the given name from the nvlist (besides of its type)
715 and frees all resources associated with it.
716 If element of the given name does not exist, the program will be aborted.
717 The nvlist must not be in error state.
721 function removes element of the given name and the given type from the nvlist
722 and frees all resources associated with it.
723 If element of the given name and the given type does not exist, the program
725 The nvlist must not be in error state.
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
740 functions remove element of the given name and the given type determined by the
741 function name from the nvlist and free all resources associated with it.
742 If element of the given name and the given type does not exist, the program
744 The nvlist must not be in error state.
746 The following example demonstrates how to prepare an nvlist and send it over
753 fd = open("/tmp/foo", O_RDONLY);
755 err(1, "open(\\"/tmp/foo\\") failed");
757 nvl = nvlist_create(0);
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.
763 nvlist_add_string(nvl, "filename", "/tmp/foo");
764 nvlist_add_number(nvl, "flags", O_RDONLY);
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
770 nvlist_move_descriptor(nvl, "fd", fd);
771 if (nvlist_send(sock, nvl) < 0) {
773 err(1, "nvlist_send() failed");
778 Receiving nvlist and getting data:
785 nvl = nvlist_recv(sock, 0);
787 err(1, "nvlist_recv() failed");
789 /* For command we take pointer to nvlist's buffer. */
790 command = nvlist_get_string(nvl, "command");
792 * For filename we remove it from the nvlist and take
793 * ownership of the buffer.
795 filename = nvlist_take_string(nvl, "filename");
796 /* The same for the descriptor. */
797 fd = nvlist_take_descriptor(nvl, "fd");
799 printf("command=%s filename=%s fd=%d\n", command, filename, fd);
804 /* command was freed by nvlist_destroy() */
807 Iterating over nvlist:
814 nvl = nvlist_recv(sock, 0);
816 err(1, "nvlist_recv() failed");
819 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
823 printf("%ju", (uintmax_t)nvlist_get_number(nvl, name));
826 printf("%s", nvlist_get_string(nvl, name));
836 Iterating over every nested nvlist:
843 nvl = nvlist_recv(sock, 0);
845 err(1, "nvlist_recv() failed");
849 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
850 if (type == NV_TYPE_NVLIST) {
851 nvl = nvlist_get_nvlist(nvl, name);
855 } while ((nvl = nvlist_get_parent(nvl, &cookie)) != NULL);
858 Iterating over every nested nvlist and every nvlist element:
861 const nvlist_t * const *array;
866 nvl = nvlist_recv(sock, 0);
868 err(1, "nvlist_recv() failed");
872 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
873 if (type == NV_TYPE_NVLIST) {
874 nvl = nvlist_get_nvlist(nvl, name);
876 } else if (type == NV_TYPE_NVLIST_ARRAY) {
877 nvl = nvlist_get_nvlist_array(nvl, name, NULL)[0];
881 } while ((nvl = nvlist_get_pararr(nvl, &cookie)) != NULL);
887 const nvlist_t * const *array;
892 nvl = nvlist_recv(sock, 0);
894 err(1, "nvlist_recv() failed");
901 while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
902 if (type == NV_TYPE_NVLIST) {
903 nvl = nvlist_get_nvlist(nvl,
906 } else if (type == NV_TYPE_NVLIST_ARRAY) {
907 nvl = nvlist_get_nvlist_array(nvl, name,
913 } while ((tmp = nvlist_get_array_next(nvl)) != NULL);
914 } while ((tmp = nvlist_get_parent(nvl, &cookie)) != NULL);
933 library was implemented by
934 .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net
935 under sponsorship from the FreeBSD Foundation.