Changeset View
Changeset View
Standalone View
Standalone View
lib/libnv/nvpair.c
Show All 28 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/lock.h> | |||||
#include <sys/malloc.h> | |||||
#include <sys/systm.h> | |||||
#include <machine/stdarg.h> | |||||
#else | |||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <stdint.h> | #include <stdint.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 "common_impl.h" | #include "common_impl.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(...) abort() | #define PJDLOG_ABORT(...) abort() | ||||
#endif | #endif | ||||
#endif | |||||
#define NVPAIR_MAGIC 0x6e7670 /* "nvp" */ | #define NVPAIR_MAGIC 0x6e7670 /* "nvp" */ | ||||
struct nvpair { | struct nvpair { | ||||
int nvp_magic; | int nvp_magic; | ||||
char *nvp_name; | char *nvp_name; | ||||
int nvp_type; | int nvp_type; | ||||
uint64_t nvp_data; | uint64_t nvp_data; | ||||
size_t nvp_datasize; | size_t nvp_datasize; | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | case NV_TYPE_NUMBER: | ||||
newnvp = nvpair_create_number(name, nvpair_get_number(nvp)); | newnvp = nvpair_create_number(name, nvpair_get_number(nvp)); | ||||
break; | break; | ||||
case NV_TYPE_STRING: | case NV_TYPE_STRING: | ||||
newnvp = nvpair_create_string(name, nvpair_get_string(nvp)); | newnvp = nvpair_create_string(name, nvpair_get_string(nvp)); | ||||
break; | break; | ||||
case NV_TYPE_NVLIST: | case NV_TYPE_NVLIST: | ||||
newnvp = nvpair_create_nvlist(name, nvpair_get_nvlist(nvp)); | newnvp = nvpair_create_nvlist(name, nvpair_get_nvlist(nvp)); | ||||
break; | break; | ||||
#ifndef _KERNEL | |||||
case NV_TYPE_DESCRIPTOR: | case NV_TYPE_DESCRIPTOR: | ||||
newnvp = nvpair_create_descriptor(name, | newnvp = nvpair_create_descriptor(name, | ||||
nvpair_get_descriptor(nvp)); | nvpair_get_descriptor(nvp)); | ||||
break; | break; | ||||
#endif | |||||
case NV_TYPE_BINARY: | case NV_TYPE_BINARY: | ||||
data = nvpair_get_binary(nvp, &datasize); | data = nvpair_get_binary(nvp, &datasize); | ||||
newnvp = nvpair_create_binary(name, data, datasize); | newnvp = nvpair_create_binary(name, data, datasize); | ||||
break; | break; | ||||
default: | default: | ||||
PJDLOG_ABORT("Unknown type: %d.", nvpair_type(nvp)); | PJDLOG_ABORT("Unknown type: %d.", nvpair_type(nvp)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | nvpair_pack_nvlist_up(unsigned char *ptr, size_t *leftp) | ||||
PJDLOG_ASSERT(*leftp >= namesize); | PJDLOG_ASSERT(*leftp >= namesize); | ||||
memcpy(ptr, name, namesize); | memcpy(ptr, name, namesize); | ||||
ptr += namesize; | ptr += namesize; | ||||
*leftp -= namesize; | *leftp -= namesize; | ||||
return (ptr); | return (ptr); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
unsigned char * | unsigned char * | ||||
nvpair_pack_descriptor(const nvpair_t *nvp, unsigned char *ptr, int64_t *fdidxp, | nvpair_pack_descriptor(const nvpair_t *nvp, unsigned char *ptr, int64_t *fdidxp, | ||||
size_t *leftp) | size_t *leftp) | ||||
{ | { | ||||
int64_t value; | int64_t value; | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR); | ||||
Show All 13 Lines | nvpair_pack_descriptor(const nvpair_t *nvp, unsigned char *ptr, int64_t *fdidxp, | ||||
PJDLOG_ASSERT(*leftp >= sizeof(value)); | PJDLOG_ASSERT(*leftp >= sizeof(value)); | ||||
memcpy(ptr, &value, sizeof(value)); | memcpy(ptr, &value, sizeof(value)); | ||||
ptr += sizeof(value); | ptr += sizeof(value); | ||||
*leftp -= sizeof(value); | *leftp -= sizeof(value); | ||||
return (ptr); | return (ptr); | ||||
} | } | ||||
#endif | |||||
unsigned char * | unsigned char * | ||||
nvpair_pack_binary(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp) | nvpair_pack_binary(const nvpair_t *nvp, unsigned char *ptr, size_t *leftp) | ||||
{ | { | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY); | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | if (*leftp < nvphdr.nvph_datasize) | ||||
goto failed; | goto failed; | ||||
nvp->nvp_type = nvphdr.nvph_type; | nvp->nvp_type = nvphdr.nvph_type; | ||||
nvp->nvp_data = 0; | nvp->nvp_data = 0; | ||||
nvp->nvp_datasize = nvphdr.nvph_datasize; | nvp->nvp_datasize = nvphdr.nvph_datasize; | ||||
return (ptr); | return (ptr); | ||||
failed: | failed: | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
const unsigned char * | const unsigned char * | ||||
nvpair_unpack_null(bool isbe __unused, nvpair_t *nvp, const unsigned char *ptr, | nvpair_unpack_null(bool isbe __unused, nvpair_t *nvp, const unsigned char *ptr, | ||||
size_t *leftp __unused) | size_t *leftp __unused) | ||||
{ | { | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NULL); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NULL); | ||||
if (nvp->nvp_datasize != 0) { | if (nvp->nvp_datasize != 0) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
return (ptr); | return (ptr); | ||||
} | } | ||||
const unsigned char * | const unsigned char * | ||||
nvpair_unpack_bool(bool isbe __unused, nvpair_t *nvp, const unsigned char *ptr, | nvpair_unpack_bool(bool isbe __unused, nvpair_t *nvp, const unsigned char *ptr, | ||||
size_t *leftp) | size_t *leftp) | ||||
{ | { | ||||
uint8_t value; | uint8_t value; | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BOOL); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BOOL); | ||||
if (nvp->nvp_datasize != sizeof(value)) { | if (nvp->nvp_datasize != sizeof(value)) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (*leftp < sizeof(value)) { | if (*leftp < sizeof(value)) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
memcpy(&value, ptr, sizeof(value)); | memcpy(&value, ptr, sizeof(value)); | ||||
ptr += sizeof(value); | ptr += sizeof(value); | ||||
*leftp -= sizeof(value); | *leftp -= sizeof(value); | ||||
if (value != 0 && value != 1) { | if (value != 0 && value != 1) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvp->nvp_data = (uint64_t)value; | nvp->nvp_data = (uint64_t)value; | ||||
return (ptr); | return (ptr); | ||||
} | } | ||||
const unsigned char * | const unsigned char * | ||||
nvpair_unpack_number(bool isbe, nvpair_t *nvp, const unsigned char *ptr, | nvpair_unpack_number(bool isbe, nvpair_t *nvp, const unsigned char *ptr, | ||||
size_t *leftp) | size_t *leftp) | ||||
{ | { | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NUMBER); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NUMBER); | ||||
if (nvp->nvp_datasize != sizeof(uint64_t)) { | if (nvp->nvp_datasize != sizeof(uint64_t)) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (*leftp < sizeof(uint64_t)) { | if (*leftp < sizeof(uint64_t)) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (isbe) | if (isbe) | ||||
nvp->nvp_data = be64dec(ptr); | nvp->nvp_data = be64dec(ptr); | ||||
else | else | ||||
nvp->nvp_data = le64dec(ptr); | nvp->nvp_data = le64dec(ptr); | ||||
ptr += sizeof(uint64_t); | ptr += sizeof(uint64_t); | ||||
*leftp -= sizeof(uint64_t); | *leftp -= sizeof(uint64_t); | ||||
return (ptr); | return (ptr); | ||||
} | } | ||||
const unsigned char * | const unsigned char * | ||||
nvpair_unpack_string(bool isbe __unused, nvpair_t *nvp, | nvpair_unpack_string(bool isbe __unused, nvpair_t *nvp, | ||||
const unsigned char *ptr, size_t *leftp) | const unsigned char *ptr, size_t *leftp) | ||||
{ | { | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING); | ||||
if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) { | if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (strnlen((const char *)ptr, nvp->nvp_datasize) != | if (strnlen((const char *)ptr, nvp->nvp_datasize) != | ||||
nvp->nvp_datasize - 1) { | nvp->nvp_datasize - 1) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvp->nvp_data = (uint64_t)(uintptr_t)strdup((const char *)ptr); | nvp->nvp_data = (uint64_t)(uintptr_t)nv_strdup((const char *)ptr); | ||||
if (nvp->nvp_data == 0) | if (nvp->nvp_data == 0) | ||||
return (NULL); | return (NULL); | ||||
ptr += nvp->nvp_datasize; | ptr += nvp->nvp_datasize; | ||||
*leftp -= nvp->nvp_datasize; | *leftp -= nvp->nvp_datasize; | ||||
return (ptr); | return (ptr); | ||||
} | } | ||||
const unsigned char * | const unsigned char * | ||||
nvpair_unpack_nvlist(bool isbe __unused, nvpair_t *nvp, | nvpair_unpack_nvlist(bool isbe __unused, nvpair_t *nvp, | ||||
const unsigned char *ptr, size_t *leftp, size_t nfds, nvlist_t **child) | const unsigned char *ptr, size_t *leftp, size_t nfds, nvlist_t **child) | ||||
{ | { | ||||
nvlist_t *value; | nvlist_t *value; | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST); | ||||
if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) { | if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
value = nvlist_create(0); | value = nvlist_create(0); | ||||
if (value == NULL) | if (value == NULL) | ||||
return (NULL); | return (NULL); | ||||
ptr = nvlist_unpack_header(value, ptr, nfds, NULL, leftp); | ptr = nvlist_unpack_header(value, ptr, nfds, NULL, leftp); | ||||
if (ptr == NULL) | if (ptr == NULL) | ||||
return (NULL); | return (NULL); | ||||
nvp->nvp_data = (uint64_t)(uintptr_t)value; | nvp->nvp_data = (uint64_t)(uintptr_t)value; | ||||
*child = value; | *child = value; | ||||
return (ptr); | return (ptr); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
const unsigned char * | const unsigned char * | ||||
nvpair_unpack_descriptor(bool isbe, nvpair_t *nvp, const unsigned char *ptr, | nvpair_unpack_descriptor(bool isbe, nvpair_t *nvp, const unsigned char *ptr, | ||||
size_t *leftp, const int *fds, size_t nfds) | size_t *leftp, const int *fds, size_t nfds) | ||||
{ | { | ||||
int64_t idx; | int64_t idx; | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR); | ||||
Show All 23 Lines | nvpair_unpack_descriptor(bool isbe, nvpair_t *nvp, const unsigned char *ptr, | ||||
nvp->nvp_data = (uint64_t)fds[idx]; | nvp->nvp_data = (uint64_t)fds[idx]; | ||||
ptr += sizeof(idx); | ptr += sizeof(idx); | ||||
*leftp -= sizeof(idx); | *leftp -= sizeof(idx); | ||||
return (ptr); | return (ptr); | ||||
} | } | ||||
#endif | |||||
const unsigned char * | const unsigned char * | ||||
nvpair_unpack_binary(bool isbe __unused, nvpair_t *nvp, | nvpair_unpack_binary(bool isbe __unused, nvpair_t *nvp, | ||||
const unsigned char *ptr, size_t *leftp) | const unsigned char *ptr, size_t *leftp) | ||||
{ | { | ||||
void *value; | void *value; | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY); | ||||
if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) { | if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
value = malloc(nvp->nvp_datasize); | value = nv_malloc(nvp->nvp_datasize); | ||||
if (value == NULL) | if (value == NULL) | ||||
return (NULL); | return (NULL); | ||||
memcpy(value, ptr, nvp->nvp_datasize); | memcpy(value, ptr, nvp->nvp_datasize); | ||||
ptr += nvp->nvp_datasize; | ptr += nvp->nvp_datasize; | ||||
*leftp -= nvp->nvp_datasize; | *leftp -= nvp->nvp_datasize; | ||||
nvp->nvp_data = (uint64_t)(uintptr_t)value; | nvp->nvp_data = (uint64_t)(uintptr_t)value; | ||||
return (ptr); | return (ptr); | ||||
} | } | ||||
const unsigned char * | const unsigned char * | ||||
nvpair_unpack(bool isbe, const unsigned char *ptr, size_t *leftp, | nvpair_unpack(bool isbe, const unsigned char *ptr, size_t *leftp, | ||||
nvpair_t **nvpp) | nvpair_t **nvpp) | ||||
{ | { | ||||
nvpair_t *nvp, *tmp; | nvpair_t *nvp, *tmp; | ||||
nvp = calloc(1, sizeof(*nvp) + NV_NAME_MAX); | nvp = nv_calloc(1, sizeof(*nvp) + NV_NAME_MAX); | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
return (NULL); | return (NULL); | ||||
nvp->nvp_name = (char *)(nvp + 1); | nvp->nvp_name = (char *)(nvp + 1); | ||||
ptr = nvpair_unpack_header(isbe, nvp, ptr, leftp); | ptr = nvpair_unpack_header(isbe, nvp, ptr, leftp); | ||||
if (ptr == NULL) | if (ptr == NULL) | ||||
goto failed; | goto failed; | ||||
tmp = realloc(nvp, sizeof(*nvp) + strlen(nvp->nvp_name) + 1); | tmp = nv_realloc(nvp, sizeof(*nvp) + strlen(nvp->nvp_name) + 1); | ||||
if (tmp == NULL) | if (tmp == NULL) | ||||
goto failed; | goto failed; | ||||
nvp = tmp; | nvp = tmp; | ||||
/* Update nvp_name after realloc(). */ | /* Update nvp_name after realloc(). */ | ||||
nvp->nvp_name = (char *)(nvp + 1); | nvp->nvp_name = (char *)(nvp + 1); | ||||
nvp->nvp_data = 0x00; | nvp->nvp_data = 0x00; | ||||
nvp->nvp_magic = NVPAIR_MAGIC; | nvp->nvp_magic = NVPAIR_MAGIC; | ||||
*nvpp = nvp; | *nvpp = nvp; | ||||
return (ptr); | return (ptr); | ||||
failed: | failed: | ||||
free(nvp); | nv_free(nvp); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
int | int | ||||
nvpair_type(const nvpair_t *nvp) | nvpair_type(const nvpair_t *nvp) | ||||
{ | { | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
Show All 15 Lines | nvpair_allocv(int type, uint64_t data, size_t datasize, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
char *name; | char *name; | ||||
int namelen; | int namelen; | ||||
PJDLOG_ASSERT(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST); | PJDLOG_ASSERT(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST); | ||||
namelen = vasprintf(&name, namefmt, nameap); | namelen = nv_vasprintf(&name, namefmt, nameap); | ||||
if (namelen < 0) | if (namelen < 0) | ||||
return (NULL); | return (NULL); | ||||
PJDLOG_ASSERT(namelen > 0); | PJDLOG_ASSERT(namelen > 0); | ||||
if (namelen >= NV_NAME_MAX) { | if (namelen >= NV_NAME_MAX) { | ||||
free(name); | nv_free(name); | ||||
errno = ENAMETOOLONG; | RESTORE_ERRNO(ENAMETOOLONG); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvp = calloc(1, sizeof(*nvp) + namelen + 1); | nvp = nv_calloc(1, sizeof(*nvp) + namelen + 1); | ||||
if (nvp != NULL) { | if (nvp != NULL) { | ||||
nvp->nvp_name = (char *)(nvp + 1); | nvp->nvp_name = (char *)(nvp + 1); | ||||
memcpy(nvp->nvp_name, name, namelen + 1); | memcpy(nvp->nvp_name, name, namelen + 1); | ||||
nvp->nvp_type = type; | nvp->nvp_type = type; | ||||
nvp->nvp_data = data; | nvp->nvp_data = data; | ||||
nvp->nvp_datasize = datasize; | nvp->nvp_datasize = datasize; | ||||
nvp->nvp_magic = NVPAIR_MAGIC; | nvp->nvp_magic = NVPAIR_MAGIC; | ||||
} | } | ||||
free(name); | nv_free(name); | ||||
return (nvp); | return (nvp); | ||||
}; | }; | ||||
nvpair_t * | nvpair_t * | ||||
nvpair_create_null(const char *name) | nvpair_create_null(const char *name) | ||||
{ | { | ||||
Show All 36 Lines | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_create_stringv(const char *name, const char *valuefmt, va_list valueap) | nvpair_create_stringv(const char *name, const char *valuefmt, va_list valueap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
char *str; | char *str; | ||||
int len; | int len; | ||||
len = vasprintf(&str, valuefmt, valueap); | len = nv_vasprintf(&str, valuefmt, valueap); | ||||
if (len < 0) | if (len < 0) | ||||
return (NULL); | return (NULL); | ||||
nvp = nvpair_create_string(name, str); | nvp = nvpair_create_string(name, str); | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
free(str); | nv_free(str); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
nvpair_t * | nvpair_t * | ||||
nvpair_create_nvlist(const char *name, const nvlist_t *value) | nvpair_create_nvlist(const char *name, const nvlist_t *value) | ||||
{ | { | ||||
return (nvpair_createf_nvlist(value, "%s", name)); | return (nvpair_createf_nvlist(value, "%s", name)); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_create_descriptor(const char *name, int value) | nvpair_create_descriptor(const char *name, int value) | ||||
{ | { | ||||
return (nvpair_createf_descriptor(value, "%s", name)); | return (nvpair_createf_descriptor(value, "%s", name)); | ||||
} | } | ||||
#endif | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_create_binary(const char *name, const void *value, size_t size) | nvpair_create_binary(const char *name, const void *value, size_t size) | ||||
{ | { | ||||
return (nvpair_createf_binary(value, size, "%s", name)); | return (nvpair_createf_binary(value, size, "%s", name)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | nvpair_createf_nvlist(const nvlist_t *value, const char *namefmt, ...) | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvp = nvpair_createv_nvlist(value, namefmt, nameap); | nvp = nvpair_createv_nvlist(value, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_createf_descriptor(int value, const char *namefmt, ...) | nvpair_createf_descriptor(int value, const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvp = nvpair_createv_descriptor(value, namefmt, nameap); | nvp = nvpair_createv_descriptor(value, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
#endif | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_createf_binary(const void *value, size_t size, const char *namefmt, ...) | nvpair_createf_binary(const void *value, size_t size, const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
Show All 29 Lines | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_createv_string(const char *value, const char *namefmt, va_list nameap) | nvpair_createv_string(const char *value, const char *namefmt, va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
size_t size; | size_t size; | ||||
char *data; | char *data; | ||||
if (value == NULL) { | if (value == NULL) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
data = strdup(value); | data = nv_strdup(value); | ||||
if (data == NULL) | if (data == NULL) | ||||
return (NULL); | return (NULL); | ||||
size = strlen(value) + 1; | size = strlen(value) + 1; | ||||
nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)data, size, | nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)data, size, | ||||
namefmt, nameap); | namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
free(data); | nv_free(data); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
nvpair_t * | nvpair_t * | ||||
nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt, | nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvlist_t *nvl; | nvlist_t *nvl; | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (value == NULL) { | if (value == NULL) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvl = nvlist_clone(value); | nvl = nvlist_clone(value); | ||||
if (nvl == NULL) | if (nvl == NULL) | ||||
return (NULL); | return (NULL); | ||||
nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)nvl, 0, | nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)nvl, 0, | ||||
namefmt, nameap); | namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
nvlist_destroy(nvl); | nvlist_destroy(nvl); | ||||
else | else | ||||
nvlist_set_parent(nvl, nvp); | nvlist_set_parent(nvl, nvp); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_createv_descriptor(int value, const char *namefmt, va_list nameap) | nvpair_createv_descriptor(int value, const char *namefmt, va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (value < 0 || !fd_is_valid(value)) { | if (value < 0 || !fd_is_valid(value)) { | ||||
errno = EBADF; | errno = EBADF; | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
value = fcntl(value, F_DUPFD_CLOEXEC, 0); | value = fcntl(value, F_DUPFD_CLOEXEC, 0); | ||||
if (value < 0) | if (value < 0) | ||||
return (NULL); | return (NULL); | ||||
nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value, | nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value, | ||||
sizeof(int64_t), namefmt, nameap); | sizeof(int64_t), namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
close(value); | close(value); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
#endif | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_createv_binary(const void *value, size_t size, const char *namefmt, | nvpair_createv_binary(const void *value, size_t size, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
void *data; | void *data; | ||||
if (value == NULL || size == 0) { | if (value == NULL || size == 0) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
data = malloc(size); | data = nv_malloc(size); | ||||
if (data == NULL) | if (data == NULL) | ||||
return (NULL); | return (NULL); | ||||
memcpy(data, value, size); | memcpy(data, value, size); | ||||
nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)data, size, | nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)data, size, | ||||
namefmt, nameap); | namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
free(data); | nv_free(data); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
nvpair_t * | nvpair_t * | ||||
nvpair_move_string(const char *name, char *value) | nvpair_move_string(const char *name, char *value) | ||||
{ | { | ||||
return (nvpair_movef_string(value, "%s", name)); | return (nvpair_movef_string(value, "%s", name)); | ||||
} | } | ||||
nvpair_t * | nvpair_t * | ||||
nvpair_move_nvlist(const char *name, nvlist_t *value) | nvpair_move_nvlist(const char *name, nvlist_t *value) | ||||
{ | { | ||||
return (nvpair_movef_nvlist(value, "%s", name)); | return (nvpair_movef_nvlist(value, "%s", name)); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_move_descriptor(const char *name, int value) | nvpair_move_descriptor(const char *name, int value) | ||||
{ | { | ||||
return (nvpair_movef_descriptor(value, "%s", name)); | return (nvpair_movef_descriptor(value, "%s", name)); | ||||
} | } | ||||
#endif | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_move_binary(const char *name, void *value, size_t size) | nvpair_move_binary(const char *name, void *value, size_t size) | ||||
{ | { | ||||
return (nvpair_movef_binary(value, size, "%s", name)); | return (nvpair_movef_binary(value, size, "%s", name)); | ||||
} | } | ||||
Show All 18 Lines | nvpair_movef_nvlist(nvlist_t *value, const char *namefmt, ...) | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvp = nvpair_movev_nvlist(value, namefmt, nameap); | nvp = nvpair_movev_nvlist(value, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_movef_descriptor(int value, const char *namefmt, ...) | nvpair_movef_descriptor(int value, const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvp = nvpair_movev_descriptor(value, namefmt, nameap); | nvp = nvpair_movev_descriptor(value, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
#endif | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_movef_binary(void *value, size_t size, const char *namefmt, ...) | nvpair_movef_binary(void *value, size_t size, const char *namefmt, ...) | ||||
{ | { | ||||
va_list nameap; | va_list nameap; | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
va_start(nameap, namefmt); | va_start(nameap, namefmt); | ||||
nvp = nvpair_movev_binary(value, size, namefmt, nameap); | nvp = nvpair_movev_binary(value, size, namefmt, nameap); | ||||
va_end(nameap); | va_end(nameap); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
nvpair_t * | nvpair_t * | ||||
nvpair_movev_string(char *value, const char *namefmt, va_list nameap) | nvpair_movev_string(char *value, const char *namefmt, va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
int serrno; | int serrno; | ||||
if (value == NULL) { | if (value == NULL) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)value, | nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)value, | ||||
strlen(value) + 1, namefmt, nameap); | strlen(value) + 1, namefmt, nameap); | ||||
if (nvp == NULL) { | if (nvp == NULL) { | ||||
serrno = errno; | SAVE_ERRNO(serrno); | ||||
free(value); | nv_free(value); | ||||
errno = serrno; | RESTORE_ERRNO(serrno); | ||||
} | } | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
nvpair_t * | nvpair_t * | ||||
nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap) | nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
if (value == NULL || nvlist_get_nvpair_parent(value) != NULL) { | if (value == NULL || nvlist_get_nvpair_parent(value) != NULL) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (nvlist_error(value) != 0) { | if (nvlist_error(value) != 0) { | ||||
errno = nvlist_error(value); | RESTORE_ERRNO(nvlist_error(value)); | ||||
nvlist_destroy(value); | nvlist_destroy(value); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)value, 0, | nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)value, 0, | ||||
namefmt, nameap); | namefmt, nameap); | ||||
if (nvp == NULL) | if (nvp == NULL) | ||||
nvlist_destroy(value); | nvlist_destroy(value); | ||||
else | else | ||||
nvlist_set_parent(value, nvp); | nvlist_set_parent(value, nvp); | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap) | nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
int serrno; | int serrno; | ||||
if (value < 0 || !fd_is_valid(value)) { | if (value < 0 || !fd_is_valid(value)) { | ||||
errno = EBADF; | errno = EBADF; | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value, | nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value, | ||||
sizeof(int64_t), namefmt, nameap); | sizeof(int64_t), namefmt, nameap); | ||||
if (nvp == NULL) { | if (nvp == NULL) { | ||||
serrno = errno; | serrno = errno; | ||||
close(value); | close(value); | ||||
errno = serrno; | errno = serrno; | ||||
} | } | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
#endif | |||||
nvpair_t * | nvpair_t * | ||||
nvpair_movev_binary(void *value, size_t size, const char *namefmt, | nvpair_movev_binary(void *value, size_t size, const char *namefmt, | ||||
va_list nameap) | va_list nameap) | ||||
{ | { | ||||
nvpair_t *nvp; | nvpair_t *nvp; | ||||
int serrno; | int serrno; | ||||
if (value == NULL || size == 0) { | if (value == NULL || size == 0) { | ||||
errno = EINVAL; | RESTORE_ERRNO(EINVAL); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)value, size, | nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)value, size, | ||||
namefmt, nameap); | namefmt, nameap); | ||||
if (nvp == NULL) { | if (nvp == NULL) { | ||||
serrno = errno; | SAVE_ERRNO(serrno); | ||||
free(value); | nv_free(value); | ||||
errno = serrno; | RESTORE_ERRNO(serrno); | ||||
} | } | ||||
return (nvp); | return (nvp); | ||||
} | } | ||||
bool | bool | ||||
nvpair_get_bool(const nvpair_t *nvp) | nvpair_get_bool(const nvpair_t *nvp) | ||||
{ | { | ||||
Show All 27 Lines | |||||
{ | { | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST); | ||||
return ((const nvlist_t *)(intptr_t)nvp->nvp_data); | return ((const nvlist_t *)(intptr_t)nvp->nvp_data); | ||||
} | } | ||||
#ifndef _KERNEL | |||||
int | int | ||||
nvpair_get_descriptor(const nvpair_t *nvp) | nvpair_get_descriptor(const nvpair_t *nvp) | ||||
{ | { | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR); | ||||
return ((int)nvp->nvp_data); | return ((int)nvp->nvp_data); | ||||
} | } | ||||
#endif | |||||
const void * | const void * | ||||
nvpair_get_binary(const nvpair_t *nvp, size_t *sizep) | nvpair_get_binary(const nvpair_t *nvp, size_t *sizep) | ||||
{ | { | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY); | PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY); | ||||
if (sizep != NULL) | if (sizep != NULL) | ||||
*sizep = nvp->nvp_datasize; | *sizep = nvp->nvp_datasize; | ||||
return ((const void *)(intptr_t)nvp->nvp_data); | return ((const void *)(intptr_t)nvp->nvp_data); | ||||
} | } | ||||
void | void | ||||
nvpair_free(nvpair_t *nvp) | nvpair_free(nvpair_t *nvp) | ||||
{ | { | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvp->nvp_list == NULL); | PJDLOG_ASSERT(nvp->nvp_list == NULL); | ||||
nvp->nvp_magic = 0; | nvp->nvp_magic = 0; | ||||
switch (nvp->nvp_type) { | switch (nvp->nvp_type) { | ||||
#ifndef _KERNEL | |||||
case NV_TYPE_DESCRIPTOR: | case NV_TYPE_DESCRIPTOR: | ||||
close((int)nvp->nvp_data); | close((int)nvp->nvp_data); | ||||
break; | break; | ||||
#endif | |||||
case NV_TYPE_NVLIST: | case NV_TYPE_NVLIST: | ||||
nvlist_destroy((nvlist_t *)(intptr_t)nvp->nvp_data); | nvlist_destroy((nvlist_t *)(intptr_t)nvp->nvp_data); | ||||
break; | break; | ||||
case NV_TYPE_STRING: | case NV_TYPE_STRING: | ||||
free((char *)(intptr_t)nvp->nvp_data); | nv_free((char *)(intptr_t)nvp->nvp_data); | ||||
break; | break; | ||||
case NV_TYPE_BINARY: | case NV_TYPE_BINARY: | ||||
free((void *)(intptr_t)nvp->nvp_data); | nv_free((void *)(intptr_t)nvp->nvp_data); | ||||
break; | break; | ||||
} | } | ||||
free(nvp); | nv_free(nvp); | ||||
} | } | ||||
void | void | ||||
nvpair_free_structure(nvpair_t *nvp) | nvpair_free_structure(nvpair_t *nvp) | ||||
{ | { | ||||
NVPAIR_ASSERT(nvp); | NVPAIR_ASSERT(nvp); | ||||
PJDLOG_ASSERT(nvp->nvp_list == NULL); | PJDLOG_ASSERT(nvp->nvp_list == NULL); | ||||
nvp->nvp_magic = 0; | nvp->nvp_magic = 0; | ||||
free(nvp); | nv_free(nvp); | ||||
} | } | ||||
const char * | const char * | ||||
nvpair_type_string(int type) | nvpair_type_string(int type) | ||||
{ | { | ||||
switch (type) { | switch (type) { | ||||
case NV_TYPE_NULL: | case NV_TYPE_NULL: | ||||
Show All 17 Lines |