svn commit: r279435 - head/lib/libnv

Ryan Stone rstone at FreeBSD.org
Sun Mar 1 00:22:33 UTC 2015


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)


More information about the svn-src-all mailing list