xref: /freebsd/share/man/man9/nv.9 (revision 907b59d76938e654f0d040a888e8dfca3de1e222)
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 August 15, 2015
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 "const nvlist_t *nvl" "const char *name" "size_t *nitems"
205.Ft "const char * const *"
206.Fn nvlist_get_string "const nvlist_t *nvl" "const char *name" "size_t *nitems"
207.Ft "const nvlist_t * const *"
208.Fn nvlist_get_nvlist "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 "nvlist_t *nvl" "const char *name" "size_t *nitems"
234.Ft "char **"
235.Fn nvlist_take_string "nvlist_t *nvl" "const char *name" "size_t *nitems"
236.Ft "nvlist_t **"
237.Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name" "size_t *nitems"
238.Ft "int *"
239.Fn nvlist_take_descriptor "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