From 9bf74836226429745ef3e5a3e840dee77141cd02 Mon Sep 17 00:00:00 2001 From: Ryan Stone Date: Sat, 3 May 2014 17:44:46 -0400 Subject: [PATCH 11/17] 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. --- lib/libnv/Makefile | 1 + lib/libnv/nv.3 | 14 +++++++++++++- lib/libnv/nv.h | 1 + lib/libnv/nvlist.c | 8 ++++++++ lib/libnv/tests/nv_tests.cc | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 1 deletion(-) diff --git a/lib/libnv/Makefile b/lib/libnv/Makefile index ddeb1ac..36e70e8 100644 --- a/lib/libnv/Makefile +++ b/lib/libnv/Makefile @@ -19,6 +19,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 28a8e0b..cf9dfe2 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" .\" @@ -246,8 +249,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 9bd438f..bd9a704 100644 --- a/lib/libnv/nv.h +++ b/lib/libnv/nv.h @@ -68,6 +68,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 929ba48..6b17a3d 100644 --- a/lib/libnv/nvlist.c +++ b/lib/libnv/nvlist.c @@ -135,6 +135,14 @@ nvlist_destroy(nvlist_t *nvl) errno = serrno; } +void +nvlist_set_error(nvlist_t *nvl, int error) +{ + + 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 7fca613..c29b273 100644 --- a/lib/libnv/tests/nv_tests.cc +++ b/lib/libnv/tests/nv_tests.cc @@ -405,6 +405,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) { @@ -546,6 +562,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) { @@ -1130,9 +1164,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); -- 1.9.2