Bring in libnv library for managing name/value pairs. The following types
are currently supported: - NV_TYPE_NULL - only name, no data; - NV_TYPE_BOOL - boolean (true or false); - NV_TYPE_NUMBER - 64bit unsigned integer; - NV_TYPE_STRING - C string; - NV_TYPE_NVLIST - nested nvlist; - NV_TYPE_DESCRIPTOR - file descriptor; - NV_TYPE_BINARY - binary data. For detailed documentation and examples see nv(3) manual page. Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
3795649286
commit
36da5199bb
@ -67,6 +67,7 @@ LINE("libmemstat", "Kernel Memory Allocator Statistics Library (libmemstat, \\-l
|
||||
LINE("libmenu", "Curses Menu Library (libmenu, \\-lmenu)")
|
||||
LINE("libnetgraph", "Netgraph User Library (libnetgraph, \\-lnetgraph)")
|
||||
LINE("libnetpgp", "Netpgp signing, verification, encryption and decryption (libnetpgp, \\-lnetpgp)")
|
||||
LINE("libnv", "Name/value pairs library (libnv, \\-lnv)")
|
||||
LINE("libossaudio", "OSS Audio Emulation Library (libossaudio, \\-lossaudio)")
|
||||
LINE("libpam", "Pluggable Authentication Module Library (libpam, \\-lpam)")
|
||||
LINE("libpcap", "Packet Capture Library (libpcap, \\-lpcap)")
|
||||
|
@ -94,6 +94,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
|
||||
${_libnandfs} \
|
||||
libnetbsd \
|
||||
${_libngatm} \
|
||||
libnv \
|
||||
libopie \
|
||||
libpam \
|
||||
libpcap \
|
||||
|
161
lib/libnv/Makefile
Normal file
161
lib/libnv/Makefile
Normal file
@ -0,0 +1,161 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LIB= nv
|
||||
SHLIBDIR?= /lib
|
||||
SHLIB_MAJOR= 0
|
||||
|
||||
SRCS= dnvlist.c
|
||||
SRCS+= msgio.c
|
||||
SRCS+= nvlist.c
|
||||
SRCS+= nvpair.c
|
||||
|
||||
INCS= dnv.h
|
||||
INCS+= nv.h
|
||||
|
||||
MAN+= nv.3
|
||||
|
||||
MLINKS+=nv.3 libnv.3 \
|
||||
nv.3 nvlist.3
|
||||
MLINKS+=nv.3 nvlist_create.3 \
|
||||
nv.3 nvlist_destroy.3 \
|
||||
nv.3 nvlist_error.3 \
|
||||
nv.3 nvlist_empty.3 \
|
||||
nv.3 nvlist_clone.3 \
|
||||
nv.3 nvlist_dump.3 \
|
||||
nv.3 nvlist_fdump.3 \
|
||||
nv.3 nvlist_size.3 \
|
||||
nv.3 nvlist_pack.3 \
|
||||
nv.3 nvlist_unpack.3 \
|
||||
nv.3 nvlist_send.3 \
|
||||
nv.3 nvlist_recv.3 \
|
||||
nv.3 nvlist_xfer.3 \
|
||||
nv.3 nvlist_next.3 \
|
||||
nv.3 nvlist_exists.3 \
|
||||
nv.3 nvlist_exists_type.3 \
|
||||
nv.3 nvlist_exists_null.3 \
|
||||
nv.3 nvlist_exists_bool.3 \
|
||||
nv.3 nvlist_exists_number.3 \
|
||||
nv.3 nvlist_exists_string.3 \
|
||||
nv.3 nvlist_exists_nvlist.3 \
|
||||
nv.3 nvlist_exists_descriptor.3 \
|
||||
nv.3 nvlist_exists_binary.3 \
|
||||
nv.3 nvlist_add_null.3 \
|
||||
nv.3 nvlist_add_bool.3 \
|
||||
nv.3 nvlist_add_number.3 \
|
||||
nv.3 nvlist_add_string.3 \
|
||||
nv.3 nvlist_add_stringf.3 \
|
||||
nv.3 nvlist_add_stringv.3 \
|
||||
nv.3 nvlist_add_nvlist.3 \
|
||||
nv.3 nvlist_add_descriptor.3 \
|
||||
nv.3 nvlist_add_binary.3 \
|
||||
nv.3 nvlist_move_string.3 \
|
||||
nv.3 nvlist_move_nvlist.3 \
|
||||
nv.3 nvlist_move_descriptor.3 \
|
||||
nv.3 nvlist_move_binary.3 \
|
||||
nv.3 nvlist_get_bool.3 \
|
||||
nv.3 nvlist_get_number.3 \
|
||||
nv.3 nvlist_get_string.3 \
|
||||
nv.3 nvlist_get_nvlist.3 \
|
||||
nv.3 nvlist_get_descriptor.3 \
|
||||
nv.3 nvlist_get_binary.3 \
|
||||
nv.3 nvlist_take_bool.3 \
|
||||
nv.3 nvlist_take_number.3 \
|
||||
nv.3 nvlist_take_string.3 \
|
||||
nv.3 nvlist_take_nvlist.3 \
|
||||
nv.3 nvlist_take_descriptor.3 \
|
||||
nv.3 nvlist_take_binary.3 \
|
||||
nv.3 nvlist_free.3 \
|
||||
nv.3 nvlist_free_type.3 \
|
||||
nv.3 nvlist_free_null.3 \
|
||||
nv.3 nvlist_free_bool.3 \
|
||||
nv.3 nvlist_free_number.3 \
|
||||
nv.3 nvlist_free_string.3 \
|
||||
nv.3 nvlist_free_nvlist.3 \
|
||||
nv.3 nvlist_free_descriptor.3 \
|
||||
nv.3 nvlist_free_binary.3
|
||||
MLINKS+=nv.3 nvlist_existsf.3 \
|
||||
nv.3 nvlist_existsf_type.3 \
|
||||
nv.3 nvlist_existsf_null.3 \
|
||||
nv.3 nvlist_existsf_bool.3 \
|
||||
nv.3 nvlist_existsf_number.3 \
|
||||
nv.3 nvlist_existsf_string.3 \
|
||||
nv.3 nvlist_existsf_nvlist.3 \
|
||||
nv.3 nvlist_existsf_descriptor.3 \
|
||||
nv.3 nvlist_existsf_binary.3 \
|
||||
nv.3 nvlist_addf_null.3 \
|
||||
nv.3 nvlist_addf_bool.3 \
|
||||
nv.3 nvlist_addf_number.3 \
|
||||
nv.3 nvlist_addf_string.3 \
|
||||
nv.3 nvlist_addf_nvlist.3 \
|
||||
nv.3 nvlist_addf_descriptor.3 \
|
||||
nv.3 nvlist_addf_binary.3 \
|
||||
nv.3 nvlist_movef_string.3 \
|
||||
nv.3 nvlist_movef_nvlist.3 \
|
||||
nv.3 nvlist_movef_descriptor.3 \
|
||||
nv.3 nvlist_movef_binary.3 \
|
||||
nv.3 nvlist_getf_bool.3 \
|
||||
nv.3 nvlist_getf_number.3 \
|
||||
nv.3 nvlist_getf_string.3 \
|
||||
nv.3 nvlist_getf_nvlist.3 \
|
||||
nv.3 nvlist_getf_descriptor.3 \
|
||||
nv.3 nvlist_getf_binary.3 \
|
||||
nv.3 nvlist_takef_bool.3 \
|
||||
nv.3 nvlist_takef_number.3 \
|
||||
nv.3 nvlist_takef_string.3 \
|
||||
nv.3 nvlist_takef_nvlist.3 \
|
||||
nv.3 nvlist_takef_descriptor.3 \
|
||||
nv.3 nvlist_takef_binary.3 \
|
||||
nv.3 nvlist_freef.3 \
|
||||
nv.3 nvlist_freef_type.3 \
|
||||
nv.3 nvlist_freef_null.3 \
|
||||
nv.3 nvlist_freef_bool.3 \
|
||||
nv.3 nvlist_freef_number.3 \
|
||||
nv.3 nvlist_freef_string.3 \
|
||||
nv.3 nvlist_freef_nvlist.3 \
|
||||
nv.3 nvlist_freef_descriptor.3 \
|
||||
nv.3 nvlist_freef_binary.3
|
||||
MLINKS+=nv.3 nvlist_existsv.3 \
|
||||
nv.3 nvlist_existsv_type.3 \
|
||||
nv.3 nvlist_existsv_null.3 \
|
||||
nv.3 nvlist_existsv_bool.3 \
|
||||
nv.3 nvlist_existsv_number.3 \
|
||||
nv.3 nvlist_existsv_string.3 \
|
||||
nv.3 nvlist_existsv_nvlist.3 \
|
||||
nv.3 nvlist_existsv_descriptor.3 \
|
||||
nv.3 nvlist_existsv_binary.3 \
|
||||
nv.3 nvlist_addv_null.3 \
|
||||
nv.3 nvlist_addv_bool.3 \
|
||||
nv.3 nvlist_addv_number.3 \
|
||||
nv.3 nvlist_addv_string.3 \
|
||||
nv.3 nvlist_addv_nvlist.3 \
|
||||
nv.3 nvlist_addv_descriptor.3 \
|
||||
nv.3 nvlist_addv_binary.3 \
|
||||
nv.3 nvlist_movev_string.3 \
|
||||
nv.3 nvlist_movev_nvlist.3 \
|
||||
nv.3 nvlist_movev_descriptor.3 \
|
||||
nv.3 nvlist_movev_binary.3 \
|
||||
nv.3 nvlist_getv_bool.3 \
|
||||
nv.3 nvlist_getv_number.3 \
|
||||
nv.3 nvlist_getv_string.3 \
|
||||
nv.3 nvlist_getv_nvlist.3 \
|
||||
nv.3 nvlist_getv_descriptor.3 \
|
||||
nv.3 nvlist_getv_binary.3 \
|
||||
nv.3 nvlist_takev_bool.3 \
|
||||
nv.3 nvlist_takev_number.3 \
|
||||
nv.3 nvlist_takev_string.3 \
|
||||
nv.3 nvlist_takev_nvlist.3 \
|
||||
nv.3 nvlist_takev_descriptor.3 \
|
||||
nv.3 nvlist_takev_binary.3 \
|
||||
nv.3 nvlist_freef.3 \
|
||||
nv.3 nvlist_freev_type.3 \
|
||||
nv.3 nvlist_freev_null.3 \
|
||||
nv.3 nvlist_freev_bool.3 \
|
||||
nv.3 nvlist_freev_number.3 \
|
||||
nv.3 nvlist_freev_string.3 \
|
||||
nv.3 nvlist_freev_nvlist.3 \
|
||||
nv.3 nvlist_freev_descriptor.3 \
|
||||
nv.3 nvlist_freev_binary.3
|
||||
|
||||
WARNS?= 6
|
||||
|
||||
.include <bsd.lib.mk>
|
37
lib/libnv/common_impl.h
Normal file
37
lib/libnv/common_impl.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_IMPL_H_
|
||||
#define _COMMON_IMPL_H_
|
||||
|
||||
#define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF)
|
||||
|
||||
#endif /* !_COMMON_IMPL_H_ */
|
106
lib/libnv/dnv.h
Normal file
106
lib/libnv/dnv.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _DNV_H_
|
||||
#define _DNV_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef _NVLIST_T_DECLARED
|
||||
#define _NVLIST_T_DECLARED
|
||||
struct nvlist;
|
||||
|
||||
typedef struct nvlist nvlist_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The dnvlist_get functions returns value associated with the given name.
|
||||
* If it returns a pointer, the pointer represents internal buffer and should
|
||||
* not be freed by the caller.
|
||||
* If no element of the given name and type exists, the function will return
|
||||
* provided default value.
|
||||
*/
|
||||
|
||||
bool dnvlist_get_bool(const nvlist_t *nvl, const char *name, bool defval);
|
||||
uint64_t dnvlist_get_number(const nvlist_t *nvl, const char *name, uint64_t defval);
|
||||
const char *dnvlist_get_string(const nvlist_t *nvl, const char *name, const char *defval);
|
||||
const nvlist_t *dnvlist_get_nvlist(const nvlist_t *nvl, const char *name, const nvlist_t *defval);
|
||||
int dnvlist_get_descriptor(const nvlist_t *nvl, const char *name, int defval);
|
||||
const void *dnvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep, const void *defval, size_t defsize);
|
||||
|
||||
bool dnvlist_getf_bool(const nvlist_t *nvl, bool defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
uint64_t dnvlist_getf_number(const nvlist_t *nvl, uint64_t defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
const char *dnvlist_getf_string(const nvlist_t *nvl, const char *defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
const nvlist_t *dnvlist_getf_nvlist(const nvlist_t *nvl, const nvlist_t *defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
int dnvlist_getf_descriptor(const nvlist_t *nvl, int defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
const void *dnvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const void *defval, size_t defsize, const char *namefmt, ...) __printflike(5, 6);
|
||||
|
||||
bool dnvlist_getv_bool(const nvlist_t *nvl, bool defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
uint64_t dnvlist_getv_number(const nvlist_t *nvl, uint64_t defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
const char *dnvlist_getv_string(const nvlist_t *nvl, const char *defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
const nvlist_t *dnvlist_getv_nvlist(const nvlist_t *nvl, const nvlist_t *defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
int dnvlist_getv_descriptor(const nvlist_t *nvl, int defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
const void *dnvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const void *defval, size_t defsize, const char *namefmt, va_list nameap) __printflike(5, 0);
|
||||
|
||||
/*
|
||||
* The dnvlist_take functions returns value associated with the given name and
|
||||
* remove corresponding nvpair.
|
||||
* If it returns a pointer, the caller has to free it.
|
||||
* If no element of the given name and type exists, the function will return
|
||||
* provided default value.
|
||||
*/
|
||||
|
||||
bool dnvlist_take_bool(nvlist_t *nvl, const char *name, bool defval);
|
||||
uint64_t dnvlist_take_number(nvlist_t *nvl, const char *name, uint64_t defval);
|
||||
char *dnvlist_take_string(nvlist_t *nvl, const char *name, char *defval);
|
||||
nvlist_t *dnvlist_take_nvlist(nvlist_t *nvl, const char *name, nvlist_t *defval);
|
||||
int dnvlist_take_descriptor(nvlist_t *nvl, const char *name, int defval);
|
||||
void *dnvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep, void *defval, size_t defsize);
|
||||
|
||||
bool dnvlist_takef_bool(nvlist_t *nvl, bool defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
uint64_t dnvlist_takef_number(nvlist_t *nvl, uint64_t defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
char *dnvlist_takef_string(nvlist_t *nvl, char *defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
nvlist_t *dnvlist_takef_nvlist(nvlist_t *nvl, nvlist_t *defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
int dnvlist_takef_descriptor(nvlist_t *nvl, int defval, const char *namefmt, ...) __printflike(3, 4);
|
||||
void *dnvlist_takef_binary(nvlist_t *nvl, size_t *sizep, void *defval, size_t defsize, const char *namefmt, ...) __printflike(5, 6);
|
||||
|
||||
bool dnvlist_takev_bool(nvlist_t *nvl, bool defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
uint64_t dnvlist_takev_number(nvlist_t *nvl, uint64_t defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
char *dnvlist_takev_string(nvlist_t *nvl, char *defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
nvlist_t *dnvlist_takev_nvlist(nvlist_t *nvl, nvlist_t *defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
int dnvlist_takev_descriptor(nvlist_t *nvl, int defval, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
void *dnvlist_takev_binary(nvlist_t *nvl, size_t *sizep, void *defval, size_t defsize, const char *namefmt, va_list nameap) __printflike(5, 0);
|
||||
|
||||
#endif /* !_DNV_H_ */
|
252
lib/libnv/dnvlist.c
Normal file
252
lib/libnv/dnvlist.c
Normal file
@ -0,0 +1,252 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nv.h"
|
||||
#include "nv_impl.h"
|
||||
|
||||
#include "dnv.h"
|
||||
|
||||
#define DNVLIST_GET(ftype, type) \
|
||||
ftype \
|
||||
dnvlist_get_##type(const nvlist_t *nvl, const char *name, ftype defval) \
|
||||
{ \
|
||||
\
|
||||
return (dnvlist_getf_##type(nvl, defval, "%s", name)); \
|
||||
}
|
||||
|
||||
DNVLIST_GET(bool, bool)
|
||||
DNVLIST_GET(uint64_t, number)
|
||||
DNVLIST_GET(const char *, string)
|
||||
DNVLIST_GET(const nvlist_t *, nvlist)
|
||||
DNVLIST_GET(int, descriptor)
|
||||
|
||||
#undef DNVLIST_GET
|
||||
|
||||
const void *
|
||||
dnvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep,
|
||||
const void *defval, size_t defsize)
|
||||
{
|
||||
|
||||
return (dnvlist_getf_binary(nvl, sizep, defval, defsize, "%s", name));
|
||||
}
|
||||
|
||||
#define DNVLIST_GETF(ftype, type) \
|
||||
ftype \
|
||||
dnvlist_getf_##type(const nvlist_t *nvl, ftype defval, \
|
||||
const char *namefmt, ...) \
|
||||
{ \
|
||||
va_list nameap; \
|
||||
ftype value; \
|
||||
\
|
||||
va_start(nameap, namefmt); \
|
||||
value = dnvlist_getv_##type(nvl, defval, namefmt, nameap); \
|
||||
va_end(nameap); \
|
||||
\
|
||||
return (value); \
|
||||
}
|
||||
|
||||
DNVLIST_GETF(bool, bool)
|
||||
DNVLIST_GETF(uint64_t, number)
|
||||
DNVLIST_GETF(const char *, string)
|
||||
DNVLIST_GETF(const nvlist_t *, nvlist)
|
||||
DNVLIST_GETF(int, descriptor)
|
||||
|
||||
#undef DNVLIST_GETF
|
||||
|
||||
const void *
|
||||
dnvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const void *defval,
|
||||
size_t defsize, const char *namefmt, ...)
|
||||
{
|
||||
va_list nameap;
|
||||
const void *value;
|
||||
|
||||
va_start(nameap, namefmt);
|
||||
value = dnvlist_getv_binary(nvl, sizep, defval, defsize, namefmt,
|
||||
nameap);
|
||||
va_end(nameap);
|
||||
|
||||
return (value);
|
||||
}
|
||||
|
||||
#define DNVLIST_GETV(ftype, type) \
|
||||
ftype \
|
||||
dnvlist_getv_##type(const nvlist_t *nvl, ftype defval, \
|
||||
const char *namefmt, va_list nameap) \
|
||||
{ \
|
||||
va_list cnameap; \
|
||||
ftype value; \
|
||||
\
|
||||
va_copy(cnameap, nameap); \
|
||||
if (nvlist_existsv_##type(nvl, namefmt, cnameap)) \
|
||||
value = nvlist_getv_##type(nvl, namefmt, nameap); \
|
||||
else \
|
||||
value = defval; \
|
||||
va_end(cnameap); \
|
||||
return (value); \
|
||||
}
|
||||
|
||||
DNVLIST_GETV(bool, bool)
|
||||
DNVLIST_GETV(uint64_t, number)
|
||||
DNVLIST_GETV(const char *, string)
|
||||
DNVLIST_GETV(const nvlist_t *, nvlist)
|
||||
DNVLIST_GETV(int, descriptor)
|
||||
|
||||
#undef DNVLIST_GETV
|
||||
|
||||
const void *
|
||||
dnvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const void *defval,
|
||||
size_t defsize, const char *namefmt, va_list nameap)
|
||||
{
|
||||
va_list cnameap;
|
||||
const void *value;
|
||||
|
||||
va_copy(cnameap, nameap);
|
||||
if (nvlist_existsv_binary(nvl, namefmt, cnameap)) {
|
||||
value = nvlist_getv_binary(nvl, sizep, namefmt, nameap);
|
||||
} else {
|
||||
if (sizep != NULL)
|
||||
*sizep = defsize;
|
||||
value = defval;
|
||||
}
|
||||
va_end(cnameap);
|
||||
return (value);
|
||||
}
|
||||
|
||||
#define DNVLIST_TAKE(ftype, type) \
|
||||
ftype \
|
||||
dnvlist_take_##type(nvlist_t *nvl, const char *name, ftype defval) \
|
||||
{ \
|
||||
\
|
||||
return (dnvlist_takef_##type(nvl, defval, "%s", name)); \
|
||||
}
|
||||
|
||||
DNVLIST_TAKE(bool, bool)
|
||||
DNVLIST_TAKE(uint64_t, number)
|
||||
DNVLIST_TAKE(char *, string)
|
||||
DNVLIST_TAKE(nvlist_t *, nvlist)
|
||||
DNVLIST_TAKE(int, descriptor)
|
||||
|
||||
#undef DNVLIST_TAKE
|
||||
|
||||
void *
|
||||
dnvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep,
|
||||
void *defval, size_t defsize)
|
||||
{
|
||||
|
||||
return (dnvlist_takef_binary(nvl, sizep, defval, defsize, "%s", name));
|
||||
}
|
||||
|
||||
#define DNVLIST_TAKEF(ftype, type) \
|
||||
ftype \
|
||||
dnvlist_takef_##type(nvlist_t *nvl, ftype defval, \
|
||||
const char *namefmt, ...) \
|
||||
{ \
|
||||
va_list nameap; \
|
||||
ftype value; \
|
||||
\
|
||||
va_start(nameap, namefmt); \
|
||||
value = dnvlist_takev_##type(nvl, defval, namefmt, nameap); \
|
||||
va_end(nameap); \
|
||||
\
|
||||
return (value); \
|
||||
}
|
||||
|
||||
DNVLIST_TAKEF(bool, bool)
|
||||
DNVLIST_TAKEF(uint64_t, number)
|
||||
DNVLIST_TAKEF(char *, string)
|
||||
DNVLIST_TAKEF(nvlist_t *, nvlist)
|
||||
DNVLIST_TAKEF(int, descriptor)
|
||||
|
||||
#undef DNVLIST_TAKEF
|
||||
|
||||
void *
|
||||
dnvlist_takef_binary(nvlist_t *nvl, size_t *sizep, void *defval,
|
||||
size_t defsize, const char *namefmt, ...)
|
||||
{
|
||||
va_list nameap;
|
||||
void *value;
|
||||
|
||||
va_start(nameap, namefmt);
|
||||
value = dnvlist_takev_binary(nvl, sizep, defval, defsize, namefmt,
|
||||
nameap);
|
||||
va_end(nameap);
|
||||
|
||||
return (value);
|
||||
}
|
||||
|
||||
#define DNVLIST_TAKEV(ftype, type) \
|
||||
ftype \
|
||||
dnvlist_takev_##type(nvlist_t *nvl, ftype defval, const char *namefmt, \
|
||||
va_list nameap) \
|
||||
{ \
|
||||
va_list cnameap; \
|
||||
ftype value; \
|
||||
\
|
||||
va_copy(cnameap, nameap); \
|
||||
if (nvlist_existsv_##type(nvl, namefmt, cnameap)) \
|
||||
value = nvlist_takev_##type(nvl, namefmt, nameap); \
|
||||
else \
|
||||
value = defval; \
|
||||
va_end(cnameap); \
|
||||
return (value); \
|
||||
}
|
||||
|
||||
DNVLIST_TAKEV(bool, bool)
|
||||
DNVLIST_TAKEV(uint64_t, number)
|
||||
DNVLIST_TAKEV(char *, string)
|
||||
DNVLIST_TAKEV(nvlist_t *, nvlist)
|
||||
DNVLIST_TAKEV(int, descriptor)
|
||||
|
||||
#undef DNVLIST_TAKEV
|
||||
|
||||
void *
|
||||
dnvlist_takev_binary(nvlist_t *nvl, size_t *sizep, void *defval,
|
||||
size_t defsize, const char *namefmt, va_list nameap)
|
||||
{
|
||||
va_list cnameap;
|
||||
void *value;
|
||||
|
||||
va_copy(cnameap, nameap);
|
||||
if (nvlist_existsv_binary(nvl, namefmt, cnameap)) {
|
||||
value = nvlist_takev_binary(nvl, sizep, namefmt, nameap);
|
||||
} else {
|
||||
if (sizep != NULL)
|
||||
*sizep = defsize;
|
||||
value = defval;
|
||||
}
|
||||
va_end(cnameap);
|
||||
return (value);
|
||||
}
|
407
lib/libnv/msgio.c
Normal file
407
lib/libnv/msgio.c
Normal file
@ -0,0 +1,407 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* Copyright (c) 2013 Mariusz Zaborski <oshogbo@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_PJDLOG
|
||||
#include <pjdlog.h>
|
||||
#endif
|
||||
|
||||
#include "common_impl.h"
|
||||
#include "msgio.h"
|
||||
|
||||
#ifndef HAVE_PJDLOG
|
||||
#include <assert.h>
|
||||
#define PJDLOG_ASSERT(...) assert(__VA_ARGS__)
|
||||
#define PJDLOG_RASSERT(expr, ...) assert(expr)
|
||||
#define PJDLOG_ABORT(...) abort()
|
||||
#endif
|
||||
|
||||
static int
|
||||
msghdr_add_fd(struct cmsghdr *cmsg, int fd)
|
||||
{
|
||||
|
||||
PJDLOG_ASSERT(fd >= 0);
|
||||
|
||||
if (!fd_is_valid(fd)) {
|
||||
errno = EBADF;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
|
||||
bcopy(&fd, CMSG_DATA(cmsg), sizeof(fd));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
msghdr_get_fd(struct cmsghdr *cmsg)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (cmsg == NULL || cmsg->cmsg_level != SOL_SOCKET ||
|
||||
cmsg->cmsg_type != SCM_RIGHTS ||
|
||||
cmsg->cmsg_len != CMSG_LEN(sizeof(fd))) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
bcopy(CMSG_DATA(cmsg), &fd, sizeof(fd));
|
||||
#ifndef MSG_CMSG_CLOEXEC
|
||||
/*
|
||||
* If the MSG_CMSG_CLOEXEC flag is not available we cannot set the
|
||||
* close-on-exec flag atomically, but we still want to set it for
|
||||
* consistency.
|
||||
*/
|
||||
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
return (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
fd_wait(int fd, bool doread)
|
||||
{
|
||||
fd_set fds;
|
||||
|
||||
PJDLOG_ASSERT(fd >= 0);
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
(void)select(fd + 1, doread ? &fds : NULL, doread ? NULL : &fds,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
msg_peek(int sock, void *buf, size_t size)
|
||||
{
|
||||
ssize_t done;
|
||||
|
||||
PJDLOG_ASSERT(sock >= 0);
|
||||
PJDLOG_ASSERT(size > 0);
|
||||
|
||||
do {
|
||||
fd_wait(sock, true);
|
||||
done = recv(sock, buf, size, MSG_PEEK | MSG_WAITALL);
|
||||
if (done == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
return (-1);
|
||||
} else if (done == 0) {
|
||||
errno = ENOTCONN;
|
||||
return (-1);
|
||||
}
|
||||
} while (done != (ssize_t)size);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
msg_recv(int sock, struct msghdr *msg)
|
||||
{
|
||||
int flags;
|
||||
|
||||
PJDLOG_ASSERT(sock >= 0);
|
||||
|
||||
#ifdef MSG_CMSG_CLOEXEC
|
||||
flags = MSG_CMSG_CLOEXEC;
|
||||
#else
|
||||
flags = 0;
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
fd_wait(sock, true);
|
||||
if (recvmsg(sock, msg, flags) == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
msg_send(int sock, const struct msghdr *msg)
|
||||
{
|
||||
|
||||
PJDLOG_ASSERT(sock >= 0);
|
||||
|
||||
for (;;) {
|
||||
fd_wait(sock, false);
|
||||
if (sendmsg(sock, msg, 0) == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cred_send(int sock)
|
||||
{
|
||||
unsigned char credbuf[CMSG_SPACE(sizeof(struct cmsgcred))];
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsg;
|
||||
struct iovec iov;
|
||||
uint8_t dummy;
|
||||
|
||||
bzero(credbuf, sizeof(credbuf));
|
||||
bzero(&msg, sizeof(msg));
|
||||
bzero(&iov, sizeof(iov));
|
||||
|
||||
/*
|
||||
* XXX: We send one byte along with the control message, because
|
||||
* setting msg_iov to NULL only works if this is the first
|
||||
* packet send over the socket. Once we send some data we
|
||||
* won't be able to send credentials anymore. This is most
|
||||
* likely a kernel bug.
|
||||
*/
|
||||
dummy = 0;
|
||||
iov.iov_base = &dummy;
|
||||
iov.iov_len = sizeof(dummy);
|
||||
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = credbuf;
|
||||
msg.msg_controllen = sizeof(credbuf);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct cmsgcred));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_CREDS;
|
||||
|
||||
if (msg_send(sock, &msg) == -1)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cred_recv(int sock, struct cmsgcred *cred)
|
||||
{
|
||||
unsigned char credbuf[CMSG_SPACE(sizeof(struct cmsgcred))];
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsg;
|
||||
struct iovec iov;
|
||||
uint8_t dummy;
|
||||
|
||||
bzero(credbuf, sizeof(credbuf));
|
||||
bzero(&msg, sizeof(msg));
|
||||
bzero(&iov, sizeof(iov));
|
||||
|
||||
iov.iov_base = &dummy;
|
||||
iov.iov_len = sizeof(dummy);
|
||||
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = credbuf;
|
||||
msg.msg_controllen = sizeof(credbuf);
|
||||
|
||||
if (msg_recv(sock, &msg) == -1)
|
||||
return (-1);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if (cmsg == NULL ||
|
||||
cmsg->cmsg_len != CMSG_LEN(sizeof(struct cmsgcred)) ||
|
||||
cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDS) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
bcopy(CMSG_DATA(cmsg), cred, sizeof(*cred));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
fd_send(int sock, const int *fds, size_t nfds)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsg;
|
||||
unsigned int i;
|
||||
int serrno, ret;
|
||||
|
||||
if (nfds == 0 || fds == NULL) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
bzero(&msg, sizeof(msg));
|
||||
msg.msg_iov = NULL;
|
||||
msg.msg_iovlen = 0;
|
||||
msg.msg_controllen = nfds * CMSG_SPACE(sizeof(int));
|
||||
msg.msg_control = calloc(1, msg.msg_controllen);
|
||||
if (msg.msg_control == NULL)
|
||||
return (-1);
|
||||
|
||||
ret = -1;
|
||||
|
||||
for (i = 0, cmsg = CMSG_FIRSTHDR(&msg); i < nfds && cmsg != NULL;
|
||||
i++, cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (msghdr_add_fd(cmsg, fds[i]) == -1)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (msg_send(sock, &msg) == -1)
|
||||
goto end;
|
||||
|
||||
ret = 0;
|
||||
end:
|
||||
serrno = errno;
|
||||
free(msg.msg_control);
|
||||
errno = serrno;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
fd_recv(int sock, int *fds, size_t nfds)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsg;
|
||||
unsigned int i;
|
||||
int serrno, ret;
|
||||
|
||||
if (nfds == 0 || fds == NULL) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
bzero(&msg, sizeof(msg));
|
||||
msg.msg_iov = NULL;
|
||||
msg.msg_iovlen = 0;
|
||||
msg.msg_controllen = nfds * CMSG_SPACE(sizeof(int));
|
||||
msg.msg_control = calloc(1, msg.msg_controllen);
|
||||
if (msg.msg_control == NULL)
|
||||
return (-1);
|
||||
|
||||
ret = -1;
|
||||
|
||||
if (msg_recv(sock, &msg) == -1)
|
||||
goto end;
|
||||
|
||||
for (i = 0, cmsg = CMSG_FIRSTHDR(&msg); i < nfds && cmsg != NULL;
|
||||
i++, cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
fds[i] = msghdr_get_fd(cmsg);
|
||||
if (fds[i] < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmsg != NULL || i < nfds) {
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* We need to close all received descriptors, even if we have
|
||||
* different control message (eg. SCM_CREDS) in between.
|
||||
*/
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
fd = msghdr_get_fd(cmsg);
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
}
|
||||
errno = EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
end:
|
||||
serrno = errno;
|
||||
free(msg.msg_control);
|
||||
errno = serrno;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
buf_send(int sock, void *buf, size_t size)
|
||||
{
|
||||
ssize_t done;
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = buf;
|
||||
do {
|
||||
fd_wait(sock, false);
|
||||
done = send(sock, ptr, size, 0);
|
||||
if (done == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return (-1);
|
||||
} else if (done == 0) {
|
||||
errno = ENOTCONN;
|
||||
return (-1);
|
||||
}
|
||||
size -= done;
|
||||
ptr += done;
|
||||
} while (size > 0);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
buf_recv(int sock, void *buf, size_t size)
|
||||
{
|
||||
ssize_t done;
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = buf;
|
||||
do {
|
||||
fd_wait(sock, true);
|
||||
done = recv(sock, ptr, size, 0);
|
||||
if (done == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return (-1);
|
||||
} else if (done == 0) {
|
||||
errno = ENOTCONN;
|
||||
return (-1);
|
||||
}
|
||||
size -= done;
|
||||
ptr += done;
|
||||
} while (size > 0);
|
||||
|
||||
return (0);
|
||||
}
|
52
lib/libnv/msgio.h
Normal file
52
lib/libnv/msgio.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Copyright (c) 2013 Mariusz Zaborski <oshogbo@FreeBSD.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MSGIO_H_
|
||||
#define _MSGIO_H_
|
||||
|
||||
struct cmsgcred;
|
||||
struct iovec;
|
||||
struct msghdr;
|
||||
|
||||
int msg_peek(int sock, void *buf, size_t size);
|
||||
|
||||
int cred_send(int sock);
|
||||
int cred_recv(int sock, struct cmsgcred *cred);
|
||||
|
||||
int fd_send(int sock, const int *fds, size_t nfds);
|
||||
int fd_recv(int sock, int *fds, size_t nfds);
|
||||
|
||||
int buf_send(int sock, void *buf, size_t size);
|
||||
int buf_recv(int sock, void *buf, size_t size);
|
||||
|
||||
#endif /* !_MSGIO_H_ */
|
604
lib/libnv/nv.3
Normal file
604
lib/libnv/nv.3
Normal file
@ -0,0 +1,604 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2013 The FreeBSD Foundation
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This documentation was written by Pawel Jakub Dawidek under sponsorship
|
||||
.\" the FreeBSD Foundation.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 8, 2013
|
||||
.Dt NV 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm nvlist_create ,
|
||||
.Nm nvlist_destroy ,
|
||||
.Nm nvlist_error ,
|
||||
.Nm nvlist_empty ,
|
||||
.Nm nvlist_exists ,
|
||||
.Nm nvlist_free ,
|
||||
.Nm nvlist_clone ,
|
||||
.Nm nvlist_dump ,
|
||||
.Nm nvlist_fdump ,
|
||||
.Nm nvlist_size ,
|
||||
.Nm nvlist_pack ,
|
||||
.Nm nvlist_unpack ,
|
||||
.Nm nvlist_send ,
|
||||
.Nm nvlist_recv ,
|
||||
.Nm nvlist_xfer ,
|
||||
.Nm nvlist_next ,
|
||||
.Nm nvlist_add ,
|
||||
.Nm nvlist_move ,
|
||||
.Nm nvlist_get ,
|
||||
.Nm nvlist_take
|
||||
.Nd "library for name/value pairs"
|
||||
.Sh LIBRARY
|
||||
.Lb libnv
|
||||
.Sh SYNOPSIS
|
||||
.In nv.h
|
||||
.Ft "nvlist_t *"
|
||||
.Fn nvlist_create "int flags"
|
||||
.Ft void
|
||||
.Fn nvlist_destroy "nvlist_t *nvl"
|
||||
.Ft int
|
||||
.Fn nvlist_error "const nvlist_t *nvl"
|
||||
.Ft bool
|
||||
.Fn nvlist_empty "const nvlist_t *nvl"
|
||||
.\"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn nvlist_clone "const nvlist_t *nvl"
|
||||
.\"
|
||||
.Ft void
|
||||
.Fn nvlist_dump "const nvlist_t *nvl, int fd"
|
||||
.Ft void
|
||||
.Fn nvlist_fdump "const nvlist_t *nvl, FILE *fp"
|
||||
.\"
|
||||
.Ft size_t
|
||||
.Fn nvlist_size "const nvlist_t *nvl"
|
||||
.Ft "void *"
|
||||
.Fn nvlist_pack "const nvlist_t *nvl" "size_t *sizep"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn nvlist_unpack "const void *buf" "size_t size"
|
||||
.\"
|
||||
.Ft int
|
||||
.Fn nvlist_send "int sock" "const nvlist_t *nvl"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn nvlist_recv "int sock"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn nvlist_xfer "int sock" "nvlist_t *nvl"
|
||||
.\"
|
||||
.Ft "const char *"
|
||||
.Fn nvlist_next "const nvlist_t *nvl" "int *typep" "void **cookiep"
|
||||
.\"
|
||||
.Ft bool
|
||||
.Fn nvlist_exists "const nvlist_t *nvl" "const char *name"
|
||||
.Ft bool
|
||||
.Fn nvlist_exists_type "const nvlist_t *nvl" "const char *name" "int type"
|
||||
.Ft bool
|
||||
.Fn nvlist_exists_null "const nvlist_t *nvl" "const char *name"
|
||||
.Ft bool
|
||||
.Fn nvlist_exists_bool "const nvlist_t *nvl" "const char *name"
|
||||
.Ft bool
|
||||
.Fn nvlist_exists_number "const nvlist_t *nvl" "const char *name"
|
||||
.Ft bool
|
||||
.Fn nvlist_exists_string "const nvlist_t *nvl" "const char *name"
|
||||
.Ft bool
|
||||
.Fn nvlist_exists_nvlist "const nvlist_t *nvl" "const char *name"
|
||||
.Ft bool
|
||||
.Fn nvlist_exists_descriptor "const nvlist_t *nvl" "const char *name"
|
||||
.Ft bool
|
||||
.Fn nvlist_exists_binary "const nvlist_t *nvl" "const char *name"
|
||||
.\"
|
||||
.Ft void
|
||||
.Fn nvlist_add_null "nvlist_t *nvl" "const char *name"
|
||||
.Ft void
|
||||
.Fn nvlist_add_bool "nvlist_t *nvl" "const char *name" "bool value"
|
||||
.Ft void
|
||||
.Fn nvlist_add_number "nvlist_t *nvl" "const char *name" "uint64_t value"
|
||||
.Ft void
|
||||
.Fn nvlist_add_string "nvlist_t *nvl" "const char *name" "const char *value"
|
||||
.Ft void
|
||||
.Fn nvlist_add_stringf "nvlist_t *nvl" "const char *name" "const char *valuefmt" "..."
|
||||
.Ft void
|
||||
.Fn nvlist_add_stringv "nvlist_t *nvl" "const char *name" "const char *valuefmt" "va_list valueap"
|
||||
.Ft void
|
||||
.Fn nvlist_add_nvlist "nvlist_t *nvl" "const char *name" "const nvlist_t *value"
|
||||
.Ft void
|
||||
.Fn nvlist_add_descriptor "nvlist_t *nvl" "const char *name" "int value"
|
||||
.Ft void
|
||||
.Fn nvlist_add_binary "nvlist_t *nvl" "const char *name" "const void *value" "size_t size"
|
||||
.\"
|
||||
.Ft void
|
||||
.Fn nvlist_move_string "nvlist_t *nvl" "const char *name" "char *value"
|
||||
.Ft void
|
||||
.Fn nvlist_move_nvlist "nvlist_t *nvl" "const char *name" "nvlist_t *value"
|
||||
.Ft void
|
||||
.Fn nvlist_move_descriptor "nvlist_t *nvl" "const char *name" "int value"
|
||||
.Ft void
|
||||
.Fn nvlist_move_binary "nvlist_t *nvl" "const char *name" "void *value" "size_t size"
|
||||
.\"
|
||||
.Ft bool
|
||||
.Fn nvlist_get_bool "const nvlist_t *nvl" "const char *name"
|
||||
.Ft uint64_t
|
||||
.Fn nvlist_get_number "const nvlist_t *nvl" "const char *name"
|
||||
.Ft "const char *"
|
||||
.Fn nvlist_get_string "const nvlist_t *nvl" "const char *name"
|
||||
.Ft "const nvlist_t *"
|
||||
.Fn nvlist_get_nvlist "const nvlist_t *nvl" "const char *name"
|
||||
.Ft int
|
||||
.Fn nvlist_get_descriptor "const nvlist_t *nvl" "const char *name"
|
||||
.Ft "const void *"
|
||||
.Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep"
|
||||
.\"
|
||||
.Ft bool
|
||||
.Fn nvlist_take_bool "nvlist_t *nvl" "const char *name"
|
||||
.Ft uint64_t
|
||||
.Fn nvlist_take_number "nvlist_t *nvl" "const char *name"
|
||||
.Ft "char *"
|
||||
.Fn nvlist_take_string "nvlist_t *nvl" "const char *name"
|
||||
.Ft "nvlist_t *"
|
||||
.Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name"
|
||||
.Ft int
|
||||
.Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name"
|
||||
.Ft "void *"
|
||||
.Fn nvlist_take_binary "nvlist_t *nvl" "const char *name" "size_t *sizep"
|
||||
.\"
|
||||
.Ft void
|
||||
.Fn nvlist_free "nvlist_t *nvl" "const char *name"
|
||||
.Ft void
|
||||
.Fn nvlist_free_type "nvlist_t *nvl" "const char *name" "int type"
|
||||
.\"
|
||||
.Ft void
|
||||
.Fn nvlist_free_null "nvlist_t *nvl" "const char *name"
|
||||
.Ft void
|
||||
.Fn nvlist_free_bool "nvlist_t *nvl" "const char *name"
|
||||
.Ft void
|
||||
.Fn nvlist_free_number "nvlist_t *nvl" "const char *name"
|
||||
.Ft void
|
||||
.Fn nvlist_free_string "nvlist_t *nvl" "const char *name"
|
||||
.Ft void
|
||||
.Fn nvlist_free_nvlist "nvlist_t *nvl" "const char *name"
|
||||
.Ft void
|
||||
.Fn nvlist_free_descriptor "nvlist_t *nvl" "const char *name"
|
||||
.Ft void
|
||||
.Fn nvlist_free_binary "nvlist_t *nvl" "const char *name"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm libnv
|
||||
library allows to easily manage name value pairs as well as send and receive
|
||||
them over sockets.
|
||||
A group (list) of name value pairs is called an
|
||||
.Nm nvlist .
|
||||
The API supports the following data types:
|
||||
.Bl -ohang -offset indent
|
||||
.It Sy null ( NV_TYPE_NULL )
|
||||
There is no data associated with the name.
|
||||
.It Sy bool ( NV_TYPE_BOLL )
|
||||
The value can be either
|
||||
.Dv true
|
||||
or
|
||||
.Dv false .
|
||||
.It Sy number ( NV_TYPE_NUMBER )
|
||||
The value is a number stored as
|
||||
.Vt uint64_t .
|
||||
.It Sy string ( NV_TYPE_STRING )
|
||||
The value is a C string.
|
||||
.It Sy nvlist ( NV_TYPE_NVLIST )
|
||||
The value is a nested nvlist.
|
||||
.It Sy descriptor ( NV_TYPE_DESCRIPTOR )
|
||||
The value is a file descriptor.
|
||||
Note that file descriptors can be sent only over
|
||||
.Xr unix 4
|
||||
domain sockets.
|
||||
.It Sy binary ( NV_TYPE_BINARY )
|
||||
The value is a binary buffer.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_create
|
||||
function allocates memory and initializes an nvlist.
|
||||
.Pp
|
||||
The following flag can be provided:
|
||||
.Pp
|
||||
.Bl -tag -width "NV_FLAG_IGNORE_CASE" -compact -offset indent
|
||||
.It Dv NV_FLAG_IGNORE_CASE
|
||||
Perform case-insensitive lookups of provided names.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_destroy
|
||||
function destroys the given nvlist.
|
||||
Function does nothing if
|
||||
.Dv NULL
|
||||
nvlist is provided.
|
||||
Function never modifies the
|
||||
.Va errno
|
||||
global variable.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_error
|
||||
function returns any error value that the nvlist accumulated.
|
||||
If the given nvlist is
|
||||
.Dv NULL
|
||||
the
|
||||
.Er ENOMEM
|
||||
error will be returned.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_empty
|
||||
functions returns
|
||||
.Dv true
|
||||
if the given nvlist is empty and
|
||||
.Dv false
|
||||
otherwise.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_clone
|
||||
functions clones the given nvlist.
|
||||
The clone shares no resources with its origin.
|
||||
This also means that all file descriptors that are part of the nvlist will be
|
||||
duplicated with the
|
||||
.Xr dup 2
|
||||
system call before placing them in the clone.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_dump
|
||||
dumps nvlist content for debugging purposes to the given file descriptor
|
||||
.Fa fd .
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_fdump
|
||||
dumps nvlist content for debugging purposes to the given file stream
|
||||
.Fa fp .
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_size
|
||||
function returns the size of the given nvlist after converting it to binary
|
||||
buffer with the
|
||||
.Fn nvlist_pack
|
||||
function.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_pack
|
||||
function converts the given nvlist to a binary buffer.
|
||||
The function allocates memory for the buffer, which should be freed with the
|
||||
.Xr free 3
|
||||
function.
|
||||
If the
|
||||
.Fa sizep
|
||||
argument is not
|
||||
.Dv NULL ,
|
||||
the size of the buffer will be stored there.
|
||||
The function returns
|
||||
.Dv NULL
|
||||
in case of an error (allocation failure).
|
||||
If the nvlist contains any file descriptors
|
||||
.Dv NULL
|
||||
will be returned.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_unpack
|
||||
function converts the given buffer to the nvlist.
|
||||
The function returns
|
||||
.Dv NULL
|
||||
in case of an error.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_send
|
||||
function sends the given nvlist over the socket given by the
|
||||
.Fa sock
|
||||
argument.
|
||||
Note that nvlist that contains file descriptors can only be send over
|
||||
.Xr unix 4
|
||||
domain sockets.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_recv
|
||||
function receives nvlist over the socket given by the
|
||||
.Fa sock
|
||||
argument.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_xfer
|
||||
function sends the given nvlist over the socket given by the
|
||||
.Fa sock
|
||||
argument and receives nvlist over the same socket.
|
||||
The given nvlist is always destroyed.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_next
|
||||
function iterates over the given nvlist returning names and types of subsequent
|
||||
elements.
|
||||
The
|
||||
.Fa cookiep
|
||||
argument allows the function to figure out which element should be returned
|
||||
next.
|
||||
The
|
||||
.Va *cookiep
|
||||
should be set to
|
||||
.Dv NULL
|
||||
for the first call and should not be changed later.
|
||||
Returning
|
||||
.Dv NULL
|
||||
means there are no more elements on the nvlist.
|
||||
The
|
||||
.Fa typep
|
||||
argument can be NULL.
|
||||
Elements may not be removed from the nvlist while traversing it.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_exists
|
||||
function returns
|
||||
.Dv true
|
||||
if element of the given name exists (besides of its type) or
|
||||
.Dv false
|
||||
otherwise.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_exists_type
|
||||
function returns
|
||||
.Dv true
|
||||
if element of the given name and the given type exists or
|
||||
.Dv false
|
||||
otherwise.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_exists_null ,
|
||||
.Fn nvlist_exists_bool ,
|
||||
.Fn nvlist_exists_number ,
|
||||
.Fn nvlist_exists_string ,
|
||||
.Fn nvlist_exists_nvlist ,
|
||||
.Fn nvlist_exists_descriptor ,
|
||||
.Fn nvlist_exists_binary
|
||||
functions return
|
||||
.Dv true
|
||||
if element of the given name and the given type determined by the function name
|
||||
exists or
|
||||
.Dv false
|
||||
otherwise.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_add_null ,
|
||||
.Fn nvlist_add_bool ,
|
||||
.Fn nvlist_add_number ,
|
||||
.Fn nvlist_add_string ,
|
||||
.Fn nvlist_add_stringf ,
|
||||
.Fn nvlist_add_stringv ,
|
||||
.Fn nvlist_add_nvlist ,
|
||||
.Fn nvlist_add_descriptor ,
|
||||
.Fn nvlist_add_binary
|
||||
functions add element to the given nvlist.
|
||||
When adding string or binary buffor the functions will allocate memory
|
||||
and copy the data over.
|
||||
When adding nvlist, the nvlist will be cloned and clone will be added.
|
||||
When adding descriptor, the descriptor will be duplicated using the
|
||||
.Xr dup 2
|
||||
system call and the new descriptor will be added.
|
||||
If an error occurs while adding new element, internal error is set which can be
|
||||
examined using the
|
||||
.Fn nvlist_error
|
||||
function.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_move_string ,
|
||||
.Fn nvlist_move_nvlist ,
|
||||
.Fn nvlist_move_descriptor ,
|
||||
.Fn nvlist_move_binary
|
||||
functions add new element to the given nvlist, but unlike
|
||||
.Fn nvlist_add_<type>
|
||||
functions they will consume the given resource.
|
||||
If an error occurs while adding new element, the resource is destroyed and
|
||||
internal error is set which can be examined using the
|
||||
.Fn nvlist_error
|
||||
function.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_get_bool ,
|
||||
.Fn nvlist_get_number ,
|
||||
.Fn nvlist_get_string ,
|
||||
.Fn nvlist_get_nvlist ,
|
||||
.Fn nvlist_get_descriptor ,
|
||||
.Fn nvlist_get_binary
|
||||
functions allow to obtain value of the given name.
|
||||
In case of string, nvlist, descriptor or binary, returned resource should
|
||||
not be modified - it still belongs to the nvlist.
|
||||
If element of the given name does not exist, the program will be aborted.
|
||||
To avoid that the caller should check for existence before trying to obtain
|
||||
the value or use
|
||||
.Xr dnvlist 3
|
||||
extension, which allows to provide default value for a missing element.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_take_bool ,
|
||||
.Fn nvlist_take_number ,
|
||||
.Fn nvlist_take_string ,
|
||||
.Fn nvlist_take_nvlist ,
|
||||
.Fn nvlist_take_descriptor ,
|
||||
.Fn nvlist_take_binary
|
||||
functions return value associated with the given name and remove the element
|
||||
from the nvlist.
|
||||
In case of string and binary values, the caller is responsible for free returned
|
||||
memory using the
|
||||
.Xr free 3
|
||||
function.
|
||||
In case of nvlist, the caller is responsible for destroying returned nvlist
|
||||
using the
|
||||
.Fn nvlist_destroy
|
||||
function.
|
||||
In case of descriptor, the caller is responsible for closing returned descriptor
|
||||
using the
|
||||
.Fn close 2
|
||||
system call.
|
||||
If element of the given name does not exist, the program will be aborted.
|
||||
To avoid that the caller should check for existence before trying to obtain
|
||||
the value or use
|
||||
.Xr dnvlist 3
|
||||
extension, which allows to provide default value for a missing element.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_free
|
||||
function removes element of the given name from the nvlist (besides of its type)
|
||||
and frees all resources associated with it.
|
||||
If element of the given name does not exist, the program will be aborted.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_free_type
|
||||
function removes element of the given name and the given type from the nvlist
|
||||
and frees all resources associated with it.
|
||||
If element of the given name and the given type does not exist, the program
|
||||
will be aborted.
|
||||
The nvlist must not be in error state.
|
||||
.Pp
|
||||
The
|
||||
.Fn nvlist_free_null ,
|
||||
.Fn nvlist_free_bool ,
|
||||
.Fn nvlist_free_number ,
|
||||
.Fn nvlist_free_string ,
|
||||
.Fn nvlist_free_nvlist ,
|
||||
.Fn nvlist_free_descriptor ,
|
||||
.Fn nvlist_free_binary
|
||||
functions remove element of the given name and the given type determined by the
|
||||
function name from the nvlist and free all resources associated with it.
|
||||
If element of the given name and the given type does not exist, the program
|
||||
will be aborted.
|
||||
The nvlist must not be in error state.
|
||||
.Sh EXAMPLES
|
||||
The following example demonstrates how to prepare an nvlist and send it over
|
||||
.Xr unix 4
|
||||
domain socket.
|
||||
.Bd -literal
|
||||
nvlist_t *nvl;
|
||||
int fd;
|
||||
|
||||
fd = open("/tmp/foo", O_RDONLY);
|
||||
if (fd < 0)
|
||||
err(1, "open(\\"/tmp/foo\\") failed");
|
||||
|
||||
nvl = nvlist_create(0);
|
||||
/*
|
||||
* There is no need to check if nvlist_create() succeeded,
|
||||
* as the nvlist_add_<type>() functions can cope.
|
||||
* If it failed, nvlist_send() will fail.
|
||||
*/
|
||||
nvlist_add_string(nvl, "filename", "/tmp/foo");
|
||||
nvlist_add_number(nvl, "flags", O_RDONLY);
|
||||
/*
|
||||
* We just want to send the descriptor, so we can give it
|
||||
* for the nvlist to consume (that's why we use nvlist_move
|
||||
* not nvlist_add).
|
||||
*/
|
||||
nvlist_move_descriptor(nvl, "fd", fd);
|
||||
if (nvlist_send(sock, nvl) < 0) {
|
||||
nvlist_destroy(nvl);
|
||||
err(1, "nvlist_send() failed");
|
||||
}
|
||||
nvlist_destroy(nvl);
|
||||
.Ed
|
||||
.Pp
|
||||
Receiving nvlist and getting data:
|
||||
.Bd -literal
|
||||
nvlist_t *nvl;
|
||||
const char *command;
|
||||
char *filename;
|
||||
int fd;
|
||||
|
||||
nvl = nvlist_recv(sock);
|
||||
if (nvl == NULL)
|
||||
err(1, "nvlist_recv() failed");
|
||||
|
||||
/* For command we take pointer to nvlist's buffer. */
|
||||
command = nvlist_get_string(nvl, "command");
|
||||
/*
|
||||
* For filename we remove it from the nvlist and take
|
||||
* ownership of the buffer.
|
||||
*/
|
||||
filename = nvlist_take_string(nvl, "filename");
|
||||
/* The same for the descriptor. */
|
||||
fd = nvlist_take_descriptor(nvl, "fd");
|
||||
|
||||
printf("command=%s filename=%s fd=%d\n", command, filename, fd);
|
||||
|
||||
nvlist_destroy(nvl);
|
||||
free(filename);
|
||||
close(fd);
|
||||
/* command was freed by nvlist_destroy() */
|
||||
.Ed
|
||||
.Pp
|
||||
Iterating over nvlist:
|
||||
.Bd -literal
|
||||
nvlist_t *nvl;
|
||||
const char *name;
|
||||
void *cookie;
|
||||
int type;
|
||||
|
||||
nvl = nvlist_recv(sock);
|
||||
if (nvl == NULL)
|
||||
err(1, "nvlist_recv() failed");
|
||||
|
||||
cookie = NULL;
|
||||
while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
|
||||
printf("%s=", name);
|
||||
switch (type) {
|
||||
case NV_TYPE_NUMBER:
|
||||
printf("%ju", (uintmax_t)nvlist_get_number(nvl, name));
|
||||
break;
|
||||
case NV_TYPE_STRING:
|
||||
printf("%s", nvlist_get_string(nvl, name));
|
||||
break;
|
||||
default:
|
||||
printf("N/A");
|
||||
break;
|
||||
}
|
||||
printf("\\n");
|
||||
}
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr close 2 ,
|
||||
.Xr dup 2 ,
|
||||
.Xr open 2 ,
|
||||
.Xr err 3 ,
|
||||
.Xr free 3 ,
|
||||
.Xr printf 3 ,
|
||||
.Xr unix 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm libnv
|
||||
library appeared in
|
||||
.Fx 10.0 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm libnv
|
||||
library was implemented by
|
||||
.An Pawel Jakub Dawidek Aq pawel@dawidek.net
|
||||
under sponsorship from the FreeBSD Foundation.
|
273
lib/libnv/nv.h
Normal file
273
lib/libnv/nv.h
Normal file
@ -0,0 +1,273 @@
|
||||
/*-
|
||||
* Copyright (c) 2009-2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NV_H_
|
||||
#define _NV_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _NVLIST_T_DECLARED
|
||||
#define _NVLIST_T_DECLARED
|
||||
struct nvlist;
|
||||
|
||||
typedef struct nvlist nvlist_t;
|
||||
#endif
|
||||
|
||||
#define NV_NAME_MAX 2048
|
||||
|
||||
#define NV_TYPE_NONE 0
|
||||
|
||||
#define NV_TYPE_NULL 1
|
||||
#define NV_TYPE_BOOL 2
|
||||
#define NV_TYPE_NUMBER 3
|
||||
#define NV_TYPE_STRING 4
|
||||
#define NV_TYPE_NVLIST 5
|
||||
#define NV_TYPE_DESCRIPTOR 6
|
||||
#define NV_TYPE_BINARY 7
|
||||
|
||||
/*
|
||||
* Perform case-insensitive lookups of provided names.
|
||||
*/
|
||||
#define NV_FLAG_IGNORE_CASE 0x01
|
||||
|
||||
nvlist_t *nvlist_create(int flags);
|
||||
void nvlist_destroy(nvlist_t *nvl);
|
||||
int nvlist_error(const nvlist_t *nvl);
|
||||
bool nvlist_empty(const nvlist_t *nvl);
|
||||
|
||||
nvlist_t *nvlist_clone(const nvlist_t *nvl);
|
||||
|
||||
void nvlist_dump(const nvlist_t *nvl, int fd);
|
||||
void nvlist_fdump(const nvlist_t *nvl, FILE *fp);
|
||||
|
||||
size_t nvlist_size(const nvlist_t *nvl);
|
||||
void *nvlist_pack(const nvlist_t *nvl, size_t *sizep);
|
||||
nvlist_t *nvlist_unpack(const void *buf, size_t size);
|
||||
|
||||
int nvlist_send(int sock, const nvlist_t *nvl);
|
||||
nvlist_t *nvlist_recv(int sock);
|
||||
nvlist_t *nvlist_xfer(int sock, nvlist_t *nvl);
|
||||
|
||||
const char *nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep);
|
||||
|
||||
/*
|
||||
* The nvlist_exists functions check if the given name (optionally of the given
|
||||
* type) exists on nvlist.
|
||||
*/
|
||||
|
||||
bool nvlist_exists(const nvlist_t *nvl, const char *name);
|
||||
bool nvlist_exists_type(const nvlist_t *nvl, const char *name, int type);
|
||||
|
||||
bool nvlist_exists_null(const nvlist_t *nvl, const char *name);
|
||||
bool nvlist_exists_bool(const nvlist_t *nvl, const char *name);
|
||||
bool nvlist_exists_number(const nvlist_t *nvl, const char *name);
|
||||
bool nvlist_exists_string(const nvlist_t *nvl, const char *name);
|
||||
bool nvlist_exists_nvlist(const nvlist_t *nvl, const char *name);
|
||||
bool nvlist_exists_descriptor(const nvlist_t *nvl, const char *name);
|
||||
bool nvlist_exists_binary(const nvlist_t *nvl, const char *name);
|
||||
|
||||
/*
|
||||
* The nvlist_add functions add the given name/value pair.
|
||||
* If a pointer is provided, nvlist_add will internally allocate memory for the
|
||||
* given data (in other words it won't consume provided buffer).
|
||||
*/
|
||||
|
||||
void nvlist_add_null(nvlist_t *nvl, const char *name);
|
||||
void nvlist_add_bool(nvlist_t *nvl, const char *name, bool value);
|
||||
void nvlist_add_number(nvlist_t *nvl, const char *name, uint64_t value);
|
||||
void nvlist_add_string(nvlist_t *nvl, const char *name, const char *value);
|
||||
void nvlist_add_stringf(nvlist_t *nvl, const char *name, const char *valuefmt, ...) __printflike(3, 4);
|
||||
void nvlist_add_stringv(nvlist_t *nvl, const char *name, const char *valuefmt, va_list valueap) __printflike(3, 0);
|
||||
void nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value);
|
||||
void nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value);
|
||||
void nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value, size_t size);
|
||||
|
||||
/*
|
||||
* The nvlist_move functions add the given name/value pair.
|
||||
* The functions consumes provided buffer.
|
||||
*/
|
||||
|
||||
void nvlist_move_string(nvlist_t *nvl, const char *name, char *value);
|
||||
void nvlist_move_nvlist(nvlist_t *nvl, const char *name, nvlist_t *value);
|
||||
void nvlist_move_descriptor(nvlist_t *nvl, const char *name, int value);
|
||||
void nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size);
|
||||
|
||||
/*
|
||||
* The nvlist_get functions returns value associated with the given name.
|
||||
* If it returns a pointer, the pointer represents internal buffer and should
|
||||
* not be freed by the caller.
|
||||
*/
|
||||
|
||||
bool nvlist_get_bool(const nvlist_t *nvl, const char *name);
|
||||
uint64_t nvlist_get_number(const nvlist_t *nvl, const char *name);
|
||||
const char *nvlist_get_string(const nvlist_t *nvl, const char *name);
|
||||
const nvlist_t *nvlist_get_nvlist(const nvlist_t *nvl, const char *name);
|
||||
int nvlist_get_descriptor(const nvlist_t *nvl, const char *name);
|
||||
const void *nvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep);
|
||||
|
||||
/*
|
||||
* The nvlist_take functions returns value associated with the given name and
|
||||
* remove the given entry from the nvlist.
|
||||
* The caller is responsible for freeing received data.
|
||||
*/
|
||||
|
||||
bool nvlist_take_bool(nvlist_t *nvl, const char *name);
|
||||
uint64_t nvlist_take_number(nvlist_t *nvl, const char *name);
|
||||
char *nvlist_take_string(nvlist_t *nvl, const char *name);
|
||||
nvlist_t *nvlist_take_nvlist(nvlist_t *nvl, const char *name);
|
||||
int nvlist_take_descriptor(nvlist_t *nvl, const char *name);
|
||||
void *nvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep);
|
||||
|
||||
/*
|
||||
* The nvlist_free functions removes the given name/value pair from the nvlist
|
||||
* and frees memory associated with it.
|
||||
*/
|
||||
|
||||
void nvlist_free(nvlist_t *nvl, const char *name);
|
||||
void nvlist_free_type(nvlist_t *nvl, const char *name, int type);
|
||||
|
||||
void nvlist_free_null(nvlist_t *nvl, const char *name);
|
||||
void nvlist_free_bool(nvlist_t *nvl, const char *name);
|
||||
void nvlist_free_number(nvlist_t *nvl, const char *name);
|
||||
void nvlist_free_string(nvlist_t *nvl, const char *name);
|
||||
void nvlist_free_nvlist(nvlist_t *nvl, const char *name);
|
||||
void nvlist_free_descriptor(nvlist_t *nvl, const char *name);
|
||||
void nvlist_free_binary(nvlist_t *nvl, const char *name);
|
||||
|
||||
/*
|
||||
* Below are the same functions, but which operate on format strings and
|
||||
* variable argument lists.
|
||||
*/
|
||||
|
||||
bool nvlist_existsf(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
bool nvlist_existsf_type(const nvlist_t *nvl, int type, const char *namefmt, ...) __printflike(3, 4);
|
||||
|
||||
bool nvlist_existsf_null(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
bool nvlist_existsf_bool(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
bool nvlist_existsf_number(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
bool nvlist_existsf_string(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
bool nvlist_existsf_nvlist(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
bool nvlist_existsf_descriptor(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
bool nvlist_existsf_binary(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
|
||||
bool nvlist_existsv(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
bool nvlist_existsv_type(const nvlist_t *nvl, int type, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
|
||||
bool nvlist_existsv_null(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
bool nvlist_existsv_bool(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
bool nvlist_existsv_number(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
bool nvlist_existsv_string(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
bool nvlist_existsv_nvlist(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
bool nvlist_existsv_descriptor(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
bool nvlist_existsv_binary(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
|
||||
void nvlist_addf_null(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
void nvlist_addf_bool(nvlist_t *nvl, bool value, const char *namefmt, ...) __printflike(3, 4);
|
||||
void nvlist_addf_number(nvlist_t *nvl, uint64_t value, const char *namefmt, ...) __printflike(3, 4);
|
||||
void nvlist_addf_string(nvlist_t *nvl, const char *value, const char *namefmt, ...) __printflike(3, 4);
|
||||
void nvlist_addf_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, ...) __printflike(3, 4);
|
||||
void nvlist_addf_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...) __printflike(3, 4);
|
||||
void nvlist_addf_binary(nvlist_t *nvl, const void *value, size_t size, const char *namefmt, ...) __printflike(4, 5);
|
||||
|
||||
void nvlist_addv_null(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
void nvlist_addv_bool(nvlist_t *nvl, bool value, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
void nvlist_addv_number(nvlist_t *nvl, uint64_t value, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
void nvlist_addv_string(nvlist_t *nvl, const char *value, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
void nvlist_addv_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
void nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
void nvlist_addv_binary(nvlist_t *nvl, const void *value, size_t size, const char *namefmt, va_list nameap) __printflike(4, 0);
|
||||
|
||||
void nvlist_movef_string(nvlist_t *nvl, char *value, const char *namefmt, ...) __printflike(3, 4);
|
||||
void nvlist_movef_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt, ...) __printflike(3, 4);
|
||||
void nvlist_movef_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...) __printflike(3, 4);
|
||||
void nvlist_movef_binary(nvlist_t *nvl, void *value, size_t size, const char *namefmt, ...) __printflike(4, 5);
|
||||
|
||||
void nvlist_movev_string(nvlist_t *nvl, char *value, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
void nvlist_movev_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
void nvlist_movev_descriptor(nvlist_t *nvl, int value, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
void nvlist_movev_binary(nvlist_t *nvl, void *value, size_t size, const char *namefmt, va_list nameap) __printflike(4, 0);
|
||||
|
||||
bool nvlist_getf_bool(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
uint64_t nvlist_getf_number(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
const char *nvlist_getf_string(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
const nvlist_t *nvlist_getf_nvlist(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
int nvlist_getf_descriptor(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
const void *nvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, ...) __printflike(3, 4);
|
||||
|
||||
bool nvlist_getv_bool(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
uint64_t nvlist_getv_number(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
const char *nvlist_getv_string(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
const nvlist_t *nvlist_getv_nvlist(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
int nvlist_getv_descriptor(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
const void *nvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
|
||||
bool nvlist_takef_bool(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
uint64_t nvlist_takef_number(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
char *nvlist_takef_string(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
nvlist_t *nvlist_takef_nvlist(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
int nvlist_takef_descriptor(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
void *nvlist_takef_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, ...) __printflike(3, 4);
|
||||
|
||||
bool nvlist_takev_bool(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
uint64_t nvlist_takev_number(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
char *nvlist_takev_string(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
nvlist_t *nvlist_takev_nvlist(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
int nvlist_takev_descriptor(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
void *nvlist_takev_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
|
||||
void nvlist_freef(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
void nvlist_freef_type(nvlist_t *nvl, int type, const char *namefmt, ...) __printflike(3, 4);
|
||||
|
||||
void nvlist_freef_null(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
void nvlist_freef_bool(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
void nvlist_freef_number(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
void nvlist_freef_string(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
void nvlist_freef_nvlist(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
void nvlist_freef_descriptor(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
void nvlist_freef_binary(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
|
||||
void nvlist_freev(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
void nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
|
||||
void nvlist_freev_null(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
void nvlist_freev_bool(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
void nvlist_freev_number(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
void nvlist_freev_string(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
void nvlist_freev_nvlist(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
void nvlist_freev_descriptor(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
void nvlist_freev_binary(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
|
||||
#endif /* !_NV_H_ */
|
130
lib/libnv/nv_impl.h
Normal file
130
lib/libnv/nv_impl.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NV_IMPL_H_
|
||||
#define _NV_IMPL_H_
|
||||
|
||||
#ifndef _NVPAIR_T_DECLARED
|
||||
#define _NVPAIR_T_DECLARED
|
||||
struct nvpair;
|
||||
|
||||
typedef struct nvpair nvpair_t;
|
||||
#endif
|
||||
|
||||
#define NV_TYPE_FIRST NV_TYPE_NULL
|
||||
#define NV_TYPE_LAST NV_TYPE_BINARY
|
||||
|
||||
#define NV_FLAG_BIG_ENDIAN 0x80
|
||||
|
||||
int *nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp);
|
||||
size_t nvlist_ndescriptors(const nvlist_t *nvl);
|
||||
|
||||
nvpair_t *nvlist_first_nvpair(const nvlist_t *nvl);
|
||||
nvpair_t *nvlist_next_nvpair(const nvlist_t *nvl, const nvpair_t *nvp);
|
||||
nvpair_t *nvlist_prev_nvpair(const nvlist_t *nvl, const nvpair_t *nvp);
|
||||
|
||||
void nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp);
|
||||
|
||||
void nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp);
|
||||
|
||||
const nvpair_t *nvlist_get_nvpair(const nvlist_t *nvl, const char *name);
|
||||
|
||||
nvpair_t *nvlist_take_nvpair(nvlist_t *nvl, const char *name);
|
||||
|
||||
/* Function removes the given nvpair from the nvlist. */
|
||||
void nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp);
|
||||
|
||||
void nvlist_free_nvpair(nvlist_t *nvl, nvpair_t *nvp);
|
||||
|
||||
int nvpair_type(const nvpair_t *nvp);
|
||||
const char *nvpair_name(const nvpair_t *nvp);
|
||||
|
||||
nvpair_t *nvpair_clone(const nvpair_t *nvp);
|
||||
|
||||
nvpair_t *nvpair_create_null(const char *name);
|
||||
nvpair_t *nvpair_create_bool(const char *name, bool value);
|
||||
nvpair_t *nvpair_create_number(const char *name, uint64_t value);
|
||||
nvpair_t *nvpair_create_string(const char *name, const char *value);
|
||||
nvpair_t *nvpair_create_stringf(const char *name, const char *valuefmt, ...) __printflike(2, 3);
|
||||
nvpair_t *nvpair_create_stringv(const char *name, const char *valuefmt, va_list valueap) __printflike(2, 0);
|
||||
nvpair_t *nvpair_create_nvlist(const char *name, const nvlist_t *value);
|
||||
nvpair_t *nvpair_create_descriptor(const char *name, int value);
|
||||
nvpair_t *nvpair_create_binary(const char *name, const void *value, size_t size);
|
||||
|
||||
nvpair_t *nvpair_move_string(const char *name, char *value);
|
||||
nvpair_t *nvpair_move_nvlist(const char *name, nvlist_t *value);
|
||||
nvpair_t *nvpair_move_descriptor(const char *name, int value);
|
||||
nvpair_t *nvpair_move_binary(const char *name, void *value, size_t size);
|
||||
|
||||
bool nvpair_get_bool(const nvpair_t *nvp);
|
||||
uint64_t nvpair_get_number(const nvpair_t *nvp);
|
||||
const char *nvpair_get_string(const nvpair_t *nvp);
|
||||
const nvlist_t *nvpair_get_nvlist(const nvpair_t *nvp);
|
||||
int nvpair_get_descriptor(const nvpair_t *nvp);
|
||||
const void *nvpair_get_binary(const nvpair_t *nvp, size_t *sizep);
|
||||
|
||||
void nvpair_free(nvpair_t *nvp);
|
||||
|
||||
const nvpair_t *nvlist_getf_nvpair(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
|
||||
const nvpair_t *nvlist_getv_nvpair(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
|
||||
nvpair_t *nvlist_takef_nvpair(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
|
||||
|
||||
nvpair_t *nvlist_takev_nvpair(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
|
||||
nvpair_t *nvpair_createf_null(const char *namefmt, ...) __printflike(1, 2);
|
||||
nvpair_t *nvpair_createf_bool(bool value, const char *namefmt, ...) __printflike(2, 3);
|
||||
nvpair_t *nvpair_createf_number(uint64_t value, const char *namefmt, ...) __printflike(2, 3);
|
||||
nvpair_t *nvpair_createf_string(const char *value, const char *namefmt, ...) __printflike(2, 3);
|
||||
nvpair_t *nvpair_createf_nvlist(const nvlist_t *value, const char *namefmt, ...) __printflike(2, 3);
|
||||
nvpair_t *nvpair_createf_descriptor(int value, const char *namefmt, ...) __printflike(2, 3);
|
||||
nvpair_t *nvpair_createf_binary(const void *value, size_t size, const char *namefmt, ...) __printflike(3, 4);
|
||||
|
||||
nvpair_t *nvpair_createv_null(const char *namefmt, va_list nameap) __printflike(1, 0);
|
||||
nvpair_t *nvpair_createv_bool(bool value, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
nvpair_t *nvpair_createv_number(uint64_t value, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
nvpair_t *nvpair_createv_string(const char *value, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
nvpair_t *nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
nvpair_t *nvpair_createv_descriptor(int value, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
nvpair_t *nvpair_createv_binary(const void *value, size_t size, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
|
||||
nvpair_t *nvpair_movef_string(char *value, const char *namefmt, ...) __printflike(2, 3);
|
||||
nvpair_t *nvpair_movef_nvlist(nvlist_t *value, const char *namefmt, ...) __printflike(2, 3);
|
||||
nvpair_t *nvpair_movef_descriptor(int value, const char *namefmt, ...) __printflike(2, 3);
|
||||
nvpair_t *nvpair_movef_binary(void *value, size_t size, const char *namefmt, ...) __printflike(3, 4);
|
||||
|
||||
nvpair_t *nvpair_movev_string(char *value, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
nvpair_t *nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
nvpair_t *nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap) __printflike(2, 0);
|
||||
nvpair_t *nvpair_movev_binary(void *value, size_t size, const char *namefmt, va_list nameap) __printflike(3, 0);
|
||||
|
||||
#endif /* !_NV_IMPL_H_ */
|
1703
lib/libnv/nvlist.c
Normal file
1703
lib/libnv/nvlist.c
Normal file
File diff suppressed because it is too large
Load Diff
43
lib/libnv/nvlist_impl.h
Normal file
43
lib/libnv/nvlist_impl.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NVLIST_IMPL_H_
|
||||
#define _NVLIST_IMPL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nv.h"
|
||||
|
||||
void *nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep);
|
||||
nvlist_t *nvlist_xunpack(const void *buf, size_t size, const int *fds,
|
||||
size_t nfds);
|
||||
|
||||
#endif /* !_NVLIST_IMPL_H_ */
|
1335
lib/libnv/nvpair.c
Normal file
1335
lib/libnv/nvpair.c
Normal file
File diff suppressed because it is too large
Load Diff
58
lib/libnv/nvpair_impl.h
Normal file
58
lib/libnv/nvpair_impl.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*-
|
||||
* Copyright (c) 2009-2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Pawel Jakub Dawidek under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NVPAIR_IMPL_H_
|
||||
#define _NVPAIR_IMPL_H_
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nv.h"
|
||||
|
||||
TAILQ_HEAD(nvl_head, nvpair);
|
||||
|
||||
void nvpair_assert(const nvpair_t *nvp);
|
||||
const nvlist_t *nvpair_nvlist(const nvpair_t *nvp);
|
||||
nvpair_t *nvpair_next(const nvpair_t *nvp);
|
||||
nvpair_t *nvpair_prev(const nvpair_t *nvp);
|
||||
void nvpair_insert(struct nvl_head *head, nvpair_t *nvp, nvlist_t *nvl);
|
||||
void nvpair_remove(struct nvl_head *head, nvpair_t *nvp, const nvlist_t *nvl);
|
||||
size_t nvpair_header_size(void);
|
||||
size_t nvpair_size(const nvpair_t *nvp);
|
||||
unsigned char *nvpair_pack(nvpair_t *nvp, unsigned char *ptr, int64_t *fdidxp,
|
||||
size_t *leftp);
|
||||
const unsigned char *nvpair_unpack(int flags, const unsigned char *ptr,
|
||||
size_t *leftp, const int *fds, size_t nfds, nvpair_t **nvpp);
|
||||
void nvpair_free_structure(nvpair_t *nvp);
|
||||
const char *nvpair_type_string(int type);
|
||||
|
||||
#endif /* !_NVPAIR_IMPL_H_ */
|
@ -97,6 +97,7 @@ LIBNCURSES?= ${DESTDIR}${LIBDIR}/libncurses.a
|
||||
LIBNCURSESW?= ${DESTDIR}${LIBDIR}/libncursesw.a
|
||||
LIBNETGRAPH?= ${DESTDIR}${LIBDIR}/libnetgraph.a
|
||||
LIBNGATM?= ${DESTDIR}${LIBDIR}/libngatm.a
|
||||
LIBNV?= ${DESTDIR}${LIBDIR}/libnv.a
|
||||
LIBNVPAIR?= ${DESTDIR}${LIBDIR}/libnvpair.a
|
||||
LIBOPIE?= ${DESTDIR}${LIBDIR}/libopie.a
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user