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