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