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