Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libnv/nvlist.c
Show All 27 Lines | |||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/endian.h> | #include <sys/endian.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#ifdef _KERNEL | |||||
#include <sys/errno.h> | |||||
#include <sys/kernel.h> | |||||
#include <sys/lock.h> | |||||
#include <sys/malloc.h> | |||||
#include <sys/systm.h> | |||||
#include <machine/stdarg.h> | |||||
#else | |||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#define _WITH_DPRINTF | #define _WITH_DPRINTF | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#endif | |||||
#ifdef HAVE_PJDLOG | #ifdef HAVE_PJDLOG | ||||
#include <pjdlog.h> | #include <pjdlog.h> | ||||
#endif | #endif | ||||
#include "msgio.h" | #include "msgio.h" | ||||
#include "nv.h" | #include "nv.h" | ||||
#include "nv_impl.h" | #include "nv_impl.h" | ||||
#include "nvlist_impl.h" | #include "nvlist_impl.h" | ||||
#include "nvpair_impl.h" | #include "nvpair_impl.h" | ||||
#ifndef HAVE_PJDLOG | #ifndef HAVE_PJDLOG | ||||
#ifdef _KERNEL | |||||
#define PJDLOG_ASSERT(...) MPASS(__VA_ARGS__) | |||||
#define PJDLOG_RASSERT(expr, ...) KASSERT(expr, (__VA_ARGS__)) | |||||
#define PJDLOG_ABORT(...) panic(__VA_ARGS__) | |||||
#else | |||||
#include <assert.h> | #include <assert.h> | ||||
#define PJDLOG_ASSERT(...) assert(__VA_ARGS__) | #define PJDLOG_ASSERT(...) assert(__VA_ARGS__) | ||||
#define PJDLOG_RASSERT(expr, ...) assert(expr) | #define PJDLOG_RASSERT(expr, ...) assert(expr) | ||||
#define PJDLOG_ABORT(...) do { \ | #define PJDLOG_ABORT(...) do { \ | ||||
fprintf(stderr, "%s:%u: ", __FILE__, __LINE__); \ | fprintf(stderr, "%s:%u: ", __FILE__, __LINE__); \ | ||||
fprintf(stderr, __VA_ARGS__); \ | fprintf(stderr, __VA_ARGS__); \ | ||||
fprintf(stderr, "\n"); \ | fprintf(stderr, "\n"); \ | ||||
abort(); \ | abort(); \ | ||||
} while (0) | } while (0) | ||||
#endif | #endif | ||||
#endif | |||||
#define NV_FLAG_PRIVATE_MASK (NV_FLAG_BIG_ENDIAN) | #define NV_FLAG_PRIVATE_MASK (NV_FLAG_BIG_ENDIAN) | ||||
#define NV_FLAG_PUBLIC_MASK (NV_FLAG_IGNORE_CASE) | #define NV_FLAG_PUBLIC_MASK (NV_FLAG_IGNORE_CASE) | ||||
#define NV_FLAG_ALL_MASK (NV_FLAG_PRIVATE_MASK | NV_FLAG_PUBLIC_MASK) | #define NV_FLAG_ALL_MASK (NV_FLAG_PRIVATE_MASK | NV_FLAG_PUBLIC_MASK) | ||||
#define NVLIST_MAGIC 0x6e766c /* "nvl" */ | #define NVLIST_MAGIC 0x6e766c /* "nvl" */ | ||||
struct nvlist { | struct nvlist { | ||||
int nvl_magic; | int nvl_magic; | ||||
int nvl_error; | int nvl_error; | ||||
int nvl_flags; | int nvl_flags; | ||||
nvpair_t *nvl_parent; | nvpair_t *nvl_parent; | ||||
struct nvl_head nvl_head; | struct nvl_head nvl_head; | ||||
}; | }; | ||||
#define NVLIST_ASSERT(nvl) do { \ | #define NVLIST_ASSERT(nvl) do { \ | ||||
PJDLOG_ASSERT((nvl) != NULL); \ | PJDLOG_ASSERT((nvl) != NULL); \ | ||||
PJDLOG_ASSERT((nvl)->nvl_magic == NVLIST_MAGIC); \ | PJDLOG_ASSERT((nvl)->nvl_magic == NVLIST_MAGIC); \ | ||||
} while (0) | } while (0) | ||||
#ifdef _KERNEL | |||||
MALLOC_DEFINE(M_NVLIST, "nvlist", "kernel nvlist"); | |||||
#endif | |||||
#define NVPAIR_ASSERT(nvp) nvpair_assert(nvp) | #define NVPAIR_ASSERT(nvp) nvpair_assert(nvp) | ||||
#define NVLIST_HEADER_MAGIC 0x6c | #define NVLIST_HEADER_MAGIC 0x6c | ||||
#define NVLIST_HEADER_VERSION 0x00 | #define NVLIST_HEADER_VERSION 0x00 | ||||
struct nvlist_header { | struct nvlist_header { | ||||
uint8_t nvlh_magic; | uint8_t nvlh_magic; | ||||
uint8_t nvlh_version; | uint8_t nvlh_version; | ||||
uint8_t nvlh_flags; | uint8_t nvlh_flags; | ||||
uint64_t nvlh_descriptors; | uint64_t nvlh_descriptors; | ||||
uint64_t nvlh_size; | uint64_t nvlh_size; | ||||
} __packed; | } __packed; | ||||
nvlist_t * | nvlist_t * | ||||
nvlist_create(int flags) | nvlist_create(int flags) | ||||
{ | { | ||||
nvlist_t *nvl; | nvlist_t *nvl; | ||||
PJDLOG_ASSERT((flags & ~(NV_FLAG_PUBLIC_MASK)) == 0); | PJDLOG_ASSERT((flags & ~(NV_FLAG_PUBLIC_MASK)) == 0); | ||||
nvl = malloc(sizeof(*nvl)); | nvl = nv_malloc(sizeof(*nvl)); | ||||
nvl->nvl_error = 0; | nvl->nvl_error = 0; | ||||
nvl->nvl_flags = flags; | nvl->nvl_flags = flags; | ||||
nvl->nvl_parent = NULL; | nvl->nvl_parent = NULL; | ||||
TAILQ_INIT(&nvl->nvl_head); | TAILQ_INIT(&nvl->nvl_head); | ||||
nvl->nvl_magic = NVLIST_MAGIC; | nvl->nvl_magic = NVLIST_MAGIC; | ||||
return (nvl); | return (nvl); | ||||
} | } | ||||
void | void | ||||
nvlist_destroy(nvlist_t *nvl) | nvlist_destroy(nvlist_t *nvl) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
int serrno; | int serrno; | ||||
if (nvl == NULL) | if (nvl == NULL) | ||||
return; | return; | ||||
serrno = errno; | SAVE_ERRNO(serrno); | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
while ((nvp = nvlist_first_nvpair(nvl)) != NULL) { | while ((nvp = nvlist_first_nvpair(nvl)) != NULL) { | ||||
nvlist_remove_nvpair(nvl, nvp); | nvlist_remove_nvpair(nvl, nvp); | ||||
nvpair_free(nvp); | nvpair_free(nvp); | ||||
} | } | ||||
nvl->nvl_magic = 0; | nvl->nvl_magic = 0; | ||||
free(nvl); | nv_free(nvl); | ||||
errno = serrno; | RESTORE_ERRNO(serrno); | ||||
} | } | ||||
void | void | ||||
nvlist_set_error(nvlist_t *nvl, int error) | nvlist_set_error(nvlist_t *nvl, int error) | ||||
{ | { | ||||
PJDLOG_ASSERT(error != 0); | PJDLOG_ASSERT(error != 0); | ||||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; | ||||
} else { | } else { | ||||
if (strcmp(nvpair_name(nvp), name) != 0) | if (strcmp(nvpair_name(nvp), name) != 0) | ||||
continue; | continue; | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
errno = ENOENT; | RESTORE_ERRNO(ENOENT); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
bool | bool | ||||
nvlist_exists_type(const nvlist_t *nvl, const char *name, int type) | nvlist_exists_type(const nvlist_t *nvl, const char *name, int type) | ||||
{ | { | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
PJDLOG_ASSERT(nvl->nvl_error == 0); | PJDLOG_ASSERT(nvl->nvl_error == 0); | ||||
PJDLOG_ASSERT(type == NV_TYPE_NONE || | PJDLOG_ASSERT(type == NV_TYPE_NONE || | ||||
(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST)); | (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST)); | ||||
return (nvlist_find(nvl, type, name) != NULL); | return (nvlist_find(nvl, type, name) != NULL); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
bool | bool | ||||
nvlist_existsf_type(const nvlist_t *nvl, int type, const char *namefmt, ...) | nvlist_existsf_type(const nvlist_t *nvl, int type, const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
bool ret; | bool ret; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
ret = nvlist_existsv_type(nvl, type, namefmt, nameap); | ret = nvlist_existsv_type(nvl, type, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
bool | bool | ||||
nvlist_existsv_type(const nvlist_t *nvl, int type, const char *namefmt, | nvlist_existsv_type(const nvlist_t *nvl, int type, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
char *name; | char *name; | ||||
bool exists; | bool exists; | ||||
vasprintf(&name, namefmt, nameap); | nv_vasprintf(&name, namefmt, nameap); | ||||
if (name == NULL) | if (name == NULL) | ||||
return (false); | return (false); | ||||
exists = nvlist_exists_type(nvl, name, type); | exists = nvlist_exists_type(nvl, name, type); | ||||
free(name); | nv_free(name); | ||||
return (exists); | return (exists); | ||||
} | } | ||||
#endif | |||||
void | void | ||||
nvlist_free_type(nvlist_t *nvl, const char *name, int type) | nvlist_free_type(nvlist_t *nvl, const char *name, int type) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
PJDLOG_ASSERT(nvl->nvl_error == 0); | PJDLOG_ASSERT(nvl->nvl_error == 0); | ||||
PJDLOG_ASSERT(type == NV_TYPE_NONE || | PJDLOG_ASSERT(type == NV_TYPE_NONE || | ||||
(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST)); | (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST)); | ||||
nvp = nvlist_find(nvl, type, name); | nvp = nvlist_find(nvl, type, name); | ||||
if (nvp != NULL) | if (nvp != NULL) | ||||
nvlist_free_nvpair(nvl, nvp); | nvlist_free_nvpair(nvl, nvp); | ||||
else | else | ||||
nvlist_report_missing(type, name); | nvlist_report_missing(type, name); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
void | void | ||||
nvlist_freef_type(nvlist_t *nvl, int type, const char *namefmt, ...) | nvlist_freef_type(nvlist_t *nvl, int type, const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvlist_freev_type(nvl, type, namefmt, nameap); | nvlist_freev_type(nvl, type, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
} | } | ||||
void | void | ||||
nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap) | nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap) | ||||
{ | { | ||||
char *name; | char *name; | ||||
vasprintf(&name, namefmt, nameap); | nv_vasprintf(&name, namefmt, nameap); | ||||
if (name == NULL) | if (name == NULL) | ||||
nvlist_report_missing(type, "<unknown>"); | nvlist_report_missing(type, "<unknown>"); | ||||
nvlist_free_type(nvl, name, type); | nvlist_free_type(nvl, name, type); | ||||
free(name); | nv_free(name); | ||||
} | } | ||||
#endif | |||||
nvlist_t * | nvlist_t * | ||||
nvlist_clone(const nvlist_t *nvl) | nvlist_clone(const nvlist_t *nvl) | ||||
{ | { | ||||
nvlist_t *newnvl; | nvlist_t *newnvl; | ||||
nvpair_t *nvp, *newnvp; | nvpair_t *nvp, *newnvp; | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
if (nvl->nvl_error != 0) { | if (nvl->nvl_error != 0) { | ||||
errno = nvl->nvl_error; | RESTORE_ERRNO(nvl->nvl_error); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
newnvl = nvlist_create(nvl->nvl_flags & NV_FLAG_PUBLIC_MASK); | newnvl = nvlist_create(nvl->nvl_flags & NV_FLAG_PUBLIC_MASK); | ||||
for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; | for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; | ||||
nvp = nvlist_next_nvpair(nvl, nvp)) { | nvp = nvlist_next_nvpair(nvl, nvp)) { | ||||
newnvp = nvpair_clone(nvp); | newnvp = nvpair_clone(nvp); | ||||
if (newnvp == NULL) | if (newnvp == NULL) | ||||
break; | break; | ||||
nvlist_move_nvpair(newnvl, newnvp); | nvlist_move_nvpair(newnvl, newnvp); | ||||
} | } | ||||
if (nvp != NULL) { | if (nvp != NULL) { | ||||
nvlist_destroy(newnvl); | nvlist_destroy(newnvl); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
return (newnvl); | return (newnvl); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
static bool | static bool | ||||
nvlist_dump_error_check(const nvlist_t *nvl, int fd, int level) | nvlist_dump_error_check(const nvlist_t *nvl, int fd, int level) | ||||
{ | { | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
dprintf(fd, "%*serror: %d\n", level * 4, "", | dprintf(fd, "%*serror: %d\n", level * 4, "", | ||||
nvlist_error(nvl)); | nvlist_error(nvl)); | ||||
return (true); | return (true); | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
nvlist_fdump(const nvlist_t *nvl, FILE *fp) | nvlist_fdump(const nvlist_t *nvl, FILE *fp) | ||||
{ | { | ||||
fflush(fp); | fflush(fp); | ||||
nvlist_dump(nvl, fileno(fp)); | nvlist_dump(nvl, fileno(fp)); | ||||
} | } | ||||
#endif | |||||
/* | /* | ||||
* The function obtains size of the nvlist after nvlist_pack(). | * The function obtains size of the nvlist after nvlist_pack(). | ||||
*/ | */ | ||||
size_t | size_t | ||||
nvlist_size(const nvlist_t *nvl) | nvlist_size(const nvlist_t *nvl) | ||||
{ | { | ||||
const nvlist_t *tmpnvl; | const nvlist_t *tmpnvl; | ||||
Show All 32 Lines | while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) { | ||||
nvp = cookie; | nvp = cookie; | ||||
} | } | ||||
} | } | ||||
out: | out: | ||||
return (size); | return (size); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
static int * | static int * | ||||
nvlist_xdescriptors(const nvlist_t *nvl, int *descs, int level) | nvlist_xdescriptors(const nvlist_t *nvl, int *descs, int level) | ||||
{ | { | ||||
const nvpair_t *nvp; | const nvpair_t *nvp; | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
PJDLOG_ASSERT(nvl->nvl_error == 0); | PJDLOG_ASSERT(nvl->nvl_error == 0); | ||||
PJDLOG_ASSERT(level < 3); | PJDLOG_ASSERT(level < 3); | ||||
Show All 9 Lines | case NV_TYPE_NVLIST: | ||||
descs = nvlist_xdescriptors(nvpair_get_nvlist(nvp), | descs = nvlist_xdescriptors(nvpair_get_nvlist(nvp), | ||||
descs, level + 1); | descs, level + 1); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
return (descs); | return (descs); | ||||
} | } | ||||
#endif | |||||
#ifndef _KERNEL | |||||
int * | int * | ||||
nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp) | nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp) | ||||
{ | { | ||||
size_t nitems; | size_t nitems; | ||||
int *fds; | int *fds; | ||||
nitems = nvlist_ndescriptors(nvl); | nitems = nvlist_ndescriptors(nvl); | ||||
fds = malloc(sizeof(fds[0]) * (nitems + 1)); | fds = nv_malloc(sizeof(fds[0]) * (nitems + 1)); | ||||
if (fds == NULL) | if (fds == NULL) | ||||
return (NULL); | return (NULL); | ||||
if (nitems > 0) | if (nitems > 0) | ||||
nvlist_xdescriptors(nvl, fds, 0); | nvlist_xdescriptors(nvl, fds, 0); | ||||
fds[nitems] = -1; | fds[nitems] = -1; | ||||
if (nitemsp != NULL) | if (nitemsp != NULL) | ||||
*nitemsp = nitems; | *nitemsp = nitems; | ||||
return (fds); | return (fds); | ||||
} | } | ||||
#endif | |||||
static size_t | static size_t | ||||
nvlist_xndescriptors(const nvlist_t *nvl, int level) | nvlist_xndescriptors(const nvlist_t *nvl, int level) | ||||
{ | { | ||||
#ifndef _KERNEL | |||||
const nvpair_t *nvp; | const nvpair_t *nvp; | ||||
size_t ndescs; | size_t ndescs; | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
PJDLOG_ASSERT(nvl->nvl_error == 0); | PJDLOG_ASSERT(nvl->nvl_error == 0); | ||||
PJDLOG_ASSERT(level < 3); | PJDLOG_ASSERT(level < 3); | ||||
ndescs = 0; | ndescs = 0; | ||||
for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; | for (nvp = nvlist_first_nvpair(nvl); nvp != NULL; | ||||
nvp = nvlist_next_nvpair(nvl, nvp)) { | nvp = nvlist_next_nvpair(nvl, nvp)) { | ||||
switch (nvpair_type(nvp)) { | switch (nvpair_type(nvp)) { | ||||
case NV_TYPE_DESCRIPTOR: | case NV_TYPE_DESCRIPTOR: | ||||
ndescs++; | ndescs++; | ||||
break; | break; | ||||
case NV_TYPE_NVLIST: | case NV_TYPE_NVLIST: | ||||
ndescs += nvlist_xndescriptors(nvpair_get_nvlist(nvp), | ndescs += nvlist_xndescriptors(nvpair_get_nvlist(nvp), | ||||
level + 1); | level + 1); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
return (ndescs); | return (ndescs); | ||||
#else | |||||
return (0); | |||||
#endif | |||||
} | } | ||||
size_t | size_t | ||||
nvlist_ndescriptors(const nvlist_t *nvl) | nvlist_ndescriptors(const nvlist_t *nvl) | ||||
{ | { | ||||
return (nvlist_xndescriptors(nvl, 0)); | return (nvlist_xndescriptors(nvl, 0)); | ||||
} | } | ||||
Show All 28 Lines | nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep) | ||||
size_t left, size; | size_t left, size; | ||||
const nvlist_t *tmpnvl; | const nvlist_t *tmpnvl; | ||||
nvpair_t *nvp, *tmpnvp; | nvpair_t *nvp, *tmpnvp; | ||||
void *cookie; | void *cookie; | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
if (nvl->nvl_error != 0) { | if (nvl->nvl_error != 0) { | ||||
errno = nvl->nvl_error; | RESTORE_ERRNO(nvl->nvl_error); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
size = nvlist_size(nvl); | size = nvlist_size(nvl); | ||||
buf = malloc(size); | buf = nv_malloc(size); | ||||
if (buf == NULL) | if (buf == NULL) | ||||
return (NULL); | return (NULL); | ||||
ptr = buf; | ptr = buf; | ||||
left = size; | left = size; | ||||
ptr = nvlist_pack_header(nvl, ptr, &left); | ptr = nvlist_pack_header(nvl, ptr, &left); | ||||
nvp = nvlist_first_nvpair(nvl); | nvp = nvlist_first_nvpair(nvl); | ||||
while (nvp != NULL) { | while (nvp != NULL) { | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
nvpair_init_datasize(nvp); | nvpair_init_datasize(nvp); | ||||
ptr = nvpair_pack_header(nvp, ptr, &left); | ptr = nvpair_pack_header(nvp, ptr, &left); | ||||
if (ptr == NULL) { | if (ptr == NULL) { | ||||
free(buf); | nv_free(buf); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
switch (nvpair_type(nvp)) { | switch (nvpair_type(nvp)) { | ||||
case NV_TYPE_NULL: | case NV_TYPE_NULL: | ||||
ptr = nvpair_pack_null(nvp, ptr, &left); | ptr = nvpair_pack_null(nvp, ptr, &left); | ||||
break; | break; | ||||
case NV_TYPE_BOOL: | case NV_TYPE_BOOL: | ||||
ptr = nvpair_pack_bool(nvp, ptr, &left); | ptr = nvpair_pack_bool(nvp, ptr, &left); | ||||
Show All 12 Lines | case NV_TYPE_NVLIST: | ||||
tmpnvp = nvlist_first_nvpair(tmpnvl); | tmpnvp = nvlist_first_nvpair(tmpnvl); | ||||
if (tmpnvp != NULL) { | if (tmpnvp != NULL) { | ||||
nvl = tmpnvl; | nvl = tmpnvl; | ||||
nvp = tmpnvp; | nvp = tmpnvp; | ||||
continue; | continue; | ||||
} | } | ||||
ptr = nvpair_pack_nvlist_up(ptr, &left); | ptr = nvpair_pack_nvlist_up(ptr, &left); | ||||
break; | break; | ||||
#ifndef _KERNEL | |||||
case NV_TYPE_DESCRIPTOR: | case NV_TYPE_DESCRIPTOR: | ||||
ptr = nvpair_pack_descriptor(nvp, ptr, fdidxp, &left); | ptr = nvpair_pack_descriptor(nvp, ptr, fdidxp, &left); | ||||
break; | break; | ||||
#endif | |||||
case NV_TYPE_BINARY: | case NV_TYPE_BINARY: | ||||
ptr = nvpair_pack_binary(nvp, ptr, &left); | ptr = nvpair_pack_binary(nvp, ptr, &left); | ||||
break; | break; | ||||
default: | default: | ||||
PJDLOG_ABORT("Invalid type (%d).", nvpair_type(nvp)); | PJDLOG_ABORT("Invalid type (%d).", nvpair_type(nvp)); | ||||
} | } | ||||
if (ptr == NULL) { | if (ptr == NULL) { | ||||
free(buf); | nv_free(buf); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) { | while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) { | ||||
cookie = NULL; | cookie = NULL; | ||||
nvl = nvlist_get_parent(nvl, &cookie); | nvl = nvlist_get_parent(nvl, &cookie); | ||||
if (nvl == NULL) | if (nvl == NULL) | ||||
goto out; | goto out; | ||||
nvp = cookie; | nvp = cookie; | ||||
Show All 11 Lines | |||||
void * | void * | ||||
nvlist_pack(const nvlist_t *nvl, size_t *sizep) | nvlist_pack(const nvlist_t *nvl, size_t *sizep) | ||||
{ | { | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
if (nvl->nvl_error != 0) { | if (nvl->nvl_error != 0) { | ||||
errno = nvl->nvl_error; | RESTORE_ERRNO(nvl->nvl_error); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (nvlist_ndescriptors(nvl) > 0) { | if (nvlist_ndescriptors(nvl) > 0) { | ||||
errno = EOPNOTSUPP; | RESTORE_ERRNO(EOPNOTSUPP); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
return (nvlist_xpack(nvl, NULL, sizep)); | return (nvlist_xpack(nvl, NULL, sizep)); | ||||
} | } | ||||
static bool | static bool | ||||
nvlist_check_header(struct nvlist_header *nvlhdrp) | nvlist_check_header(struct nvlist_header *nvlhdrp) | ||||
{ | { | ||||
if (nvlhdrp->nvlh_magic != NVLIST_HEADER_MAGIC) { | if (nvlhdrp->nvlh_magic != NVLIST_HEADER_MAGIC) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (false); | return (false); | ||||
} | } | ||||
if ((nvlhdrp->nvlh_flags & ~NV_FLAG_ALL_MASK) != 0) { | if ((nvlhdrp->nvlh_flags & ~NV_FLAG_ALL_MASK) != 0) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (false); | return (false); | ||||
} | } | ||||
#if BYTE_ORDER == BIG_ENDIAN | #if BYTE_ORDER == BIG_ENDIAN | ||||
if ((nvlhdrp->nvlh_flags & NV_FLAG_BIG_ENDIAN) == 0) { | if ((nvlhdrp->nvlh_flags & NV_FLAG_BIG_ENDIAN) == 0) { | ||||
nvlhdrp->nvlh_size = le64toh(nvlhdrp->nvlh_size); | nvlhdrp->nvlh_size = le64toh(nvlhdrp->nvlh_size); | ||||
nvlhdrp->nvlh_descriptors = le64toh(nvlhdrp->nvlh_descriptors); | nvlhdrp->nvlh_descriptors = le64toh(nvlhdrp->nvlh_descriptors); | ||||
} | } | ||||
#else | #else | ||||
Show All 35 Lines | nvlist_unpack_header(nvlist_t *nvl, const unsigned char *ptr, size_t nfds, | ||||
ptr += sizeof(nvlhdr); | ptr += sizeof(nvlhdr); | ||||
if (isbep != NULL) | if (isbep != NULL) | ||||
*isbep = (((int)nvlhdr.nvlh_flags & NV_FLAG_BIG_ENDIAN) != 0); | *isbep = (((int)nvlhdr.nvlh_flags & NV_FLAG_BIG_ENDIAN) != 0); | ||||
*leftp -= sizeof(nvlhdr); | *leftp -= sizeof(nvlhdr); | ||||
return (ptr); | return (ptr); | ||||
failed: | failed: | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvlist_t * | nvlist_t * | ||||
nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds) | nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds) | ||||
{ | { | ||||
const unsigned char *ptr; | const unsigned char *ptr; | ||||
nvlist_t *nvl, *retnvl, *tmpnvl; | nvlist_t *nvl, *retnvl, *tmpnvl; | ||||
Show All 30 Lines | while (left > 0) { | ||||
case NV_TYPE_STRING: | case NV_TYPE_STRING: | ||||
ptr = nvpair_unpack_string(isbe, nvp, ptr, &left); | ptr = nvpair_unpack_string(isbe, nvp, ptr, &left); | ||||
break; | break; | ||||
case NV_TYPE_NVLIST: | case NV_TYPE_NVLIST: | ||||
ptr = nvpair_unpack_nvlist(isbe, nvp, ptr, &left, nfds, | ptr = nvpair_unpack_nvlist(isbe, nvp, ptr, &left, nfds, | ||||
&tmpnvl); | &tmpnvl); | ||||
nvlist_set_parent(tmpnvl, nvp); | nvlist_set_parent(tmpnvl, nvp); | ||||
break; | break; | ||||
#ifndef _KERNEL | |||||
case NV_TYPE_DESCRIPTOR: | case NV_TYPE_DESCRIPTOR: | ||||
ptr = nvpair_unpack_descriptor(isbe, nvp, ptr, &left, | ptr = nvpair_unpack_descriptor(isbe, nvp, ptr, &left, | ||||
fds, nfds); | fds, nfds); | ||||
break; | break; | ||||
#endif | |||||
case NV_TYPE_BINARY: | case NV_TYPE_BINARY: | ||||
ptr = nvpair_unpack_binary(isbe, nvp, ptr, &left); | ptr = nvpair_unpack_binary(isbe, nvp, ptr, &left); | ||||
break; | break; | ||||
case NV_TYPE_NVLIST_UP: | case NV_TYPE_NVLIST_UP: | ||||
if (nvl->nvl_parent == NULL) | if (nvl->nvl_parent == NULL) | ||||
goto failed; | goto failed; | ||||
nvl = nvpair_nvlist(nvl->nvl_parent); | nvl = nvpair_nvlist(nvl->nvl_parent); | ||||
continue; | continue; | ||||
Show All 17 Lines | |||||
nvlist_t * | nvlist_t * | ||||
nvlist_unpack(const void *buf, size_t size) | nvlist_unpack(const void *buf, size_t size) | ||||
{ | { | ||||
return (nvlist_xunpack(buf, size, NULL, 0)); | return (nvlist_xunpack(buf, size, NULL, 0)); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
int | int | ||||
nvlist_send(int sock, const nvlist_t *nvl) | nvlist_send(int sock, const nvlist_t *nvl) | ||||
{ | { | ||||
size_t datasize, nfds; | size_t datasize, nfds; | ||||
int *fds; | int *fds; | ||||
void *data; | void *data; | ||||
int64_t fdidx; | int64_t fdidx; | ||||
int serrno, ret; | int serrno, ret; | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | nvlist_xfer(int sock, nvlist_t *nvl) | ||||
if (nvlist_send(sock, nvl) < 0) { | if (nvlist_send(sock, nvl) < 0) { | ||||
nvlist_destroy(nvl); | nvlist_destroy(nvl); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvlist_destroy(nvl); | nvlist_destroy(nvl); | ||||
return (nvlist_recv(sock)); | return (nvlist_recv(sock)); | ||||
} | } | ||||
#endif | |||||
nvpair_t * | nvpair_t * | ||||
nvlist_first_nvpair(const nvlist_t *nvl) | nvlist_first_nvpair(const nvlist_t *nvl) | ||||
{ | { | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
return (TAILQ_FIRST(&nvl->nvl_head)); | return (TAILQ_FIRST(&nvl->nvl_head)); | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | nvlist_exists_##type(const nvlist_t *nvl, const char *name) \ | ||||
return (nvlist_find(nvl, NV_TYPE_##TYPE, name) != NULL); \ | return (nvlist_find(nvl, NV_TYPE_##TYPE, name) != NULL); \ | ||||
} | } | ||||
NVLIST_EXISTS(null, NULL) | NVLIST_EXISTS(null, NULL) | ||||
NVLIST_EXISTS(bool, BOOL) | NVLIST_EXISTS(bool, BOOL) | ||||
NVLIST_EXISTS(number, NUMBER) | NVLIST_EXISTS(number, NUMBER) | ||||
NVLIST_EXISTS(string, STRING) | NVLIST_EXISTS(string, STRING) | ||||
NVLIST_EXISTS(nvlist, NVLIST) | NVLIST_EXISTS(nvlist, NVLIST) | ||||
#ifndef _KERNEL | |||||
NVLIST_EXISTS(descriptor, DESCRIPTOR) | NVLIST_EXISTS(descriptor, DESCRIPTOR) | ||||
#endif | |||||
NVLIST_EXISTS(binary, BINARY) | NVLIST_EXISTS(binary, BINARY) | ||||
#undef NVLIST_EXISTS | #undef NVLIST_EXISTS | ||||
#ifndef _KERNEL | |||||
bool | bool | ||||
nvlist_existsf(const nvlist_t *nvl, const char *namefmt, ...) | nvlist_existsf(const nvlist_t *nvl, const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
bool ret; | bool ret; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
ret = nvlist_existsv(nvl, namefmt, nameap); | ret = nvlist_existsv(nvl, namefmt, nameap); | ||||
Show All 14 Lines | nvlist_existsf_##type(const nvlist_t *nvl, const char *namefmt, ...) \ | ||||
return (ret); \ | return (ret); \ | ||||
} | } | ||||
NVLIST_EXISTSF(null) | NVLIST_EXISTSF(null) | ||||
NVLIST_EXISTSF(bool) | NVLIST_EXISTSF(bool) | ||||
NVLIST_EXISTSF(number) | NVLIST_EXISTSF(number) | ||||
NVLIST_EXISTSF(string) | NVLIST_EXISTSF(string) | ||||
NVLIST_EXISTSF(nvlist) | NVLIST_EXISTSF(nvlist) | ||||
#ifndef _KERNEL | |||||
NVLIST_EXISTSF(descriptor) | NVLIST_EXISTSF(descriptor) | ||||
#endif | |||||
NVLIST_EXISTSF(binary) | NVLIST_EXISTSF(binary) | ||||
#undef NVLIST_EXISTSF | #undef NVLIST_EXISTSF | ||||
bool | bool | ||||
nvlist_existsv(const nvlist_t *nvl, const char *namefmt, va_list nameap) | nvlist_existsv(const nvlist_t *nvl, const char *namefmt, va_list nameap) | ||||
{ | { | ||||
char *name; | char *name; | ||||
bool exists; | bool exists; | ||||
vasprintf(&name, namefmt, nameap); | nv_vasprintf(&name, namefmt, nameap); | ||||
if (name == NULL) | if (name == NULL) | ||||
return (false); | return (false); | ||||
exists = nvlist_exists(nvl, name); | exists = nvlist_exists(nvl, name); | ||||
free(name); | nv_free(name); | ||||
return (exists); | return (exists); | ||||
} | } | ||||
#define NVLIST_EXISTSV(type) \ | #define NVLIST_EXISTSV(type) \ | ||||
bool \ | bool \ | ||||
nvlist_existsv_##type(const nvlist_t *nvl, const char *namefmt, \ | nvlist_existsv_##type(const nvlist_t *nvl, const char *namefmt, \ | ||||
va_list nameap) \ | va_list nameap) \ | ||||
{ \ | { \ | ||||
Show All 12 Lines | |||||
NVLIST_EXISTSV(bool) | NVLIST_EXISTSV(bool) | ||||
NVLIST_EXISTSV(number) | NVLIST_EXISTSV(number) | ||||
NVLIST_EXISTSV(string) | NVLIST_EXISTSV(string) | ||||
NVLIST_EXISTSV(nvlist) | NVLIST_EXISTSV(nvlist) | ||||
NVLIST_EXISTSV(descriptor) | NVLIST_EXISTSV(descriptor) | ||||
NVLIST_EXISTSV(binary) | NVLIST_EXISTSV(binary) | ||||
#undef NVLIST_EXISTSV | #undef NVLIST_EXISTSV | ||||
#endif | |||||
void | void | ||||
nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp) | nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp) | ||||
{ | { | ||||
nvpair_t *newnvp; | nvpair_t *newnvp; | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
if (nvlist_exists(nvl, nvpair_name(nvp))) { | if (nvlist_exists(nvl, nvpair_name(nvp))) { | ||||
nvl->nvl_error = errno = EEXIST; | nvl->nvl_error = EEXIST; | ||||
RESTORE_ERRNO(nvlist_error(nvl)); | |||||
return; | return; | ||||
} | } | ||||
newnvp = nvpair_clone(nvp); | newnvp = nvpair_clone(nvp); | ||||
if (newnvp == NULL) { | if (newnvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
RESTORE_ERRNO(nvlist_error(nvl)); | |||||
return; | return; | ||||
} | } | ||||
nvpair_insert(&nvl->nvl_head, newnvp, nvl); | nvpair_insert(&nvl->nvl_head, newnvp, nvl); | ||||
} | } | ||||
void | void | ||||
nvlist_add_null(nvlist_t *nvl, const char *name) | nvlist_add_null(nvlist_t *nvl, const char *name) | ||||
Show All 35 Lines | |||||
void | void | ||||
nvlist_add_stringv(nvlist_t *nvl, const char *name, const char *valuefmt, | nvlist_add_stringv(nvlist_t *nvl, const char *name, const char *valuefmt, | ||||
va_list valueap) | va_list valueap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_create_stringv(name, valuefmt, valueap); | nvp = nvpair_create_stringv(name, valuefmt, valueap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
void | void | ||||
nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value) | nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value) | ||||
{ | { | ||||
nvlist_addf_nvlist(nvl, value, "%s", name); | nvlist_addf_nvlist(nvl, value, "%s", name); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
void | void | ||||
nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value) | nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value) | ||||
{ | { | ||||
nvlist_addf_descriptor(nvl, value, "%s", name); | nvlist_addf_descriptor(nvl, value, "%s", name); | ||||
} | } | ||||
#endif | |||||
void | void | ||||
nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value, | nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value, | ||||
size_t size) | size_t size) | ||||
{ | { | ||||
nvlist_addf_binary(nvl, value, size, "%s", name); | nvlist_addf_binary(nvl, value, size, "%s", name); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvlist_addv_nvlist(nvl, value, namefmt, nameap); | nvlist_addv_nvlist(nvl, value, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
void | void | ||||
nvlist_addf_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...) | nvlist_addf_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvlist_addv_descriptor(nvl, value, namefmt, nameap); | nvlist_addv_descriptor(nvl, value, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
} | } | ||||
#endif | |||||
void | void | ||||
nvlist_addf_binary(nvlist_t *nvl, const void *value, size_t size, | nvlist_addf_binary(nvlist_t *nvl, const void *value, size_t size, | ||||
const char *namefmt, ...) | const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvlist_addv_binary(nvl, value, size, namefmt, nameap); | nvlist_addv_binary(nvl, value, size, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
} | } | ||||
void | void | ||||
nvlist_addv_null(nvlist_t *nvl, const char *namefmt, va_list nameap) | nvlist_addv_null(nvlist_t *nvl, const char *namefmt, va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_createv_null(namefmt, nameap); | nvp = nvpair_createv_null(namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
void | void | ||||
nvlist_addv_bool(nvlist_t *nvl, bool value, const char *namefmt, va_list nameap) | nvlist_addv_bool(nvlist_t *nvl, bool value, const char *namefmt, va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_createv_bool(value, namefmt, nameap); | nvp = nvpair_createv_bool(value, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
void | void | ||||
nvlist_addv_number(nvlist_t *nvl, uint64_t value, const char *namefmt, | nvlist_addv_number(nvlist_t *nvl, uint64_t value, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_createv_number(value, namefmt, nameap); | nvp = nvpair_createv_number(value, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
void | void | ||||
nvlist_addv_string(nvlist_t *nvl, const char *value, const char *namefmt, | nvlist_addv_string(nvlist_t *nvl, const char *value, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_createv_string(value, namefmt, nameap); | nvp = nvpair_createv_string(value, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
void | void | ||||
nvlist_addv_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, | nvlist_addv_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_createv_nvlist(value, namefmt, nameap); | nvp = nvpair_createv_nvlist(value, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
void | void | ||||
nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt, | nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
errno = nvlist_error(nvl); | errno = nvlist_error(nvl); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_createv_descriptor(value, namefmt, nameap); | nvp = nvpair_createv_descriptor(value, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | ||||
else | else | ||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
#endif | |||||
void | void | ||||
nvlist_addv_binary(nvlist_t *nvl, const void *value, size_t size, | nvlist_addv_binary(nvlist_t *nvl, const void *value, size_t size, | ||||
const char *namefmt, va_list nameap) | const char *namefmt, va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_createv_binary(value, size, namefmt, nameap); | nvp = nvpair_createv_binary(value, size, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
void | void | ||||
nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp) | nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp) | ||||
{ | { | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvpair_nvlist(nvp) == NULL); | PJDLOG_ASSERT(nvpair_nvlist(nvp) == NULL); | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
nvpair_free(nvp); | nvpair_free(nvp); | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
if (nvlist_exists(nvl, nvpair_name(nvp))) { | if (nvlist_exists(nvl, nvpair_name(nvp))) { | ||||
nvpair_free(nvp); | nvpair_free(nvp); | ||||
nvl->nvl_error = errno = EEXIST; | nvl->nvl_error = EEXIST; | ||||
RESTORE_ERRNO(nvl->nvl_error); | |||||
return; | return; | ||||
} | } | ||||
nvpair_insert(&nvl->nvl_head, nvp, nvl); | nvpair_insert(&nvl->nvl_head, nvp, nvl); | ||||
} | } | ||||
#define NVLIST_MOVE(vtype, type) \ | #define NVLIST_MOVE(vtype, type) \ | ||||
void \ | void \ | ||||
nvlist_move_##type(nvlist_t *nvl, const char *name, vtype value) \ | nvlist_move_##type(nvlist_t *nvl, const char *name, vtype value) \ | ||||
{ \ | { \ | ||||
\ | \ | ||||
nvlist_movef_##type(nvl, value, "%s", name); \ | nvlist_movef_##type(nvl, value, "%s", name); \ | ||||
} | } | ||||
NVLIST_MOVE(char *, string) | NVLIST_MOVE(char *, string) | ||||
NVLIST_MOVE(nvlist_t *, nvlist) | NVLIST_MOVE(nvlist_t *, nvlist) | ||||
#ifndef _KERNEL | |||||
NVLIST_MOVE(int, descriptor) | NVLIST_MOVE(int, descriptor) | ||||
#endif | |||||
#undef NVLIST_MOVE | #undef NVLIST_MOVE | ||||
void | void | ||||
nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size) | nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size) | ||||
{ | { | ||||
nvlist_movef_binary(nvl, value, size, "%s", name); | nvlist_movef_binary(nvl, value, size, "%s", name); | ||||
} | } | ||||
#define NVLIST_MOVEF(vtype, type) \ | #define NVLIST_MOVEF(vtype, type) \ | ||||
void \ | void \ | ||||
nvlist_movef_##type(nvlist_t *nvl, vtype value, const char *namefmt, \ | nvlist_movef_##type(nvlist_t *nvl, vtype value, const char *namefmt, \ | ||||
...) \ | ...) \ | ||||
{ \ | { \ | ||||
va_list nameap; \ | va_list nameap; \ | ||||
\ | \ | ||||
va_start(nameap, namefmt); \ | va_start(nameap, namefmt); \ | ||||
nvlist_movev_##type(nvl, value, namefmt, nameap); \ | nvlist_movev_##type(nvl, value, namefmt, nameap); \ | ||||
va_end(nameap); \ | va_end(nameap); \ | ||||
} | } | ||||
NVLIST_MOVEF(char *, string) | NVLIST_MOVEF(char *, string) | ||||
NVLIST_MOVEF(nvlist_t *, nvlist) | NVLIST_MOVEF(nvlist_t *, nvlist) | ||||
#ifndef _KERNEL | |||||
NVLIST_MOVEF(int, descriptor) | NVLIST_MOVEF(int, descriptor) | ||||
#endif | |||||
#undef NVLIST_MOVEF | #undef NVLIST_MOVEF | ||||
void | void | ||||
nvlist_movef_binary(nvlist_t *nvl, void *value, size_t size, | nvlist_movef_binary(nvlist_t *nvl, void *value, size_t size, | ||||
const char *namefmt, ...) | const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvlist_movev_binary(nvl, value, size, namefmt, nameap); | nvlist_movev_binary(nvl, value, size, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
} | } | ||||
void | void | ||||
nvlist_movev_string(nvlist_t *nvl, char *value, const char *namefmt, | nvlist_movev_string(nvlist_t *nvl, char *value, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
free(value); | nv_free(value); | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_movev_string(value, namefmt, nameap); | nvp = nvpair_movev_string(value, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
void | void | ||||
nvlist_movev_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt, | nvlist_movev_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
if (value != NULL && nvlist_get_nvpair_parent(value) != NULL) | if (value != NULL && nvlist_get_nvpair_parent(value) != NULL) | ||||
nvlist_destroy(value); | nvlist_destroy(value); | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_movev_nvlist(value, namefmt, nameap); | nvp = nvpair_movev_nvlist(value, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
void | void | ||||
nvlist_movev_descriptor(nvlist_t *nvl, int value, const char *namefmt, | nvlist_movev_descriptor(nvlist_t *nvl, int value, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
close(value); | close(value); | ||||
errno = nvlist_error(nvl); | errno = nvlist_error(nvl); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_movev_descriptor(value, namefmt, nameap); | nvp = nvpair_movev_descriptor(value, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | ||||
else | else | ||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
#endif | |||||
void | void | ||||
nvlist_movev_binary(nvlist_t *nvl, void *value, size_t size, | nvlist_movev_binary(nvlist_t *nvl, void *value, size_t size, | ||||
const char *namefmt, va_list nameap) | const char *namefmt, va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (nvlist_error(nvl) != 0) { | if (nvlist_error(nvl) != 0) { | ||||
free(value); | nv_free(value); | ||||
errno = nvlist_error(nvl); | RESTORE_ERRNO(nvlist_error(nvl)); | ||||
return; | return; | ||||
} | } | ||||
nvp = nvpair_movev_binary(value, size, namefmt, nameap); | nvp = nvpair_movev_binary(value, size, namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) { | ||||
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM); | nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); | ||||
else | RESTORE_ERRNO(nvl->nvl_error); | ||||
} else | |||||
nvlist_move_nvpair(nvl, nvp); | nvlist_move_nvpair(nvl, nvp); | ||||
} | } | ||||
const nvpair_t * | const nvpair_t * | ||||
nvlist_get_nvpair(const nvlist_t *nvl, const char *name) | nvlist_get_nvpair(const nvlist_t *nvl, const char *name) | ||||
{ | { | ||||
return (nvlist_find(nvl, NV_TYPE_NONE, name)); | return (nvlist_find(nvl, NV_TYPE_NONE, name)); | ||||
Show All 10 Lines | if (nvp == NULL) \ | ||||
nvlist_report_missing(NV_TYPE_##TYPE, name); \ | nvlist_report_missing(NV_TYPE_##TYPE, name); \ | ||||
return (nvpair_get_##type(nvp)); \ | return (nvpair_get_##type(nvp)); \ | ||||
} | } | ||||
NVLIST_GET(bool, bool, BOOL) | NVLIST_GET(bool, bool, BOOL) | ||||
NVLIST_GET(uint64_t, number, NUMBER) | NVLIST_GET(uint64_t, number, NUMBER) | ||||
NVLIST_GET(const char *, string, STRING) | NVLIST_GET(const char *, string, STRING) | ||||
NVLIST_GET(const nvlist_t *, nvlist, NVLIST) | NVLIST_GET(const nvlist_t *, nvlist, NVLIST) | ||||
#ifndef _KERNEL | |||||
NVLIST_GET(int, descriptor, DESCRIPTOR) | NVLIST_GET(int, descriptor, DESCRIPTOR) | ||||
#endif | |||||
#undef NVLIST_GET | #undef NVLIST_GET | ||||
const void * | const void * | ||||
nvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep) | nvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
Show All 13 Lines | ftype value; \ | ||||
\ | \ | ||||
va_start(nameap, namefmt); \ | va_start(nameap, namefmt); \ | ||||
value = nvlist_getv_##type(nvl, namefmt, nameap); \ | value = nvlist_getv_##type(nvl, namefmt, nameap); \ | ||||
va_end(nameap); \ | va_end(nameap); \ | ||||
\ | \ | ||||
return (value); \ | return (value); \ | ||||
} | } | ||||
#ifndef _KERNEL | |||||
NVLIST_GETF(bool, bool) | NVLIST_GETF(bool, bool) | ||||
NVLIST_GETF(uint64_t, number) | NVLIST_GETF(uint64_t, number) | ||||
NVLIST_GETF(const char *, string) | NVLIST_GETF(const char *, string) | ||||
NVLIST_GETF(const nvlist_t *, nvlist) | NVLIST_GETF(const nvlist_t *, nvlist) | ||||
NVLIST_GETF(int, descriptor) | NVLIST_GETF(int, descriptor) | ||||
#undef NVLIST_GETF | #undef NVLIST_GETF | ||||
Show All 37 Lines | |||||
const void * | const void * | ||||
nvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, | nvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
char *name; | char *name; | ||||
const void *binary; | const void *binary; | ||||
vasprintf(&name, namefmt, nameap); | nv_vasprintf(&name, namefmt, nameap); | ||||
if (name == NULL) | if (name == NULL) | ||||
nvlist_report_missing(NV_TYPE_BINARY, "<unknown>"); | nvlist_report_missing(NV_TYPE_BINARY, "<unknown>"); | ||||
binary = nvlist_get_binary(nvl, name, sizep); | binary = nvlist_get_binary(nvl, name, sizep); | ||||
free(name); | nv_free(name); | ||||
return (binary); | return (binary); | ||||
} | } | ||||
#endif | |||||
#define NVLIST_TAKE(ftype, type, TYPE) \ | #define NVLIST_TAKE(ftype, type, TYPE) \ | ||||
ftype \ | ftype \ | ||||
nvlist_take_##type(nvlist_t *nvl, const char *name) \ | nvlist_take_##type(nvlist_t *nvl, const char *name) \ | ||||
{ \ | { \ | ||||
nvpair_t *nvp; \ | nvpair_t *nvp; \ | ||||
ftype value; \ | ftype value; \ | ||||
\ | \ | ||||
nvp = nvlist_find(nvl, NV_TYPE_##TYPE, name); \ | nvp = nvlist_find(nvl, NV_TYPE_##TYPE, name); \ | ||||
if (nvp == NULL) \ | if (nvp == NULL) \ | ||||
nvlist_report_missing(NV_TYPE_##TYPE, name); \ | nvlist_report_missing(NV_TYPE_##TYPE, name); \ | ||||
value = (ftype)(intptr_t)nvpair_get_##type(nvp); \ | value = (ftype)(intptr_t)nvpair_get_##type(nvp); \ | ||||
nvlist_remove_nvpair(nvl, nvp); \ | nvlist_remove_nvpair(nvl, nvp); \ | ||||
nvpair_free_structure(nvp); \ | nvpair_free_structure(nvp); \ | ||||
return (value); \ | return (value); \ | ||||
} | } | ||||
NVLIST_TAKE(bool, bool, BOOL) | NVLIST_TAKE(bool, bool, BOOL) | ||||
NVLIST_TAKE(uint64_t, number, NUMBER) | NVLIST_TAKE(uint64_t, number, NUMBER) | ||||
NVLIST_TAKE(char *, string, STRING) | NVLIST_TAKE(char *, string, STRING) | ||||
NVLIST_TAKE(nvlist_t *, nvlist, NVLIST) | NVLIST_TAKE(nvlist_t *, nvlist, NVLIST) | ||||
#ifndef _KERNEL | |||||
NVLIST_TAKE(int, descriptor, DESCRIPTOR) | NVLIST_TAKE(int, descriptor, DESCRIPTOR) | ||||
#endif | |||||
#undef NVLIST_TAKE | #undef NVLIST_TAKE | ||||
void * | void * | ||||
nvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep) | nvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
void *value; | void *value; | ||||
Show All 17 Lines | ftype value; \ | ||||
\ | \ | ||||
va_start(nameap, namefmt); \ | va_start(nameap, namefmt); \ | ||||
value = nvlist_takev_##type(nvl, namefmt, nameap); \ | value = nvlist_takev_##type(nvl, namefmt, nameap); \ | ||||
va_end(nameap); \ | va_end(nameap); \ | ||||
\ | \ | ||||
return (value); \ | return (value); \ | ||||
} | } | ||||
#ifndef _KERNEL | |||||
NVLIST_TAKEF(bool, bool) | NVLIST_TAKEF(bool, bool) | ||||
NVLIST_TAKEF(uint64_t, number) | NVLIST_TAKEF(uint64_t, number) | ||||
NVLIST_TAKEF(char *, string) | NVLIST_TAKEF(char *, string) | ||||
NVLIST_TAKEF(nvlist_t *, nvlist) | NVLIST_TAKEF(nvlist_t *, nvlist) | ||||
NVLIST_TAKEF(int, descriptor) | NVLIST_TAKEF(int, descriptor) | ||||
#undef NVLIST_TAKEF | #undef NVLIST_TAKEF | ||||
Show All 35 Lines | |||||
void * | void * | ||||
nvlist_takev_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, | nvlist_takev_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
char *name; | char *name; | ||||
void *binary; | void *binary; | ||||
vasprintf(&name, namefmt, nameap); | nv_vasprintf(&name, namefmt, nameap); | ||||
if (name == NULL) | if (name == NULL) | ||||
nvlist_report_missing(NV_TYPE_BINARY, "<unknown>"); | nvlist_report_missing(NV_TYPE_BINARY, "<unknown>"); | ||||
binary = nvlist_take_binary(nvl, name, sizep); | binary = nvlist_take_binary(nvl, name, sizep); | ||||
free(name); | nv_free(name); | ||||
return (binary); | return (binary); | ||||
} | } | ||||
#endif | |||||
void | void | ||||
nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp) | nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp) | ||||
{ | { | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl); | PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl); | ||||
Show All 16 Lines | nvlist_free_##type(nvlist_t *nvl, const char *name) \ | ||||
nvlist_free_type(nvl, name, NV_TYPE_##TYPE); \ | nvlist_free_type(nvl, name, NV_TYPE_##TYPE); \ | ||||
} | } | ||||
NVLIST_FREE(null, NULL) | NVLIST_FREE(null, NULL) | ||||
NVLIST_FREE(bool, BOOL) | NVLIST_FREE(bool, BOOL) | ||||
NVLIST_FREE(number, NUMBER) | NVLIST_FREE(number, NUMBER) | ||||
NVLIST_FREE(string, STRING) | NVLIST_FREE(string, STRING) | ||||
NVLIST_FREE(nvlist, NVLIST) | NVLIST_FREE(nvlist, NVLIST) | ||||
#ifndef _KERNEL | |||||
NVLIST_FREE(descriptor, DESCRIPTOR) | NVLIST_FREE(descriptor, DESCRIPTOR) | ||||
#endif | |||||
NVLIST_FREE(binary, BINARY) | NVLIST_FREE(binary, BINARY) | ||||
#undef NVLIST_FREE | #undef NVLIST_FREE | ||||
#ifndef _KERNEL | |||||
void | void | ||||
nvlist_freef(nvlist_t *nvl, const char *namefmt, ...) | nvlist_freef(nvlist_t *nvl, const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvlist_freev(nvl, namefmt, nameap); | nvlist_freev(nvl, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
NVLIST_FREEV(null, NULL) | NVLIST_FREEV(null, NULL) | ||||
NVLIST_FREEV(bool, BOOL) | NVLIST_FREEV(bool, BOOL) | ||||
NVLIST_FREEV(number, NUMBER) | NVLIST_FREEV(number, NUMBER) | ||||
NVLIST_FREEV(string, STRING) | NVLIST_FREEV(string, STRING) | ||||
NVLIST_FREEV(nvlist, NVLIST) | NVLIST_FREEV(nvlist, NVLIST) | ||||
NVLIST_FREEV(descriptor, DESCRIPTOR) | NVLIST_FREEV(descriptor, DESCRIPTOR) | ||||
NVLIST_FREEV(binary, BINARY) | NVLIST_FREEV(binary, BINARY) | ||||
#undef NVLIST_FREEV | #undef NVLIST_FREEV | ||||
#endif | |||||
void | void | ||||
nvlist_free_nvpair(nvlist_t *nvl, nvpair_t *nvp) | nvlist_free_nvpair(nvlist_t *nvl, nvpair_t *nvp) | ||||
{ | { | ||||
NVLIST_ASSERT(nvl); | NVLIST_ASSERT(nvl); | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl); | PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl); | ||||
nvlist_remove_nvpair(nvl, nvp); | nvlist_remove_nvpair(nvl, nvp); | ||||
nvpair_free(nvp); | nvpair_free(nvp); | ||||
} | } |