Date: Sun, 1 Mar 2015 00:22:32 +0000 (UTC) From: Ryan Stone <rstone@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r279435 - head/lib/libnv Message-ID: <201503010022.t210MWMg083686@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rstone Date: Sun Mar 1 00:22:31 2015 New Revision: 279435 URL: https://svnweb.freebsd.org/changeset/base/279435 Log: 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. Modified: head/lib/libnv/dnvlist.c head/lib/libnv/nv_impl.h head/lib/libnv/nvlist.c Modified: head/lib/libnv/dnvlist.c ============================================================================== --- head/lib/libnv/dnvlist.c Sun Mar 1 00:22:23 2015 (r279434) +++ head/lib/libnv/dnvlist.c Sun Mar 1 00:22:31 2015 (r279435) @@ -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); } Modified: head/lib/libnv/nv_impl.h ============================================================================== --- head/lib/libnv/nv_impl.h Sun Mar 1 00:22:23 2015 (r279434) +++ head/lib/libnv/nv_impl.h Sun Mar 1 00:22:31 2015 (r279435) @@ -97,14 +97,6 @@ const void *nvpair_get_binary(const nvpa 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); Modified: head/lib/libnv/nvlist.c ============================================================================== --- head/lib/libnv/nvlist.c Sun Mar 1 00:22:23 2015 (r279434) +++ head/lib/libnv/nvlist.c Sun Mar 1 00:22:31 2015 (r279435) @@ -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 ty 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; - NVLIST_ASSERT(nvl); - PJDLOG_ASSERT(nvl->nvl_error == 0); - PJDLOG_ASSERT(type == NV_TYPE_NONE || - (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST)); + vasprintf(&name, namefmt, nameap); + if (name == NULL) + return (false); - return (nvlist_findv(nvl, type, namefmt, nameap) != NULL); + 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)); - 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 typ void nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap) { - va_list cnameap; - 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)); + char *name; - 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; + + vasprintf(&name, namefmt, nameap); + if (name == NULL) + return (false); - return (nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap) != NULL); + 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 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; + + nvp = nvlist_find(nvl, NV_TYPE_BINARY, name); + if (nvp == NULL) + nvlist_report_missing(NV_TYPE_BINARY, name); - return (nvlist_getf_binary(nvl, sizep, "%s", name)); + return (nvpair_get_binary(nvp, sizep)); } #define NVLIST_GETF(ftype, type) \ @@ -1599,7 +1630,6 @@ nvlist_getf_##type(const nvlist_t *nvl, 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, 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; + + nvp = nvlist_find(nvl, NV_TYPE_BINARY, name); + if (nvp == NULL) + nvlist_report_missing(NV_TYPE_BINARY, name); - return (nvlist_takef_binary(nvl, sizep, "%s", 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 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_ 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 * 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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503010022.t210MWMg083686>