summaryrefslogtreecommitdiffstats
path: root/lib/libnv
diff options
context:
space:
mode:
authorrstone <rstone@FreeBSD.org>2015-03-01 00:22:23 +0000
committerrstone <rstone@FreeBSD.org>2015-03-01 00:22:23 +0000
commit8c5d4c9ca27df87867fa8736af38f34923b1be9f (patch)
tree92792cbd1327fbe33615ed596201014a8d0d605d /lib/libnv
parent96dd7966e7751c9bd4e19a107cdf7ebff88cc0da (diff)
downloadFreeBSD-src-8c5d4c9ca27df87867fa8736af38f34923b1be9f.zip
FreeBSD-src-8c5d4c9ca27df87867fa8736af38f34923b1be9f.tar.gz
Add function to force an nvlist into the error state
Add an nvlist_set_error() function that can be used to force an nvlist into the error state. This is useful both for writing tests and for writing APIs that use nvlists internally. Differential Revision: https://reviews.freebsd.org/D1878 Reviewed by: pjd, jfv MFC After: 1 month Sponsored by: Sandvine Inc.
Diffstat (limited to 'lib/libnv')
-rw-r--r--lib/libnv/Makefile1
-rw-r--r--lib/libnv/nv.314
-rw-r--r--lib/libnv/nv.h1
-rw-r--r--lib/libnv/nvlist.c14
-rw-r--r--lib/libnv/tests/nv_tests.cc36
5 files changed, 65 insertions, 1 deletions
diff --git a/lib/libnv/Makefile b/lib/libnv/Makefile
index c74c55c..61b158f 100644
--- a/lib/libnv/Makefile
+++ b/lib/libnv/Makefile
@@ -22,6 +22,7 @@ MLINKS+=nv.3 libnv.3 \
MLINKS+=nv.3 nvlist_create.3 \
nv.3 nvlist_destroy.3 \
nv.3 nvlist_error.3 \
+ nv.3 nvlist_set_error.3 \
nv.3 nvlist_empty.3 \
nv.3 nvlist_clone.3 \
nv.3 nvlist_dump.3 \
diff --git a/lib/libnv/nv.3 b/lib/libnv/nv.3
index 6ff6329..be6e0fe 100644
--- a/lib/libnv/nv.3
+++ b/lib/libnv/nv.3
@@ -35,6 +35,7 @@
.Nm nvlist_create ,
.Nm nvlist_destroy ,
.Nm nvlist_error ,
+.Nm nvlist_set_error ,
.Nm nvlist_empty ,
.Nm nvlist_exists ,
.Nm nvlist_free ,
@@ -63,6 +64,8 @@
.Fn nvlist_destroy "nvlist_t *nvl"
.Ft int
.Fn nvlist_error "const nvlist_t *nvl"
+.Ft void
+.Fn nvlist_set_error "nvlist_t *nvl, int error"
.Ft bool
.Fn nvlist_empty "const nvlist_t *nvl"
.\"
@@ -248,8 +251,17 @@ the
error will be returned.
.Pp
The
+.Fn nvlist_set_error
+function sets an nvlist to be in the error state.
+Subsequent calls to
+.Fn nvlist_error
+will return the given error value.
+This function cannot be used to clear the error state from an nvlist.
+This function does nothing if the nvlist is already in the error state.
+.Pp
+The
.Fn nvlist_empty
-functions returns
+function returns
.Dv true
if the given nvlist is empty and
.Dv false
diff --git a/lib/libnv/nv.h b/lib/libnv/nv.h
index 738bc83..bc80d68 100644
--- a/lib/libnv/nv.h
+++ b/lib/libnv/nv.h
@@ -69,6 +69,7 @@ nvlist_t *nvlist_create(int flags);
void nvlist_destroy(nvlist_t *nvl);
int nvlist_error(const nvlist_t *nvl);
bool nvlist_empty(const nvlist_t *nvl);
+void nvlist_set_error(nvlist_t *nvl, int error);
nvlist_t *nvlist_clone(const nvlist_t *nvl);
diff --git a/lib/libnv/nvlist.c b/lib/libnv/nvlist.c
index 839f607..90fcde3 100644
--- a/lib/libnv/nvlist.c
+++ b/lib/libnv/nvlist.c
@@ -137,6 +137,20 @@ nvlist_destroy(nvlist_t *nvl)
errno = serrno;
}
+void
+nvlist_set_error(nvlist_t *nvl, int error)
+{
+
+ PJDLOG_ASSERT(error != 0);
+
+ /*
+ * Check for error != 0 so that we don't do the wrong thing if somebody
+ * tries to abuse this API when asserts are disabled.
+ */
+ if (nvl != NULL && error != 0 && nvl->nvl_error == 0)
+ nvl->nvl_error = error;
+}
+
int
nvlist_error(const nvlist_t *nvl)
{
diff --git a/lib/libnv/tests/nv_tests.cc b/lib/libnv/tests/nv_tests.cc
index dc86b2a..e2a9924 100644
--- a/lib/libnv/tests/nv_tests.cc
+++ b/lib/libnv/tests/nv_tests.cc
@@ -409,6 +409,22 @@ ATF_TEST_CASE_BODY(nvlist_clone__nested_nvlist)
nvlist_destroy(nvl);
}
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_clone__error_nvlist);
+ATF_TEST_CASE_BODY(nvlist_clone__error_nvlist)
+{
+ nvlist_t *nvl, *clone;
+
+ nvl = nvlist_create(0);
+ ATF_REQUIRE(nvl != NULL);
+
+ nvlist_set_error(nvl, ENOMEM);
+
+ clone = nvlist_clone(nvl);
+ ATF_REQUIRE(clone == NULL);
+
+ nvlist_destroy(nvl);
+}
+
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_pack__empty_nvlist);
ATF_TEST_CASE_BODY(nvlist_pack__empty_nvlist)
{
@@ -550,6 +566,24 @@ ATF_TEST_CASE_BODY(nvlist_pack__multiple_values)
free(packed);
}
+ATF_TEST_CASE_WITHOUT_HEAD(nvlist_pack__error_nvlist);
+ATF_TEST_CASE_BODY(nvlist_pack__error_nvlist)
+{
+ nvlist_t *nvl;
+ void *packed;
+ size_t size;
+
+ nvl = nvlist_create(0);
+ ATF_REQUIRE(nvl != NULL);
+
+ nvlist_set_error(nvl, ENOMEM);
+
+ packed = nvlist_pack(nvl, &size);
+ ATF_REQUIRE(packed == NULL);
+
+ nvlist_destroy(nvl);
+}
+
ATF_TEST_CASE_WITHOUT_HEAD(nvlist_unpack__duplicate_key);
ATF_TEST_CASE_BODY(nvlist_unpack__duplicate_key)
{
@@ -1148,9 +1182,11 @@ ATF_INIT_TEST_CASES(tp)
ATF_ADD_TEST_CASE(tp, nvlist_clone__empty_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_clone__nonempty_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_clone__nested_nvlist);
+ ATF_ADD_TEST_CASE(tp, nvlist_clone__error_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_pack__empty_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_pack__multiple_values);
+ ATF_ADD_TEST_CASE(tp, nvlist_pack__error_nvlist);
ATF_ADD_TEST_CASE(tp, nvlist_unpack__duplicate_key);
ATF_ADD_TEST_CASE(tp, nvlist_move_string__single_insert);
OpenPOWER on IntegriCloud