Don't allocate memory for operations that do not insert
Almost every operation performed on an nvlist was allocating a new string to hold the key name. The nvlist_exists* family of functions would always return false if they failed to allocate the string. The rest of the functions would outright abort(). Fix the non-varargs variants of the functions to perform the requested operations directly and the varargs versions to allocate the string and call into the non-varargs versions. The varargs versions are still broken and really can't be fixed, so we might consider axing them entirely. However, now the non- varargs functions are always safe to call. Differential Revision: https://reviews.freebsd.org/D1879 Reviewed by: pjd, jfv MFC after: 1 month Sponsored by: Sandvine Inc.
This commit is contained in:
parent
a87e516267
commit
ed007c94ba
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=279435
@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nv.h"
|
||||
#include "nv_impl.h"
|
||||
@ -44,7 +45,10 @@ ftype \
|
||||
dnvlist_get_##type(const nvlist_t *nvl, const char *name, ftype defval) \
|
||||
{ \
|
||||
\
|
||||
return (dnvlist_getf_##type(nvl, defval, "%s", name)); \
|
||||
if (nvlist_exists_##type(nvl, name)) \
|
||||
return (nvlist_get_##type(nvl, name)); \
|
||||
else \
|
||||
return (defval); \
|
||||
}
|
||||
|
||||
DNVLIST_GET(bool, bool)
|
||||
@ -59,8 +63,16 @@ const void *
|
||||
dnvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep,
|
||||
const void *defval, size_t defsize)
|
||||
{
|
||||
const void *value;
|
||||
|
||||
return (dnvlist_getf_binary(nvl, sizep, defval, defsize, "%s", name));
|
||||
if (nvlist_exists_binary(nvl, name))
|
||||
value = nvlist_get_binary(nvl, name, sizep);
|
||||
else {
|
||||
if (sizep != NULL)
|
||||
*sizep = defsize;
|
||||
value = defval;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
#define DNVLIST_GETF(ftype, type) \
|
||||
@ -106,15 +118,14 @@ ftype \
|
||||
dnvlist_getv_##type(const nvlist_t *nvl, ftype defval, \
|
||||
const char *namefmt, va_list nameap) \
|
||||
{ \
|
||||
va_list cnameap; \
|
||||
char *name; \
|
||||
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); \
|
||||
vasprintf(&name, namefmt, nameap); \
|
||||
if (name == NULL) \
|
||||
return (defval); \
|
||||
value = dnvlist_get_##type(nvl, name, defval); \
|
||||
free(name); \
|
||||
return (value); \
|
||||
}
|
||||
|
||||
@ -130,18 +141,18 @@ 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;
|
||||
char *name;
|
||||
const void *value;
|
||||
|
||||
va_copy(cnameap, nameap);
|
||||
if (nvlist_existsv_binary(nvl, namefmt, cnameap)) {
|
||||
value = nvlist_getv_binary(nvl, sizep, namefmt, nameap);
|
||||
vasprintf(&name, namefmt, nameap);
|
||||
if (name != NULL) {
|
||||
value = dnvlist_get_binary(nvl, name, sizep, defval, defsize);
|
||||
free(name);
|
||||
} else {
|
||||
if (sizep != NULL)
|
||||
*sizep = defsize;
|
||||
value = defval;
|
||||
}
|
||||
va_end(cnameap);
|
||||
return (value);
|
||||
}
|
||||
|
||||
@ -150,7 +161,10 @@ ftype \
|
||||
dnvlist_take_##type(nvlist_t *nvl, const char *name, ftype defval) \
|
||||
{ \
|
||||
\
|
||||
return (dnvlist_takef_##type(nvl, defval, "%s", name)); \
|
||||
if (nvlist_exists_##type(nvl, name)) \
|
||||
return (nvlist_take_##type(nvl, name)); \
|
||||
else \
|
||||
return (defval); \
|
||||
}
|
||||
|
||||
DNVLIST_TAKE(bool, bool)
|
||||
@ -165,8 +179,16 @@ void *
|
||||
dnvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep,
|
||||
void *defval, size_t defsize)
|
||||
{
|
||||
void *value;
|
||||
|
||||
return (dnvlist_takef_binary(nvl, sizep, defval, defsize, "%s", name));
|
||||
if (nvlist_exists_binary(nvl, name))
|
||||
value = nvlist_take_binary(nvl, name, sizep);
|
||||
else {
|
||||
if (sizep != NULL)
|
||||
*sizep = defsize;
|
||||
value = defval;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
#define DNVLIST_TAKEF(ftype, type) \
|
||||
@ -212,15 +234,14 @@ ftype \
|
||||
dnvlist_takev_##type(nvlist_t *nvl, ftype defval, const char *namefmt, \
|
||||
va_list nameap) \
|
||||
{ \
|
||||
va_list cnameap; \
|
||||
char *name; \
|
||||
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); \
|
||||
vasprintf(&name, namefmt, nameap); \
|
||||
if (name == NULL) \
|
||||
return (defval); \
|
||||
value = dnvlist_take_##type(nvl, name, defval); \
|
||||
free(name); \
|
||||
return (value); \
|
||||
}
|
||||
|
||||
@ -236,17 +257,18 @@ void *
|
||||
dnvlist_takev_binary(nvlist_t *nvl, size_t *sizep, void *defval,
|
||||
size_t defsize, const char *namefmt, va_list nameap)
|
||||
{
|
||||
va_list cnameap;
|
||||
char *name;
|
||||
void *value;
|
||||
|
||||
va_copy(cnameap, nameap);
|
||||
if (nvlist_existsv_binary(nvl, namefmt, cnameap)) {
|
||||
value = nvlist_takev_binary(nvl, sizep, namefmt, nameap);
|
||||
vasprintf(&name, namefmt, nameap);
|
||||
if (name != NULL) {
|
||||
value = dnvlist_take_binary(nvl, name, sizep, defval, defsize);
|
||||
free(name);
|
||||
} else {
|
||||
if (sizep != NULL)
|
||||
*sizep = defsize;
|
||||
value = defval;
|
||||
}
|
||||
va_end(cnameap);
|
||||
|
||||
return (value);
|
||||
}
|
||||
|
@ -97,14 +97,6 @@ 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);
|
||||
|
@ -208,29 +208,23 @@ nvlist_empty(const nvlist_t *nvl)
|
||||
}
|
||||
|
||||
static void
|
||||
nvlist_report_missing(int type, const char *namefmt, va_list nameap)
|
||||
nvlist_report_missing(int type, const char *name)
|
||||
{
|
||||
char *name;
|
||||
|
||||
vasprintf(&name, namefmt, nameap);
|
||||
PJDLOG_ABORT("Element '%s' of type %s doesn't exist.",
|
||||
name != NULL ? name : "N/A", nvpair_type_string(type));
|
||||
name, nvpair_type_string(type));
|
||||
}
|
||||
|
||||
static nvpair_t *
|
||||
nvlist_findv(const nvlist_t *nvl, int type, const char *namefmt, va_list nameap)
|
||||
nvlist_find(const nvlist_t *nvl, int type, const char *name)
|
||||
{
|
||||
nvpair_t *nvp;
|
||||
char *name;
|
||||
|
||||
NVLIST_ASSERT(nvl);
|
||||
PJDLOG_ASSERT(nvl->nvl_error == 0);
|
||||
PJDLOG_ASSERT(type == NV_TYPE_NONE ||
|
||||
(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST));
|
||||
|
||||
if (vasprintf(&name, namefmt, nameap) < 0)
|
||||
return (NULL);
|
||||
|
||||
for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
|
||||
nvp = nvlist_next_nvpair(nvl, nvp)) {
|
||||
if (type != NV_TYPE_NONE && nvpair_type(nvp) != type)
|
||||
@ -245,8 +239,6 @@ nvlist_findv(const nvlist_t *nvl, int type, const char *namefmt, va_list nameap)
|
||||
break;
|
||||
}
|
||||
|
||||
free(name);
|
||||
|
||||
if (nvp == NULL)
|
||||
errno = ENOENT;
|
||||
|
||||
@ -257,7 +249,12 @@ bool
|
||||
nvlist_exists_type(const nvlist_t *nvl, const char *name, int type)
|
||||
{
|
||||
|
||||
return (nvlist_existsf_type(nvl, type, "%s", name));
|
||||
NVLIST_ASSERT(nvl);
|
||||
PJDLOG_ASSERT(nvl->nvl_error == 0);
|
||||
PJDLOG_ASSERT(type == NV_TYPE_NONE ||
|
||||
(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST));
|
||||
|
||||
return (nvlist_find(nvl, type, name) != NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -277,20 +274,33 @@ bool
|
||||
nvlist_existsv_type(const nvlist_t *nvl, int type, const char *namefmt,
|
||||
va_list nameap)
|
||||
{
|
||||
char *name;
|
||||
bool exists;
|
||||
|
||||
vasprintf(&name, namefmt, nameap);
|
||||
if (name == NULL)
|
||||
return (false);
|
||||
|
||||
exists = nvlist_exists_type(nvl, name, type);
|
||||
free(name);
|
||||
return (exists);
|
||||
}
|
||||
|
||||
void
|
||||
nvlist_free_type(nvlist_t *nvl, const char *name, int type)
|
||||
{
|
||||
nvpair_t *nvp;
|
||||
|
||||
NVLIST_ASSERT(nvl);
|
||||
PJDLOG_ASSERT(nvl->nvl_error == 0);
|
||||
PJDLOG_ASSERT(type == NV_TYPE_NONE ||
|
||||
(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST));
|
||||
|
||||
return (nvlist_findv(nvl, type, namefmt, nameap) != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nvlist_free_type(nvlist_t *nvl, const char *name, int type)
|
||||
{
|
||||
|
||||
nvlist_freef_type(nvl, type, "%s", name);
|
||||
nvp = nvlist_find(nvl, type, name);
|
||||
if (nvp != NULL)
|
||||
nvlist_free_nvpair(nvl, nvp);
|
||||
else
|
||||
nvlist_report_missing(type, name);
|
||||
}
|
||||
|
||||
void
|
||||
@ -306,21 +316,13 @@ nvlist_freef_type(nvlist_t *nvl, int type, const char *namefmt, ...)
|
||||
void
|
||||
nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap)
|
||||
{
|
||||
va_list cnameap;
|
||||
nvpair_t *nvp;
|
||||
char *name;
|
||||
|
||||
NVLIST_ASSERT(nvl);
|
||||
PJDLOG_ASSERT(nvl->nvl_error == 0);
|
||||
PJDLOG_ASSERT(type == NV_TYPE_NONE ||
|
||||
(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST));
|
||||
|
||||
va_copy(cnameap, nameap);
|
||||
nvp = nvlist_findv(nvl, type, namefmt, cnameap);
|
||||
va_end(cnameap);
|
||||
if (nvp != NULL)
|
||||
nvlist_free_nvpair(nvl, nvp);
|
||||
else
|
||||
nvlist_report_missing(type, namefmt, nameap);
|
||||
vasprintf(&name, namefmt, nameap);
|
||||
if (name == NULL)
|
||||
nvlist_report_missing(type, "<unknown>");
|
||||
nvlist_free_type(nvl, name, type);
|
||||
free(name);
|
||||
}
|
||||
|
||||
nvlist_t *
|
||||
@ -1031,24 +1033,24 @@ bool
|
||||
nvlist_exists(const nvlist_t *nvl, const char *name)
|
||||
{
|
||||
|
||||
return (nvlist_existsf(nvl, "%s", name));
|
||||
return (nvlist_find(nvl, NV_TYPE_NONE, name) != NULL);
|
||||
}
|
||||
|
||||
#define NVLIST_EXISTS(type) \
|
||||
#define NVLIST_EXISTS(type, TYPE) \
|
||||
bool \
|
||||
nvlist_exists_##type(const nvlist_t *nvl, const char *name) \
|
||||
{ \
|
||||
\
|
||||
return (nvlist_existsf_##type(nvl, "%s", name)); \
|
||||
return (nvlist_find(nvl, NV_TYPE_##TYPE, name) != NULL); \
|
||||
}
|
||||
|
||||
NVLIST_EXISTS(null)
|
||||
NVLIST_EXISTS(bool)
|
||||
NVLIST_EXISTS(number)
|
||||
NVLIST_EXISTS(string)
|
||||
NVLIST_EXISTS(nvlist)
|
||||
NVLIST_EXISTS(descriptor)
|
||||
NVLIST_EXISTS(binary)
|
||||
NVLIST_EXISTS(null, NULL)
|
||||
NVLIST_EXISTS(bool, BOOL)
|
||||
NVLIST_EXISTS(number, NUMBER)
|
||||
NVLIST_EXISTS(string, STRING)
|
||||
NVLIST_EXISTS(nvlist, NVLIST)
|
||||
NVLIST_EXISTS(descriptor, DESCRIPTOR)
|
||||
NVLIST_EXISTS(binary, BINARY)
|
||||
|
||||
#undef NVLIST_EXISTS
|
||||
|
||||
@ -1090,27 +1092,41 @@ NVLIST_EXISTSF(binary)
|
||||
bool
|
||||
nvlist_existsv(const nvlist_t *nvl, const char *namefmt, va_list nameap)
|
||||
{
|
||||
char *name;
|
||||
bool exists;
|
||||
|
||||
return (nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap) != NULL);
|
||||
vasprintf(&name, namefmt, nameap);
|
||||
if (name == NULL)
|
||||
return (false);
|
||||
|
||||
exists = nvlist_exists(nvl, name);
|
||||
free(name);
|
||||
return (exists);
|
||||
}
|
||||
|
||||
#define NVLIST_EXISTSV(type, TYPE) \
|
||||
#define NVLIST_EXISTSV(type) \
|
||||
bool \
|
||||
nvlist_existsv_##type(const nvlist_t *nvl, const char *namefmt, \
|
||||
va_list nameap) \
|
||||
{ \
|
||||
char *name; \
|
||||
bool exists; \
|
||||
\
|
||||
return (nvlist_findv(nvl, NV_TYPE_##TYPE, namefmt, nameap) != \
|
||||
NULL); \
|
||||
vasprintf(&name, namefmt, nameap); \
|
||||
if (name == NULL) \
|
||||
return (false); \
|
||||
exists = nvlist_exists_##type(nvl, name); \
|
||||
free(name); \
|
||||
return (exists); \
|
||||
}
|
||||
|
||||
NVLIST_EXISTSV(null, NULL)
|
||||
NVLIST_EXISTSV(bool, BOOL)
|
||||
NVLIST_EXISTSV(number, NUMBER)
|
||||
NVLIST_EXISTSV(string, STRING)
|
||||
NVLIST_EXISTSV(nvlist, NVLIST)
|
||||
NVLIST_EXISTSV(descriptor, DESCRIPTOR)
|
||||
NVLIST_EXISTSV(binary, BINARY)
|
||||
NVLIST_EXISTSV(null)
|
||||
NVLIST_EXISTSV(bool)
|
||||
NVLIST_EXISTSV(number)
|
||||
NVLIST_EXISTSV(string)
|
||||
NVLIST_EXISTSV(nvlist)
|
||||
NVLIST_EXISTSV(descriptor)
|
||||
NVLIST_EXISTSV(binary)
|
||||
|
||||
#undef NVLIST_EXISTSV
|
||||
|
||||
@ -1561,28 +1577,43 @@ nvlist_movev_binary(nvlist_t *nvl, void *value, size_t size,
|
||||
nvlist_move_nvpair(nvl, nvp);
|
||||
}
|
||||
|
||||
#define NVLIST_GET(ftype, type) \
|
||||
const nvpair_t *
|
||||
nvlist_get_nvpair(const nvlist_t *nvl, const char *name)
|
||||
{
|
||||
|
||||
return (nvlist_find(nvl, NV_TYPE_NONE, name));
|
||||
}
|
||||
|
||||
#define NVLIST_GET(ftype, type, TYPE) \
|
||||
ftype \
|
||||
nvlist_get_##type(const nvlist_t *nvl, const char *name) \
|
||||
{ \
|
||||
const nvpair_t *nvp; \
|
||||
\
|
||||
return (nvlist_getf_##type(nvl, "%s", name)); \
|
||||
nvp = nvlist_find(nvl, NV_TYPE_##TYPE, name); \
|
||||
if (nvp == NULL) \
|
||||
nvlist_report_missing(NV_TYPE_##TYPE, name); \
|
||||
return (nvpair_get_##type(nvp)); \
|
||||
}
|
||||
|
||||
NVLIST_GET(const nvpair_t *, nvpair)
|
||||
NVLIST_GET(bool, bool)
|
||||
NVLIST_GET(uint64_t, number)
|
||||
NVLIST_GET(const char *, string)
|
||||
NVLIST_GET(const nvlist_t *, nvlist)
|
||||
NVLIST_GET(int, descriptor)
|
||||
NVLIST_GET(bool, bool, BOOL)
|
||||
NVLIST_GET(uint64_t, number, NUMBER)
|
||||
NVLIST_GET(const char *, string, STRING)
|
||||
NVLIST_GET(const nvlist_t *, nvlist, NVLIST)
|
||||
NVLIST_GET(int, descriptor, DESCRIPTOR)
|
||||
|
||||
#undef NVLIST_GET
|
||||
|
||||
const void *
|
||||
nvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep)
|
||||
{
|
||||
nvpair_t *nvp;
|
||||
|
||||
return (nvlist_getf_binary(nvl, sizep, "%s", name));
|
||||
nvp = nvlist_find(nvl, NV_TYPE_BINARY, name);
|
||||
if (nvp == NULL)
|
||||
nvlist_report_missing(NV_TYPE_BINARY, name);
|
||||
|
||||
return (nvpair_get_binary(nvp, sizep));
|
||||
}
|
||||
|
||||
#define NVLIST_GETF(ftype, type) \
|
||||
@ -1599,7 +1630,6 @@ nvlist_getf_##type(const nvlist_t *nvl, const char *namefmt, ...) \
|
||||
return (value); \
|
||||
}
|
||||
|
||||
NVLIST_GETF(const nvpair_t *, nvpair)
|
||||
NVLIST_GETF(bool, bool)
|
||||
NVLIST_GETF(uint64_t, number)
|
||||
NVLIST_GETF(const char *, string)
|
||||
@ -1621,27 +1651,21 @@ nvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, ...)
|
||||
return (value);
|
||||
}
|
||||
|
||||
const nvpair_t *
|
||||
nvlist_getv_nvpair(const nvlist_t *nvl, const char *namefmt, va_list nameap)
|
||||
{
|
||||
|
||||
return (nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap));
|
||||
}
|
||||
|
||||
#define NVLIST_GETV(ftype, type, TYPE) \
|
||||
ftype \
|
||||
nvlist_getv_##type(const nvlist_t *nvl, const char *namefmt, \
|
||||
va_list nameap) \
|
||||
{ \
|
||||
va_list cnameap; \
|
||||
const nvpair_t *nvp; \
|
||||
char *name; \
|
||||
ftype value; \
|
||||
\
|
||||
va_copy(cnameap, nameap); \
|
||||
nvp = nvlist_findv(nvl, NV_TYPE_##TYPE, namefmt, cnameap); \
|
||||
va_end(cnameap); \
|
||||
if (nvp == NULL) \
|
||||
nvlist_report_missing(NV_TYPE_##TYPE, namefmt, nameap); \
|
||||
return (nvpair_get_##type(nvp)); \
|
||||
vasprintf(&name, namefmt, nameap); \
|
||||
if (name == NULL) \
|
||||
nvlist_report_missing(NV_TYPE_##TYPE, "<unknown>"); \
|
||||
value = nvlist_get_##type(nvl, name); \
|
||||
free(name); \
|
||||
\
|
||||
return (value); \
|
||||
}
|
||||
|
||||
NVLIST_GETV(bool, bool, BOOL)
|
||||
@ -1656,40 +1680,56 @@ const void *
|
||||
nvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt,
|
||||
va_list nameap)
|
||||
{
|
||||
va_list cnameap;
|
||||
const nvpair_t *nvp;
|
||||
char *name;
|
||||
const void *binary;
|
||||
|
||||
va_copy(cnameap, nameap);
|
||||
nvp = nvlist_findv(nvl, NV_TYPE_BINARY, namefmt, cnameap);
|
||||
va_end(cnameap);
|
||||
if (nvp == NULL)
|
||||
nvlist_report_missing(NV_TYPE_BINARY, namefmt, nameap);
|
||||
vasprintf(&name, namefmt, nameap);
|
||||
if (name == NULL)
|
||||
nvlist_report_missing(NV_TYPE_BINARY, "<unknown>");
|
||||
|
||||
return (nvpair_get_binary(nvp, sizep));
|
||||
binary = nvlist_get_binary(nvl, name, sizep);
|
||||
free(name);
|
||||
return (binary);
|
||||
}
|
||||
|
||||
#define NVLIST_TAKE(ftype, type) \
|
||||
#define NVLIST_TAKE(ftype, type, TYPE) \
|
||||
ftype \
|
||||
nvlist_take_##type(nvlist_t *nvl, const char *name) \
|
||||
{ \
|
||||
nvpair_t *nvp; \
|
||||
ftype value; \
|
||||
\
|
||||
return (nvlist_takef_##type(nvl, "%s", name)); \
|
||||
nvp = nvlist_find(nvl, NV_TYPE_##TYPE, name); \
|
||||
if (nvp == NULL) \
|
||||
nvlist_report_missing(NV_TYPE_##TYPE, name); \
|
||||
value = (ftype)(intptr_t)nvpair_get_##type(nvp); \
|
||||
nvlist_remove_nvpair(nvl, nvp); \
|
||||
nvpair_free_structure(nvp); \
|
||||
return (value); \
|
||||
}
|
||||
|
||||
NVLIST_TAKE(nvpair_t *, nvpair)
|
||||
NVLIST_TAKE(bool, bool)
|
||||
NVLIST_TAKE(uint64_t, number)
|
||||
NVLIST_TAKE(char *, string)
|
||||
NVLIST_TAKE(nvlist_t *, nvlist)
|
||||
NVLIST_TAKE(int, descriptor)
|
||||
NVLIST_TAKE(bool, bool, BOOL)
|
||||
NVLIST_TAKE(uint64_t, number, NUMBER)
|
||||
NVLIST_TAKE(char *, string, STRING)
|
||||
NVLIST_TAKE(nvlist_t *, nvlist, NVLIST)
|
||||
NVLIST_TAKE(int, descriptor, DESCRIPTOR)
|
||||
|
||||
#undef NVLIST_TAKE
|
||||
|
||||
void *
|
||||
nvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep)
|
||||
{
|
||||
nvpair_t *nvp;
|
||||
void *value;
|
||||
|
||||
return (nvlist_takef_binary(nvl, sizep, "%s", name));
|
||||
nvp = nvlist_find(nvl, NV_TYPE_BINARY, name);
|
||||
if (nvp == NULL)
|
||||
nvlist_report_missing(NV_TYPE_BINARY, name);
|
||||
|
||||
value = (void *)(intptr_t)nvpair_get_binary(nvp, sizep);
|
||||
nvlist_remove_nvpair(nvl, nvp);
|
||||
nvpair_free_structure(nvp);
|
||||
return (value);
|
||||
}
|
||||
|
||||
#define NVLIST_TAKEF(ftype, type) \
|
||||
@ -1706,7 +1746,6 @@ nvlist_takef_##type(nvlist_t *nvl, const char *namefmt, ...) \
|
||||
return (value); \
|
||||
}
|
||||
|
||||
NVLIST_TAKEF(nvpair_t *, nvpair)
|
||||
NVLIST_TAKEF(bool, bool)
|
||||
NVLIST_TAKEF(uint64_t, number)
|
||||
NVLIST_TAKEF(char *, string)
|
||||
@ -1728,33 +1767,18 @@ nvlist_takef_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, ...)
|
||||
return (value);
|
||||
}
|
||||
|
||||
nvpair_t *
|
||||
nvlist_takev_nvpair(nvlist_t *nvl, const char *namefmt, va_list nameap)
|
||||
{
|
||||
nvpair_t *nvp;
|
||||
|
||||
nvp = nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap);
|
||||
if (nvp != NULL)
|
||||
nvlist_remove_nvpair(nvl, nvp);
|
||||
return (nvp);
|
||||
}
|
||||
|
||||
#define NVLIST_TAKEV(ftype, type, TYPE) \
|
||||
ftype \
|
||||
nvlist_takev_##type(nvlist_t *nvl, const char *namefmt, va_list nameap) \
|
||||
{ \
|
||||
va_list cnameap; \
|
||||
nvpair_t *nvp; \
|
||||
char *name; \
|
||||
ftype value; \
|
||||
\
|
||||
va_copy(cnameap, nameap); \
|
||||
nvp = nvlist_findv(nvl, NV_TYPE_##TYPE, namefmt, cnameap); \
|
||||
va_end(cnameap); \
|
||||
if (nvp == NULL) \
|
||||
nvlist_report_missing(NV_TYPE_##TYPE, namefmt, nameap); \
|
||||
value = (ftype)(intptr_t)nvpair_get_##type(nvp); \
|
||||
nvlist_remove_nvpair(nvl, nvp); \
|
||||
nvpair_free_structure(nvp); \
|
||||
vasprintf(&name, namefmt, nameap); \
|
||||
if (name == NULL) \
|
||||
nvlist_report_missing(NV_TYPE_##TYPE, "<unknown>"); \
|
||||
value = nvlist_take_##type(nvl, name); \
|
||||
free(name); \
|
||||
return (value); \
|
||||
}
|
||||
|
||||
@ -1770,20 +1794,16 @@ void *
|
||||
nvlist_takev_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt,
|
||||
va_list nameap)
|
||||
{
|
||||
va_list cnameap;
|
||||
nvpair_t *nvp;
|
||||
void *value;
|
||||
char *name;
|
||||
void *binary;
|
||||
|
||||
va_copy(cnameap, nameap);
|
||||
nvp = nvlist_findv(nvl, NV_TYPE_BINARY, namefmt, cnameap);
|
||||
va_end(cnameap);
|
||||
if (nvp == NULL)
|
||||
nvlist_report_missing(NV_TYPE_BINARY, namefmt, nameap);
|
||||
vasprintf(&name, namefmt, nameap);
|
||||
if (name == NULL)
|
||||
nvlist_report_missing(NV_TYPE_BINARY, "<unknown>");
|
||||
|
||||
value = (void *)(intptr_t)nvpair_get_binary(nvp, sizep);
|
||||
nvlist_remove_nvpair(nvl, nvp);
|
||||
nvpair_free_structure(nvp);
|
||||
return (value);
|
||||
binary = nvlist_take_binary(nvl, name, sizep);
|
||||
free(name);
|
||||
return (binary);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1801,24 +1821,24 @@ void
|
||||
nvlist_free(nvlist_t *nvl, const char *name)
|
||||
{
|
||||
|
||||
nvlist_freef(nvl, "%s", name);
|
||||
nvlist_free_type(nvl, name, NV_TYPE_NONE);
|
||||
}
|
||||
|
||||
#define NVLIST_FREE(type) \
|
||||
#define NVLIST_FREE(type, TYPE) \
|
||||
void \
|
||||
nvlist_free_##type(nvlist_t *nvl, const char *name) \
|
||||
{ \
|
||||
\
|
||||
nvlist_freef_##type(nvl, "%s", name); \
|
||||
nvlist_free_type(nvl, name, NV_TYPE_##TYPE); \
|
||||
}
|
||||
|
||||
NVLIST_FREE(null)
|
||||
NVLIST_FREE(bool)
|
||||
NVLIST_FREE(number)
|
||||
NVLIST_FREE(string)
|
||||
NVLIST_FREE(nvlist)
|
||||
NVLIST_FREE(descriptor)
|
||||
NVLIST_FREE(binary)
|
||||
NVLIST_FREE(null, NULL)
|
||||
NVLIST_FREE(bool, BOOL)
|
||||
NVLIST_FREE(number, NUMBER)
|
||||
NVLIST_FREE(string, STRING)
|
||||
NVLIST_FREE(nvlist, NVLIST)
|
||||
NVLIST_FREE(descriptor, DESCRIPTOR)
|
||||
NVLIST_FREE(binary, BINARY)
|
||||
|
||||
#undef NVLIST_FREE
|
||||
|
||||
@ -1864,8 +1884,13 @@ nvlist_freev(nvlist_t *nvl, const char *namefmt, va_list nameap)
|
||||
void \
|
||||
nvlist_freev_##type(nvlist_t *nvl, const char *namefmt, va_list nameap) \
|
||||
{ \
|
||||
char *name; \
|
||||
\
|
||||
nvlist_freev_type(nvl, NV_TYPE_##TYPE, namefmt, nameap); \
|
||||
vasprintf(&name, namefmt, nameap); \
|
||||
if (name == NULL) \
|
||||
nvlist_report_missing(NV_TYPE_##TYPE, "<unknown>"); \
|
||||
nvlist_free_##type(nvl, name); \
|
||||
free(name); \
|
||||
}
|
||||
|
||||
NVLIST_FREEV(null, NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user