xref: /freebsd/share/man/man9/nv.9 (revision 58c86148dd9e76281e7eb5f90282e8cf004a653a)
1*58c86148SMariusz Zaborski.\"
2*58c86148SMariusz Zaborski.\" Copyright (c) 2013 The FreeBSD Foundation
3*58c86148SMariusz Zaborski.\" All rights reserved.
4*58c86148SMariusz Zaborski.\"
5*58c86148SMariusz Zaborski.\" This documentation was written by Pawel Jakub Dawidek under sponsorship
6*58c86148SMariusz Zaborski.\" the FreeBSD Foundation.
7*58c86148SMariusz Zaborski.\"
8*58c86148SMariusz Zaborski.\" Redistribution and use in source and binary forms, with or without
9*58c86148SMariusz Zaborski.\" modification, are permitted provided that the following conditions
10*58c86148SMariusz Zaborski.\" are met:
11*58c86148SMariusz Zaborski.\" 1. Redistributions of source code must retain the above copyright
12*58c86148SMariusz Zaborski.\"    notice, this list of conditions and the following disclaimer.
13*58c86148SMariusz Zaborski.\" 2. Redistributions in binary form must reproduce the above copyright
14*58c86148SMariusz Zaborski.\"    notice, this list of conditions and the following disclaimer in the
15*58c86148SMariusz Zaborski.\"    documentation and/or other materials provided with the distribution.
16*58c86148SMariusz Zaborski.\"
17*58c86148SMariusz Zaborski.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18*58c86148SMariusz Zaborski.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*58c86148SMariusz Zaborski.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*58c86148SMariusz Zaborski.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21*58c86148SMariusz Zaborski.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*58c86148SMariusz Zaborski.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*58c86148SMariusz Zaborski.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*58c86148SMariusz Zaborski.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*58c86148SMariusz Zaborski.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*58c86148SMariusz Zaborski.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*58c86148SMariusz Zaborski.\" SUCH DAMAGE.
28*58c86148SMariusz Zaborski.\"
29*58c86148SMariusz Zaborski.\" $FreeBSD$
30*58c86148SMariusz Zaborski.\"
31*58c86148SMariusz Zaborski.Dd July 4, 2015
32*58c86148SMariusz Zaborski.Dt NV 9
33*58c86148SMariusz Zaborski.Os
34*58c86148SMariusz Zaborski.Sh NAME
35*58c86148SMariusz Zaborski.Nm nvlist_create ,
36*58c86148SMariusz Zaborski.Nm nvlist_destroy ,
37*58c86148SMariusz Zaborski.Nm nvlist_error ,
38*58c86148SMariusz Zaborski.Nm nvlist_set_error ,
39*58c86148SMariusz Zaborski.Nm nvlist_empty ,
40*58c86148SMariusz Zaborski.Nm nvlist_flags ,
41*58c86148SMariusz Zaborski.Nm nvlist_exists ,
42*58c86148SMariusz Zaborski.Nm nvlist_free ,
43*58c86148SMariusz Zaborski.Nm nvlist_clone ,
44*58c86148SMariusz Zaborski.Nm nvlist_dump ,
45*58c86148SMariusz Zaborski.Nm nvlist_fdump ,
46*58c86148SMariusz Zaborski.Nm nvlist_size ,
47*58c86148SMariusz Zaborski.Nm nvlist_pack ,
48*58c86148SMariusz Zaborski.Nm nvlist_unpack ,
49*58c86148SMariusz Zaborski.Nm nvlist_send ,
50*58c86148SMariusz Zaborski.Nm nvlist_recv ,
51*58c86148SMariusz Zaborski.Nm nvlist_xfer ,
52*58c86148SMariusz Zaborski.Nm nvlist_next ,
53*58c86148SMariusz Zaborski.Nm nvlist_add ,
54*58c86148SMariusz Zaborski.Nm nvlist_move ,
55*58c86148SMariusz Zaborski.Nm nvlist_get ,
56*58c86148SMariusz Zaborski.Nm nvlist_take
57*58c86148SMariusz Zaborski.Nd "library for name/value pairs"
58*58c86148SMariusz Zaborski.Sh LIBRARY
59*58c86148SMariusz Zaborski.Lb libnv
60*58c86148SMariusz Zaborski.Sh SYNOPSIS
61*58c86148SMariusz Zaborski.In nv.h
62*58c86148SMariusz Zaborski.Ft "nvlist_t *"
63*58c86148SMariusz Zaborski.Fn nvlist_create "int flags"
64*58c86148SMariusz Zaborski.Ft void
65*58c86148SMariusz Zaborski.Fn nvlist_destroy "nvlist_t *nvl"
66*58c86148SMariusz Zaborski.Ft int
67*58c86148SMariusz Zaborski.Fn nvlist_error "const nvlist_t *nvl"
68*58c86148SMariusz Zaborski.Ft void
69*58c86148SMariusz Zaborski.Fn nvlist_set_error "nvlist_t *nvl, int error"
70*58c86148SMariusz Zaborski.Ft bool
71*58c86148SMariusz Zaborski.Fn nvlist_empty "const nvlist_t *nvl"
72*58c86148SMariusz Zaborski.Ft int
73*58c86148SMariusz Zaborski.Fn nvlist_flags "const nvlist_t *nvl"
74*58c86148SMariusz Zaborski.\"
75*58c86148SMariusz Zaborski.Ft "nvlist_t *"
76*58c86148SMariusz Zaborski.Fn nvlist_clone "const nvlist_t *nvl"
77*58c86148SMariusz Zaborski.\"
78*58c86148SMariusz Zaborski.Ft void
79*58c86148SMariusz Zaborski.Fn nvlist_dump "const nvlist_t *nvl, int fd"
80*58c86148SMariusz Zaborski.Ft void
81*58c86148SMariusz Zaborski.Fn nvlist_fdump "const nvlist_t *nvl, FILE *fp"
82*58c86148SMariusz Zaborski.\"
83*58c86148SMariusz Zaborski.Ft size_t
84*58c86148SMariusz Zaborski.Fn nvlist_size "const nvlist_t *nvl"
85*58c86148SMariusz Zaborski.Ft "void *"
86*58c86148SMariusz Zaborski.Fn nvlist_pack "const nvlist_t *nvl" "size_t *sizep"
87*58c86148SMariusz Zaborski.Ft "nvlist_t *"
88*58c86148SMariusz Zaborski.Fn nvlist_unpack "const void *buf" "size_t size" "int flags"
89*58c86148SMariusz Zaborski.\"
90*58c86148SMariusz Zaborski.Ft int
91*58c86148SMariusz Zaborski.Fn nvlist_send "int sock" "const nvlist_t *nvl"
92*58c86148SMariusz Zaborski.Ft "nvlist_t *"
93*58c86148SMariusz Zaborski.Fn nvlist_recv "int sock" "int flags"
94*58c86148SMariusz Zaborski.Ft "nvlist_t *"
95*58c86148SMariusz Zaborski.Fn nvlist_xfer "int sock" "nvlist_t *nvl" "int flags"
96*58c86148SMariusz Zaborski.\"
97*58c86148SMariusz Zaborski.Ft "const char *"
98*58c86148SMariusz Zaborski.Fn nvlist_next "const nvlist_t *nvl" "int *typep" "void **cookiep"
99*58c86148SMariusz Zaborski.\"
100*58c86148SMariusz Zaborski.Ft bool
101*58c86148SMariusz Zaborski.Fn nvlist_exists "const nvlist_t *nvl" "const char *name"
102*58c86148SMariusz Zaborski.Ft bool
103*58c86148SMariusz Zaborski.Fn nvlist_exists_type "const nvlist_t *nvl" "const char *name" "int type"
104*58c86148SMariusz Zaborski.Ft bool
105*58c86148SMariusz Zaborski.Fn nvlist_exists_null "const nvlist_t *nvl" "const char *name"
106*58c86148SMariusz Zaborski.Ft bool
107*58c86148SMariusz Zaborski.Fn nvlist_exists_bool "const nvlist_t *nvl" "const char *name"
108*58c86148SMariusz Zaborski.Ft bool
109*58c86148SMariusz Zaborski.Fn nvlist_exists_number "const nvlist_t *nvl" "const char *name"
110*58c86148SMariusz Zaborski.Ft bool
111*58c86148SMariusz Zaborski.Fn nvlist_exists_string "const nvlist_t *nvl" "const char *name"
112*58c86148SMariusz Zaborski.Ft bool
113*58c86148SMariusz Zaborski.Fn nvlist_exists_nvlist "const nvlist_t *nvl" "const char *name"
114*58c86148SMariusz Zaborski.Ft bool
115*58c86148SMariusz Zaborski.Fn nvlist_exists_descriptor "const nvlist_t *nvl" "const char *name"
116*58c86148SMariusz Zaborski.Ft bool
117*58c86148SMariusz Zaborski.Fn nvlist_exists_binary "const nvlist_t *nvl" "const char *name"
118*58c86148SMariusz Zaborski.\"
119*58c86148SMariusz Zaborski.Ft void
120*58c86148SMariusz Zaborski.Fn nvlist_add_null "nvlist_t *nvl" "const char *name"
121*58c86148SMariusz Zaborski.Ft void
122*58c86148SMariusz Zaborski.Fn nvlist_add_bool "nvlist_t *nvl" "const char *name" "bool value"
123*58c86148SMariusz Zaborski.Ft void
124*58c86148SMariusz Zaborski.Fn nvlist_add_number "nvlist_t *nvl" "const char *name" "uint64_t value"
125*58c86148SMariusz Zaborski.Ft void
126*58c86148SMariusz Zaborski.Fn nvlist_add_string "nvlist_t *nvl" "const char *name" "const char *value"
127*58c86148SMariusz Zaborski.Ft void
128*58c86148SMariusz Zaborski.Fn nvlist_add_stringf "nvlist_t *nvl" "const char *name" "const char *valuefmt" "..."
129*58c86148SMariusz Zaborski.Ft void
130*58c86148SMariusz Zaborski.Fn nvlist_add_stringv "nvlist_t *nvl" "const char *name" "const char *valuefmt" "va_list valueap"
131*58c86148SMariusz Zaborski.Ft void
132*58c86148SMariusz Zaborski.Fn nvlist_add_nvlist "nvlist_t *nvl" "const char *name" "const nvlist_t *value"
133*58c86148SMariusz Zaborski.Ft void
134*58c86148SMariusz Zaborski.Fn nvlist_add_descriptor "nvlist_t *nvl" "const char *name" "int value"
135*58c86148SMariusz Zaborski.Ft void
136*58c86148SMariusz Zaborski.Fn nvlist_add_binary "nvlist_t *nvl" "const char *name" "const void *value" "size_t size"
137*58c86148SMariusz Zaborski.\"
138*58c86148SMariusz Zaborski.Ft void
139*58c86148SMariusz Zaborski.Fn nvlist_move_string "nvlist_t *nvl" "const char *name" "char *value"
140*58c86148SMariusz Zaborski.Ft void
141*58c86148SMariusz Zaborski.Fn nvlist_move_nvlist "nvlist_t *nvl" "const char *name" "nvlist_t *value"
142*58c86148SMariusz Zaborski.Ft void
143*58c86148SMariusz Zaborski.Fn nvlist_move_descriptor "nvlist_t *nvl" "const char *name" "int value"
144*58c86148SMariusz Zaborski.Ft void
145*58c86148SMariusz Zaborski.Fn nvlist_move_binary "nvlist_t *nvl" "const char *name" "void *value" "size_t size"
146*58c86148SMariusz Zaborski.\"
147*58c86148SMariusz Zaborski.Ft bool
148*58c86148SMariusz Zaborski.Fn nvlist_get_bool "const nvlist_t *nvl" "const char *name"
149*58c86148SMariusz Zaborski.Ft uint64_t
150*58c86148SMariusz Zaborski.Fn nvlist_get_number "const nvlist_t *nvl" "const char *name"
151*58c86148SMariusz Zaborski.Ft "const char *"
152*58c86148SMariusz Zaborski.Fn nvlist_get_string "const nvlist_t *nvl" "const char *name"
153*58c86148SMariusz Zaborski.Ft "const nvlist_t *"
154*58c86148SMariusz Zaborski.Fn nvlist_get_nvlist "const nvlist_t *nvl" "const char *name"
155*58c86148SMariusz Zaborski.Ft int
156*58c86148SMariusz Zaborski.Fn nvlist_get_descriptor "const nvlist_t *nvl" "const char *name"
157*58c86148SMariusz Zaborski.Ft "const void *"
158*58c86148SMariusz Zaborski.Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep"
159*58c86148SMariusz Zaborski.Ft "const nvlist_t *"
160*58c86148SMariusz Zaborski.Fn nvlist_get_parent "const nvlist_t *nvl" "void **cookiep"
161*58c86148SMariusz Zaborski.\"
162*58c86148SMariusz Zaborski.Ft bool
163*58c86148SMariusz Zaborski.Fn nvlist_take_bool "nvlist_t *nvl" "const char *name"
164*58c86148SMariusz Zaborski.Ft uint64_t
165*58c86148SMariusz Zaborski.Fn nvlist_take_number "nvlist_t *nvl" "const char *name"
166*58c86148SMariusz Zaborski.Ft "char *"
167*58c86148SMariusz Zaborski.Fn nvlist_take_string "nvlist_t *nvl" "const char *name"
168*58c86148SMariusz Zaborski.Ft "nvlist_t *"
169*58c86148SMariusz Zaborski.Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name"
170*58c86148SMariusz Zaborski.Ft int
171*58c86148SMariusz Zaborski.Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name"
172*58c86148SMariusz Zaborski.Ft "void *"
173*58c86148SMariusz Zaborski.Fn nvlist_take_binary "nvlist_t *nvl" "const char *name" "size_t *sizep"
174*58c86148SMariusz Zaborski.\"
175*58c86148SMariusz Zaborski.Ft void
176*58c86148SMariusz Zaborski.Fn nvlist_free "nvlist_t *nvl" "const char *name"
177*58c86148SMariusz Zaborski.Ft void
178*58c86148SMariusz Zaborski.Fn nvlist_free_type "nvlist_t *nvl" "const char *name" "int type"
179*58c86148SMariusz Zaborski.\"
180*58c86148SMariusz Zaborski.Ft void
181*58c86148SMariusz Zaborski.Fn nvlist_free_null "nvlist_t *nvl" "const char *name"
182*58c86148SMariusz Zaborski.Ft void
183*58c86148SMariusz Zaborski.Fn nvlist_free_bool "nvlist_t *nvl" "const char *name"
184*58c86148SMariusz Zaborski.Ft void
185*58c86148SMariusz Zaborski.Fn nvlist_free_number "nvlist_t *nvl" "const char *name"
186*58c86148SMariusz Zaborski.Ft void
187*58c86148SMariusz Zaborski.Fn nvlist_free_string "nvlist_t *nvl" "const char *name"
188*58c86148SMariusz Zaborski.Ft void
189*58c86148SMariusz Zaborski.Fn nvlist_free_nvlist "nvlist_t *nvl" "const char *name"
190*58c86148SMariusz Zaborski.Ft void
191*58c86148SMariusz Zaborski.Fn nvlist_free_descriptor "nvlist_t *nvl" "const char *name"
192*58c86148SMariusz Zaborski.Ft void
193*58c86148SMariusz Zaborski.Fn nvlist_free_binary "nvlist_t *nvl" "const char *name"
194*58c86148SMariusz Zaborski.Sh DESCRIPTION
195*58c86148SMariusz ZaborskiThe
196*58c86148SMariusz Zaborski.Nm libnv
197*58c86148SMariusz Zaborskilibrary allows to easily manage name value pairs as well as send and receive
198*58c86148SMariusz Zaborskithem over sockets.
199*58c86148SMariusz ZaborskiA group (list) of name value pairs is called an
200*58c86148SMariusz Zaborski.Nm nvlist .
201*58c86148SMariusz ZaborskiThe API supports the following data types:
202*58c86148SMariusz Zaborski.Bl -ohang -offset indent
203*58c86148SMariusz Zaborski.It Sy null ( NV_TYPE_NULL )
204*58c86148SMariusz ZaborskiThere is no data associated with the name.
205*58c86148SMariusz Zaborski.It Sy bool ( NV_TYPE_BOOL )
206*58c86148SMariusz ZaborskiThe value can be either
207*58c86148SMariusz Zaborski.Dv true
208*58c86148SMariusz Zaborskior
209*58c86148SMariusz Zaborski.Dv false .
210*58c86148SMariusz Zaborski.It Sy number ( NV_TYPE_NUMBER )
211*58c86148SMariusz ZaborskiThe value is a number stored as
212*58c86148SMariusz Zaborski.Vt uint64_t .
213*58c86148SMariusz Zaborski.It Sy string ( NV_TYPE_STRING )
214*58c86148SMariusz ZaborskiThe value is a C string.
215*58c86148SMariusz Zaborski.It Sy nvlist ( NV_TYPE_NVLIST )
216*58c86148SMariusz ZaborskiThe value is a nested nvlist.
217*58c86148SMariusz Zaborski.It Sy descriptor ( NV_TYPE_DESCRIPTOR )
218*58c86148SMariusz ZaborskiThe value is a file descriptor.
219*58c86148SMariusz ZaborskiNote that file descriptors can be sent only over
220*58c86148SMariusz Zaborski.Xr unix 4
221*58c86148SMariusz Zaborskidomain sockets.
222*58c86148SMariusz Zaborski.It Sy binary ( NV_TYPE_BINARY )
223*58c86148SMariusz ZaborskiThe value is a binary buffer.
224*58c86148SMariusz Zaborski.El
225*58c86148SMariusz Zaborski.Pp
226*58c86148SMariusz ZaborskiThe
227*58c86148SMariusz Zaborski.Fn nvlist_create
228*58c86148SMariusz Zaborskifunction allocates memory and initializes an nvlist.
229*58c86148SMariusz Zaborski.Pp
230*58c86148SMariusz ZaborskiThe following flag can be provided:
231*58c86148SMariusz Zaborski.Pp
232*58c86148SMariusz Zaborski.Bl -tag -width "NV_FLAG_IGNORE_CASE" -compact -offset indent
233*58c86148SMariusz Zaborski.It Dv NV_FLAG_IGNORE_CASE
234*58c86148SMariusz ZaborskiPerform case-insensitive lookups of provided names.
235*58c86148SMariusz Zaborski.It Dv NV_FLAG_NO_UNIQUE
236*58c86148SMariusz ZaborskiNames in the nvlist do not have to be unique.
237*58c86148SMariusz Zaborski.El
238*58c86148SMariusz Zaborski.Pp
239*58c86148SMariusz ZaborskiThe
240*58c86148SMariusz Zaborski.Fn nvlist_destroy
241*58c86148SMariusz Zaborskifunction destroys the given nvlist.
242*58c86148SMariusz ZaborskiFunction does nothing if
243*58c86148SMariusz Zaborski.Dv NULL
244*58c86148SMariusz Zaborskinvlist is provided.
245*58c86148SMariusz ZaborskiFunction never modifies the
246*58c86148SMariusz Zaborski.Va errno
247*58c86148SMariusz Zaborskiglobal variable.
248*58c86148SMariusz Zaborski.Pp
249*58c86148SMariusz ZaborskiThe
250*58c86148SMariusz Zaborski.Fn nvlist_error
251*58c86148SMariusz Zaborskifunction returns any error value that the nvlist accumulated.
252*58c86148SMariusz ZaborskiIf the given nvlist is
253*58c86148SMariusz Zaborski.Dv NULL
254*58c86148SMariusz Zaborskithe
255*58c86148SMariusz Zaborski.Er ENOMEM
256*58c86148SMariusz Zaborskierror will be returned.
257*58c86148SMariusz Zaborski.Pp
258*58c86148SMariusz ZaborskiThe
259*58c86148SMariusz Zaborski.Fn nvlist_set_error
260*58c86148SMariusz Zaborskifunction sets an nvlist to be in the error state.
261*58c86148SMariusz ZaborskiSubsequent calls to
262*58c86148SMariusz Zaborski.Fn nvlist_error
263*58c86148SMariusz Zaborskiwill return the given error value.
264*58c86148SMariusz ZaborskiThis function cannot be used to clear the error state from an nvlist.
265*58c86148SMariusz ZaborskiThis function does nothing if the nvlist is already in the error state.
266*58c86148SMariusz Zaborski.Pp
267*58c86148SMariusz ZaborskiThe
268*58c86148SMariusz Zaborski.Fn nvlist_empty
269*58c86148SMariusz Zaborskifunction returns
270*58c86148SMariusz Zaborski.Dv true
271*58c86148SMariusz Zaborskiif the given nvlist is empty and
272*58c86148SMariusz Zaborski.Dv false
273*58c86148SMariusz Zaborskiotherwise.
274*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
275*58c86148SMariusz Zaborski.Pp
276*58c86148SMariusz ZaborskiThe
277*58c86148SMariusz Zaborski.Fn nvlist_flags
278*58c86148SMariusz Zaborskifunction returns flags used to create the nvlist with the
279*58c86148SMariusz Zaborski.Fn nvlist_create
280*58c86148SMariusz Zaborskifunction.
281*58c86148SMariusz Zaborski.Pp
282*58c86148SMariusz ZaborskiThe
283*58c86148SMariusz Zaborski.Fn nvlist_clone
284*58c86148SMariusz Zaborskifunctions clones the given nvlist.
285*58c86148SMariusz ZaborskiThe clone shares no resources with its origin.
286*58c86148SMariusz ZaborskiThis also means that all file descriptors that are part of the nvlist will be
287*58c86148SMariusz Zaborskiduplicated with the
288*58c86148SMariusz Zaborski.Xr dup 2
289*58c86148SMariusz Zaborskisystem call before placing them in the clone.
290*58c86148SMariusz Zaborski.Pp
291*58c86148SMariusz ZaborskiThe
292*58c86148SMariusz Zaborski.Fn nvlist_dump
293*58c86148SMariusz Zaborskidumps nvlist content for debugging purposes to the given file descriptor
294*58c86148SMariusz Zaborski.Fa fd .
295*58c86148SMariusz Zaborski.Pp
296*58c86148SMariusz ZaborskiThe
297*58c86148SMariusz Zaborski.Fn nvlist_fdump
298*58c86148SMariusz Zaborskidumps nvlist content for debugging purposes to the given file stream
299*58c86148SMariusz Zaborski.Fa fp .
300*58c86148SMariusz Zaborski.Pp
301*58c86148SMariusz ZaborskiThe
302*58c86148SMariusz Zaborski.Fn nvlist_size
303*58c86148SMariusz Zaborskifunction returns the size of the given nvlist after converting it to binary
304*58c86148SMariusz Zaborskibuffer with the
305*58c86148SMariusz Zaborski.Fn nvlist_pack
306*58c86148SMariusz Zaborskifunction.
307*58c86148SMariusz Zaborski.Pp
308*58c86148SMariusz ZaborskiThe
309*58c86148SMariusz Zaborski.Fn nvlist_pack
310*58c86148SMariusz Zaborskifunction converts the given nvlist to a binary buffer.
311*58c86148SMariusz ZaborskiThe function allocates memory for the buffer, which should be freed with the
312*58c86148SMariusz Zaborski.Xr free 3
313*58c86148SMariusz Zaborskifunction.
314*58c86148SMariusz ZaborskiIf the
315*58c86148SMariusz Zaborski.Fa sizep
316*58c86148SMariusz Zaborskiargument is not
317*58c86148SMariusz Zaborski.Dv NULL ,
318*58c86148SMariusz Zaborskithe size of the buffer will be stored there.
319*58c86148SMariusz ZaborskiThe function returns
320*58c86148SMariusz Zaborski.Dv NULL
321*58c86148SMariusz Zaborskiin case of an error (allocation failure).
322*58c86148SMariusz ZaborskiIf the nvlist contains any file descriptors
323*58c86148SMariusz Zaborski.Dv NULL
324*58c86148SMariusz Zaborskiwill be returned.
325*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
326*58c86148SMariusz Zaborski.Pp
327*58c86148SMariusz ZaborskiThe
328*58c86148SMariusz Zaborski.Fn nvlist_unpack
329*58c86148SMariusz Zaborskifunction converts the given buffer to the nvlist.
330*58c86148SMariusz ZaborskiThe
331*58c86148SMariusz Zaborski.Fa flags
332*58c86148SMariusz Zaborskiargument defines what type of the top level nvlist is expected to be.
333*58c86148SMariusz ZaborskiFlags are set up using the
334*58c86148SMariusz Zaborski.Fn nvlist_create
335*58c86148SMariusz Zaborskifunction.
336*58c86148SMariusz ZaborskiIf the nvlist flags do not match the flags passed to
337*58c86148SMariusz Zaborski.Fn nvlist_unpack ,
338*58c86148SMariusz Zaborskithe nvlist will not be returned.
339*58c86148SMariusz ZaborskiEvery nested nvlist list should be checked using
340*58c86148SMariusz Zaborski.Fn nvlist_flags
341*58c86148SMariusz Zaborskifunction.
342*58c86148SMariusz ZaborskiThe function returns
343*58c86148SMariusz Zaborski.Dv NULL
344*58c86148SMariusz Zaborskiin case of an error.
345*58c86148SMariusz Zaborski.Pp
346*58c86148SMariusz ZaborskiThe
347*58c86148SMariusz Zaborski.Fn nvlist_send
348*58c86148SMariusz Zaborskifunction sends the given nvlist over the socket given by the
349*58c86148SMariusz Zaborski.Fa sock
350*58c86148SMariusz Zaborskiargument.
351*58c86148SMariusz ZaborskiNote that nvlist that contains file descriptors can only be send over
352*58c86148SMariusz Zaborski.Xr unix 4
353*58c86148SMariusz Zaborskidomain sockets.
354*58c86148SMariusz Zaborski.Pp
355*58c86148SMariusz ZaborskiThe
356*58c86148SMariusz Zaborski.Fn nvlist_recv
357*58c86148SMariusz Zaborskifunction receives nvlist over the socket given by the
358*58c86148SMariusz Zaborski.Fa sock
359*58c86148SMariusz Zaborskiargument.
360*58c86148SMariusz ZaborskiThe
361*58c86148SMariusz Zaborski.Fa flags
362*58c86148SMariusz Zaborskiargument defines what type of the top level nvlist is expected to be.
363*58c86148SMariusz ZaborskiFlags are set up using the
364*58c86148SMariusz Zaborski.Fn nvlist_create
365*58c86148SMariusz Zaborskifunction.
366*58c86148SMariusz ZaborskiIf the nvlist flags do not match the flags passed to
367*58c86148SMariusz Zaborski.Fn nvlist_recv ,
368*58c86148SMariusz Zaborskithe nvlist will not be returned.
369*58c86148SMariusz ZaborskiEvery nested nvlist list should be checked using
370*58c86148SMariusz Zaborski.Fn nvlist_flags
371*58c86148SMariusz Zaborskifunction.
372*58c86148SMariusz Zaborski.Pp
373*58c86148SMariusz ZaborskiThe
374*58c86148SMariusz Zaborski.Fn nvlist_xfer
375*58c86148SMariusz Zaborskifunction sends the given nvlist over the socket given by the
376*58c86148SMariusz Zaborski.Fa sock
377*58c86148SMariusz Zaborskiargument and receives nvlist over the same socket.
378*58c86148SMariusz ZaborskiThe
379*58c86148SMariusz Zaborski.Fa flags
380*58c86148SMariusz Zaborskiargument defines what type of the top level nvlist is expected to be.
381*58c86148SMariusz ZaborskiFlags are set up using the
382*58c86148SMariusz Zaborski.Fn nvlist_create
383*58c86148SMariusz Zaborskifunction.
384*58c86148SMariusz ZaborskiIf the nvlist flags do not match the flags passed to
385*58c86148SMariusz Zaborski.Fn nvlist_xfer ,
386*58c86148SMariusz Zaborskithe nvlist will not be returned.
387*58c86148SMariusz ZaborskiEvery nested nvlist list should be checked using
388*58c86148SMariusz Zaborski.Fn nvlist_flags
389*58c86148SMariusz Zaborskifunction.
390*58c86148SMariusz ZaborskiThe given nvlist is always destroyed.
391*58c86148SMariusz Zaborski.Pp
392*58c86148SMariusz ZaborskiThe
393*58c86148SMariusz Zaborski.Fn nvlist_next
394*58c86148SMariusz Zaborskifunction iterates over the given nvlist returning names and types of subsequent
395*58c86148SMariusz Zaborskielements.
396*58c86148SMariusz ZaborskiThe
397*58c86148SMariusz Zaborski.Fa cookiep
398*58c86148SMariusz Zaborskiargument allows the function to figure out which element should be returned
399*58c86148SMariusz Zaborskinext.
400*58c86148SMariusz ZaborskiThe
401*58c86148SMariusz Zaborski.Va *cookiep
402*58c86148SMariusz Zaborskishould be set to
403*58c86148SMariusz Zaborski.Dv NULL
404*58c86148SMariusz Zaborskifor the first call and should not be changed later.
405*58c86148SMariusz ZaborskiReturning
406*58c86148SMariusz Zaborski.Dv NULL
407*58c86148SMariusz Zaborskimeans there are no more elements on the nvlist.
408*58c86148SMariusz ZaborskiThe
409*58c86148SMariusz Zaborski.Fa typep
410*58c86148SMariusz Zaborskiargument can be NULL.
411*58c86148SMariusz ZaborskiElements may not be removed from the nvlist while traversing it.
412*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
413*58c86148SMariusz Zaborski.Pp
414*58c86148SMariusz ZaborskiThe
415*58c86148SMariusz Zaborski.Fn nvlist_exists
416*58c86148SMariusz Zaborskifunction returns
417*58c86148SMariusz Zaborski.Dv true
418*58c86148SMariusz Zaborskiif element of the given name exists (besides of its type) or
419*58c86148SMariusz Zaborski.Dv false
420*58c86148SMariusz Zaborskiotherwise.
421*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
422*58c86148SMariusz Zaborski.Pp
423*58c86148SMariusz ZaborskiThe
424*58c86148SMariusz Zaborski.Fn nvlist_exists_type
425*58c86148SMariusz Zaborskifunction returns
426*58c86148SMariusz Zaborski.Dv true
427*58c86148SMariusz Zaborskiif element of the given name and the given type exists or
428*58c86148SMariusz Zaborski.Dv false
429*58c86148SMariusz Zaborskiotherwise.
430*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
431*58c86148SMariusz Zaborski.Pp
432*58c86148SMariusz ZaborskiThe
433*58c86148SMariusz Zaborski.Fn nvlist_exists_null ,
434*58c86148SMariusz Zaborski.Fn nvlist_exists_bool ,
435*58c86148SMariusz Zaborski.Fn nvlist_exists_number ,
436*58c86148SMariusz Zaborski.Fn nvlist_exists_string ,
437*58c86148SMariusz Zaborski.Fn nvlist_exists_nvlist ,
438*58c86148SMariusz Zaborski.Fn nvlist_exists_descriptor ,
439*58c86148SMariusz Zaborski.Fn nvlist_exists_binary
440*58c86148SMariusz Zaborskifunctions return
441*58c86148SMariusz Zaborski.Dv true
442*58c86148SMariusz Zaborskiif element of the given name and the given type determined by the function name
443*58c86148SMariusz Zaborskiexists or
444*58c86148SMariusz Zaborski.Dv false
445*58c86148SMariusz Zaborskiotherwise.
446*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
447*58c86148SMariusz Zaborski.Pp
448*58c86148SMariusz ZaborskiThe
449*58c86148SMariusz Zaborski.Fn nvlist_add_null ,
450*58c86148SMariusz Zaborski.Fn nvlist_add_bool ,
451*58c86148SMariusz Zaborski.Fn nvlist_add_number ,
452*58c86148SMariusz Zaborski.Fn nvlist_add_string ,
453*58c86148SMariusz Zaborski.Fn nvlist_add_stringf ,
454*58c86148SMariusz Zaborski.Fn nvlist_add_stringv ,
455*58c86148SMariusz Zaborski.Fn nvlist_add_nvlist ,
456*58c86148SMariusz Zaborski.Fn nvlist_add_descriptor ,
457*58c86148SMariusz Zaborski.Fn nvlist_add_binary
458*58c86148SMariusz Zaborskifunctions add element to the given nvlist.
459*58c86148SMariusz ZaborskiWhen adding string or binary buffor the functions will allocate memory
460*58c86148SMariusz Zaborskiand copy the data over.
461*58c86148SMariusz ZaborskiWhen adding nvlist, the nvlist will be cloned and clone will be added.
462*58c86148SMariusz ZaborskiWhen adding descriptor, the descriptor will be duplicated using the
463*58c86148SMariusz Zaborski.Xr dup 2
464*58c86148SMariusz Zaborskisystem call and the new descriptor will be added.
465*58c86148SMariusz ZaborskiIf an error occurs while adding new element, internal error is set which can be
466*58c86148SMariusz Zaborskiexamined using the
467*58c86148SMariusz Zaborski.Fn nvlist_error
468*58c86148SMariusz Zaborskifunction.
469*58c86148SMariusz Zaborski.Pp
470*58c86148SMariusz ZaborskiThe
471*58c86148SMariusz Zaborski.Fn nvlist_move_string ,
472*58c86148SMariusz Zaborski.Fn nvlist_move_nvlist ,
473*58c86148SMariusz Zaborski.Fn nvlist_move_descriptor ,
474*58c86148SMariusz Zaborski.Fn nvlist_move_binary
475*58c86148SMariusz Zaborskifunctions add new element to the given nvlist, but unlike
476*58c86148SMariusz Zaborski.Fn nvlist_add_<type>
477*58c86148SMariusz Zaborskifunctions they will consume the given resource.
478*58c86148SMariusz ZaborskiIf an error occurs while adding new element, the resource is destroyed and
479*58c86148SMariusz Zaborskiinternal error is set which can be examined using the
480*58c86148SMariusz Zaborski.Fn nvlist_error
481*58c86148SMariusz Zaborskifunction.
482*58c86148SMariusz Zaborski.Pp
483*58c86148SMariusz ZaborskiThe
484*58c86148SMariusz Zaborski.Fn nvlist_get_bool ,
485*58c86148SMariusz Zaborski.Fn nvlist_get_number ,
486*58c86148SMariusz Zaborski.Fn nvlist_get_string ,
487*58c86148SMariusz Zaborski.Fn nvlist_get_nvlist ,
488*58c86148SMariusz Zaborski.Fn nvlist_get_descriptor ,
489*58c86148SMariusz Zaborski.Fn nvlist_get_binary
490*58c86148SMariusz Zaborskifunctions allow to obtain value of the given name.
491*58c86148SMariusz ZaborskiIn case of string, nvlist, descriptor or binary, returned resource should
492*58c86148SMariusz Zaborskinot be modified - it still belongs to the nvlist.
493*58c86148SMariusz ZaborskiIf element of the given name does not exist, the program will be aborted.
494*58c86148SMariusz ZaborskiTo avoid that the caller should check for existence before trying to obtain
495*58c86148SMariusz Zaborskithe value or use
496*58c86148SMariusz Zaborski.Xr dnvlist 3
497*58c86148SMariusz Zaborskiextension, which allows to provide default value for a missing element.
498*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
499*58c86148SMariusz Zaborski.Pp
500*58c86148SMariusz ZaborskiThe
501*58c86148SMariusz Zaborski.Fn nvlist_get_parent
502*58c86148SMariusz Zaborskifunction allows to obtain the parent nvlist from the nested nvlist.
503*58c86148SMariusz Zaborski.Pp
504*58c86148SMariusz ZaborskiThe
505*58c86148SMariusz Zaborski.Fn nvlist_take_bool ,
506*58c86148SMariusz Zaborski.Fn nvlist_take_number ,
507*58c86148SMariusz Zaborski.Fn nvlist_take_string ,
508*58c86148SMariusz Zaborski.Fn nvlist_take_nvlist ,
509*58c86148SMariusz Zaborski.Fn nvlist_take_descriptor ,
510*58c86148SMariusz Zaborski.Fn nvlist_take_binary
511*58c86148SMariusz Zaborskifunctions return value associated with the given name and remove the element
512*58c86148SMariusz Zaborskifrom the nvlist.
513*58c86148SMariusz ZaborskiIn case of string and binary values, the caller is responsible for free returned
514*58c86148SMariusz Zaborskimemory using the
515*58c86148SMariusz Zaborski.Xr free 3
516*58c86148SMariusz Zaborskifunction.
517*58c86148SMariusz ZaborskiIn case of nvlist, the caller is responsible for destroying returned nvlist
518*58c86148SMariusz Zaborskiusing the
519*58c86148SMariusz Zaborski.Fn nvlist_destroy
520*58c86148SMariusz Zaborskifunction.
521*58c86148SMariusz ZaborskiIn case of descriptor, the caller is responsible for closing returned descriptor
522*58c86148SMariusz Zaborskiusing the
523*58c86148SMariusz Zaborski.Fn close 2
524*58c86148SMariusz Zaborskisystem call.
525*58c86148SMariusz ZaborskiIf element of the given name does not exist, the program will be aborted.
526*58c86148SMariusz ZaborskiTo avoid that the caller should check for existence before trying to obtain
527*58c86148SMariusz Zaborskithe value or use
528*58c86148SMariusz Zaborski.Xr dnvlist 3
529*58c86148SMariusz Zaborskiextension, which allows to provide default value for a missing element.
530*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
531*58c86148SMariusz Zaborski.Pp
532*58c86148SMariusz ZaborskiThe
533*58c86148SMariusz Zaborski.Fn nvlist_free
534*58c86148SMariusz Zaborskifunction removes element of the given name from the nvlist (besides of its type)
535*58c86148SMariusz Zaborskiand frees all resources associated with it.
536*58c86148SMariusz ZaborskiIf element of the given name does not exist, the program will be aborted.
537*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
538*58c86148SMariusz Zaborski.Pp
539*58c86148SMariusz ZaborskiThe
540*58c86148SMariusz Zaborski.Fn nvlist_free_type
541*58c86148SMariusz Zaborskifunction removes element of the given name and the given type from the nvlist
542*58c86148SMariusz Zaborskiand frees all resources associated with it.
543*58c86148SMariusz ZaborskiIf element of the given name and the given type does not exist, the program
544*58c86148SMariusz Zaborskiwill be aborted.
545*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
546*58c86148SMariusz Zaborski.Pp
547*58c86148SMariusz ZaborskiThe
548*58c86148SMariusz Zaborski.Fn nvlist_free_null ,
549*58c86148SMariusz Zaborski.Fn nvlist_free_bool ,
550*58c86148SMariusz Zaborski.Fn nvlist_free_number ,
551*58c86148SMariusz Zaborski.Fn nvlist_free_string ,
552*58c86148SMariusz Zaborski.Fn nvlist_free_nvlist ,
553*58c86148SMariusz Zaborski.Fn nvlist_free_descriptor ,
554*58c86148SMariusz Zaborski.Fn nvlist_free_binary
555*58c86148SMariusz Zaborskifunctions remove element of the given name and the given type determined by the
556*58c86148SMariusz Zaborskifunction name from the nvlist and free all resources associated with it.
557*58c86148SMariusz ZaborskiIf element of the given name and the given type does not exist, the program
558*58c86148SMariusz Zaborskiwill be aborted.
559*58c86148SMariusz ZaborskiThe nvlist must not be in error state.
560*58c86148SMariusz Zaborski.Sh EXAMPLES
561*58c86148SMariusz ZaborskiThe following example demonstrates how to prepare an nvlist and send it over
562*58c86148SMariusz Zaborski.Xr unix 4
563*58c86148SMariusz Zaborskidomain socket.
564*58c86148SMariusz Zaborski.Bd -literal
565*58c86148SMariusz Zaborskinvlist_t *nvl;
566*58c86148SMariusz Zaborskiint fd;
567*58c86148SMariusz Zaborski
568*58c86148SMariusz Zaborskifd = open("/tmp/foo", O_RDONLY);
569*58c86148SMariusz Zaborskiif (fd < 0)
570*58c86148SMariusz Zaborski        err(1, "open(\\"/tmp/foo\\") failed");
571*58c86148SMariusz Zaborski
572*58c86148SMariusz Zaborskinvl = nvlist_create(0);
573*58c86148SMariusz Zaborski/*
574*58c86148SMariusz Zaborski * There is no need to check if nvlist_create() succeeded,
575*58c86148SMariusz Zaborski * as the nvlist_add_<type>() functions can cope.
576*58c86148SMariusz Zaborski * If it failed, nvlist_send() will fail.
577*58c86148SMariusz Zaborski */
578*58c86148SMariusz Zaborskinvlist_add_string(nvl, "filename", "/tmp/foo");
579*58c86148SMariusz Zaborskinvlist_add_number(nvl, "flags", O_RDONLY);
580*58c86148SMariusz Zaborski/*
581*58c86148SMariusz Zaborski * We just want to send the descriptor, so we can give it
582*58c86148SMariusz Zaborski * for the nvlist to consume (that's why we use nvlist_move
583*58c86148SMariusz Zaborski * not nvlist_add).
584*58c86148SMariusz Zaborski */
585*58c86148SMariusz Zaborskinvlist_move_descriptor(nvl, "fd", fd);
586*58c86148SMariusz Zaborskiif (nvlist_send(sock, nvl) < 0) {
587*58c86148SMariusz Zaborski	nvlist_destroy(nvl);
588*58c86148SMariusz Zaborski	err(1, "nvlist_send() failed");
589*58c86148SMariusz Zaborski}
590*58c86148SMariusz Zaborskinvlist_destroy(nvl);
591*58c86148SMariusz Zaborski.Ed
592*58c86148SMariusz Zaborski.Pp
593*58c86148SMariusz ZaborskiReceiving nvlist and getting data:
594*58c86148SMariusz Zaborski.Bd -literal
595*58c86148SMariusz Zaborskinvlist_t *nvl;
596*58c86148SMariusz Zaborskiconst char *command;
597*58c86148SMariusz Zaborskichar *filename;
598*58c86148SMariusz Zaborskiint fd;
599*58c86148SMariusz Zaborski
600*58c86148SMariusz Zaborskinvl = nvlist_recv(sock, 0);
601*58c86148SMariusz Zaborskiif (nvl == NULL)
602*58c86148SMariusz Zaborski	err(1, "nvlist_recv() failed");
603*58c86148SMariusz Zaborski
604*58c86148SMariusz Zaborski/* For command we take pointer to nvlist's buffer. */
605*58c86148SMariusz Zaborskicommand = nvlist_get_string(nvl, "command");
606*58c86148SMariusz Zaborski/*
607*58c86148SMariusz Zaborski * For filename we remove it from the nvlist and take
608*58c86148SMariusz Zaborski * ownership of the buffer.
609*58c86148SMariusz Zaborski */
610*58c86148SMariusz Zaborskifilename = nvlist_take_string(nvl, "filename");
611*58c86148SMariusz Zaborski/* The same for the descriptor. */
612*58c86148SMariusz Zaborskifd = nvlist_take_descriptor(nvl, "fd");
613*58c86148SMariusz Zaborski
614*58c86148SMariusz Zaborskiprintf("command=%s filename=%s fd=%d\n", command, filename, fd);
615*58c86148SMariusz Zaborski
616*58c86148SMariusz Zaborskinvlist_destroy(nvl);
617*58c86148SMariusz Zaborskifree(filename);
618*58c86148SMariusz Zaborskiclose(fd);
619*58c86148SMariusz Zaborski/* command was freed by nvlist_destroy() */
620*58c86148SMariusz Zaborski.Ed
621*58c86148SMariusz Zaborski.Pp
622*58c86148SMariusz ZaborskiIterating over nvlist:
623*58c86148SMariusz Zaborski.Bd -literal
624*58c86148SMariusz Zaborskinvlist_t *nvl;
625*58c86148SMariusz Zaborskiconst char *name;
626*58c86148SMariusz Zaborskivoid *cookie;
627*58c86148SMariusz Zaborskiint type;
628*58c86148SMariusz Zaborski
629*58c86148SMariusz Zaborskinvl = nvlist_recv(sock, 0);
630*58c86148SMariusz Zaborskiif (nvl == NULL)
631*58c86148SMariusz Zaborski	err(1, "nvlist_recv() failed");
632*58c86148SMariusz Zaborski
633*58c86148SMariusz Zaborskicookie = NULL;
634*58c86148SMariusz Zaborskiwhile ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
635*58c86148SMariusz Zaborski	printf("%s=", name);
636*58c86148SMariusz Zaborski	switch (type) {
637*58c86148SMariusz Zaborski	case NV_TYPE_NUMBER:
638*58c86148SMariusz Zaborski		printf("%ju", (uintmax_t)nvlist_get_number(nvl, name));
639*58c86148SMariusz Zaborski		break;
640*58c86148SMariusz Zaborski	case NV_TYPE_STRING:
641*58c86148SMariusz Zaborski		printf("%s", nvlist_get_string(nvl, name));
642*58c86148SMariusz Zaborski		break;
643*58c86148SMariusz Zaborski	default:
644*58c86148SMariusz Zaborski		printf("N/A");
645*58c86148SMariusz Zaborski		break;
646*58c86148SMariusz Zaborski	}
647*58c86148SMariusz Zaborski	printf("\\n");
648*58c86148SMariusz Zaborski}
649*58c86148SMariusz Zaborski.Ed
650*58c86148SMariusz Zaborski.Pp
651*58c86148SMariusz ZaborskiIterating over every nested nvlist:
652*58c86148SMariusz Zaborski.Bd -literal
653*58c86148SMariusz Zaborskinvlist_t *nvl;
654*58c86148SMariusz Zaborskiconst char *name;
655*58c86148SMariusz Zaborskivoid *cookie;
656*58c86148SMariusz Zaborskiint type;
657*58c86148SMariusz Zaborski
658*58c86148SMariusz Zaborskinvl = nvlist_recv(sock, 0);
659*58c86148SMariusz Zaborskiif (nvl == NULL)
660*58c86148SMariusz Zaborski	err(1, "nvlist_recv() failed");
661*58c86148SMariusz Zaborski
662*58c86148SMariusz Zaborskicookie = NULL;
663*58c86148SMariusz Zaborskido {
664*58c86148SMariusz Zaborski	while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
665*58c86148SMariusz Zaborski		if (type == NV_TYPE_NVLIST) {
666*58c86148SMariusz Zaborski			nvl = nvlist_get_nvlist(nvl, name);
667*58c86148SMariusz Zaborski			cookie = NULL;
668*58c86148SMariusz Zaborski		}
669*58c86148SMariusz Zaborski	}
670*58c86148SMariusz Zaborski} while ((nvl = nvlist_get_parent(nvl, &cookie)) != NULL);
671*58c86148SMariusz Zaborski.Ed
672*58c86148SMariusz Zaborski.Sh SEE ALSO
673*58c86148SMariusz Zaborski.Xr close 2 ,
674*58c86148SMariusz Zaborski.Xr dup 2 ,
675*58c86148SMariusz Zaborski.Xr open 2 ,
676*58c86148SMariusz Zaborski.Xr err 3 ,
677*58c86148SMariusz Zaborski.Xr free 3 ,
678*58c86148SMariusz Zaborski.Xr printf 3 ,
679*58c86148SMariusz Zaborski.Xr unix 4
680*58c86148SMariusz Zaborski.Sh HISTORY
681*58c86148SMariusz ZaborskiThe
682*58c86148SMariusz Zaborski.Nm libnv
683*58c86148SMariusz Zaborskilibrary appeared in
684*58c86148SMariusz Zaborski.Fx 11.0 .
685*58c86148SMariusz Zaborski.Sh AUTHORS
686*58c86148SMariusz Zaborski.An -nosplit
687*58c86148SMariusz ZaborskiThe
688*58c86148SMariusz Zaborski.Nm libnv
689*58c86148SMariusz Zaborskilibrary was implemented by
690*58c86148SMariusz Zaborski.An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net
691*58c86148SMariusz Zaborskiunder sponsorship from the FreeBSD Foundation.
692