aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib
diff options
context:
space:
mode:
authorMariusz Zaborski <oshogbo@FreeBSD.org>2018-06-18 22:57:32 +0000
committerMariusz Zaborski <oshogbo@FreeBSD.org>2018-06-18 22:57:32 +0000
commit24881c060c7b91335603f9a042eeb0bebe550d12 (patch)
treeb44f90c5067dba7c046543bd719d8d927dfd25bc /sys/contrib
parent936a20bb1c05c0507efa9ca437feb4dbacd89200 (diff)
downloadsrc-24881c060c7b91335603f9a042eeb0bebe550d12.tar.gz
src-24881c060c7b91335603f9a042eeb0bebe550d12.zip
libnv: Add nvlist_append_*_array() family of functions.
The nvlist_append_{bool,number,string,nvlist,descriptor}_array() functions allows to dynamically extend array stored in the nvlist. Submitted by: Mindaugas Rasiukevicius <rmind@netbsd.org>
Notes
Notes: svn path=/head/; revision=335347
Diffstat (limited to 'sys/contrib')
-rw-r--r--sys/contrib/libnv/nv_impl.h6
-rw-r--r--sys/contrib/libnv/nvlist.c31
-rw-r--r--sys/contrib/libnv/nvpair.c137
3 files changed, 174 insertions, 0 deletions
diff --git a/sys/contrib/libnv/nv_impl.h b/sys/contrib/libnv/nv_impl.h
index 4bfc07935504..56e01a2bfb31 100644
--- a/sys/contrib/libnv/nv_impl.h
+++ b/sys/contrib/libnv/nv_impl.h
@@ -143,6 +143,12 @@ nvpair_t *nvpair_move_descriptor_array(const char *name, int *value, size_t nite
nvpair_t *nvpair_move_number_array(const char *name, uint64_t *value, size_t nitems);
nvpair_t *nvpair_move_string_array(const char *name, char **value, size_t nitems);
+int nvpair_append_bool_array(nvpair_t *nvp, const bool value);
+int nvpair_append_number_array(nvpair_t *nvp, const uint64_t value);
+int nvpair_append_string_array(nvpair_t *nvp, const char *value);
+int nvpair_append_nvlist_array(nvpair_t *nvp, const nvlist_t *value);
+int nvpair_append_descriptor_array(nvpair_t *nvp, const int value);
+
bool nvpair_get_bool(const nvpair_t *nvp);
uint64_t nvpair_get_number(const nvpair_t *nvp);
const char *nvpair_get_string(const nvpair_t *nvp);
diff --git a/sys/contrib/libnv/nvlist.c b/sys/contrib/libnv/nvlist.c
index cc4c895ecdc0..0101d8c9e8ce 100644
--- a/sys/contrib/libnv/nvlist.c
+++ b/sys/contrib/libnv/nvlist.c
@@ -1607,6 +1607,37 @@ NVLIST_ADD_ARRAY(const int *, descriptor)
#undef NVLIST_ADD_ARRAY
+#define NVLIST_APPEND_ARRAY(vtype, type, TYPE) \
+void \
+nvlist_append_##type##_array(nvlist_t *nvl, const char *name, vtype value)\
+{ \
+ nvpair_t *nvp; \
+ \
+ if (nvlist_error(nvl) != 0) { \
+ ERRNO_SET(nvlist_error(nvl)); \
+ return; \
+ } \
+ nvp = nvlist_find(nvl, NV_TYPE_##TYPE##_ARRAY, name); \
+ if (nvp == NULL) { \
+ nvlist_add_##type##_array(nvl, name, &value, 1); \
+ return; \
+ } \
+ if (nvpair_append_##type##_array(nvp, value) == -1) { \
+ nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM); \
+ ERRNO_SET(nvl->nvl_error); \
+ } \
+}
+
+NVLIST_APPEND_ARRAY(const bool, bool, BOOL)
+NVLIST_APPEND_ARRAY(const uint64_t, number, NUMBER)
+NVLIST_APPEND_ARRAY(const char *, string, STRING)
+NVLIST_APPEND_ARRAY(const nvlist_t *, nvlist, NVLIST)
+#ifndef _KERNEL
+NVLIST_APPEND_ARRAY(const int, descriptor, DESCRIPTOR)
+#endif
+
+#undef NVLIST_APPEND_ARRAY
+
bool
nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp)
{
diff --git a/sys/contrib/libnv/nvpair.c b/sys/contrib/libnv/nvpair.c
index aa561ee0adcb..c00c63827848 100644
--- a/sys/contrib/libnv/nvpair.c
+++ b/sys/contrib/libnv/nvpair.c
@@ -144,6 +144,28 @@ nvpair_allocv(const char *name, int type, uint64_t data, size_t datasize,
return (nvp);
}
+static int
+nvpair_append(nvpair_t *nvp, const void *value, size_t valsize, size_t datasize)
+{
+ void *olddata, *data, *valp;
+ size_t oldlen;
+
+ oldlen = nvp->nvp_nitems * valsize;
+ olddata = (void *)(uintptr_t)nvp->nvp_data;
+ data = nv_realloc(olddata, oldlen + valsize);
+ if (data == NULL) {
+ ERRNO_SET(ENOMEM);
+ return (-1);
+ }
+ valp = (unsigned char *)data + oldlen;
+ memcpy(valp, value, valsize);
+
+ nvp->nvp_data = (uint64_t)(uintptr_t)data;
+ nvp->nvp_datasize += datasize;
+ nvp->nvp_nitems++;
+ return (0);
+}
+
nvlist_t *
nvpair_nvlist(const nvpair_t *nvp)
{
@@ -1913,6 +1935,121 @@ nvpair_get_descriptor_array(const nvpair_t *nvp, size_t *nitems)
}
#endif
+int
+nvpair_append_bool_array(nvpair_t *nvp, const bool value)
+{
+
+ NVPAIR_ASSERT(nvp);
+ PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BOOL_ARRAY);
+ return (nvpair_append(nvp, &value, sizeof(value), sizeof(value)));
+}
+
+int
+nvpair_append_number_array(nvpair_t *nvp, const uint64_t value)
+{
+
+ NVPAIR_ASSERT(nvp);
+ PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NUMBER_ARRAY);
+ return (nvpair_append(nvp, &value, sizeof(value), sizeof(value)));
+}
+
+int
+nvpair_append_string_array(nvpair_t *nvp, const char *value)
+{
+ char *str;
+
+ NVPAIR_ASSERT(nvp);
+ PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING_ARRAY);
+ if (value == NULL) {
+ ERRNO_SET(EINVAL);
+ return (-1);
+ }
+ str = nv_strdup(value);
+ if (str == NULL) {
+ return (-1);
+ }
+ if (nvpair_append(nvp, &str, sizeof(str), strlen(str) + 1) == -1) {
+ nv_free(str);
+ return (-1);
+ }
+ return (0);
+}
+
+int
+nvpair_append_nvlist_array(nvpair_t *nvp, const nvlist_t *value)
+{
+ nvpair_t *tmpnvp;
+ nvlist_t *nvl, *prev;
+ int flags;
+
+ NVPAIR_ASSERT(nvp);
+ PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST_ARRAY);
+ if (value == NULL || nvlist_error(value) != 0 ||
+ nvlist_get_pararr(value, NULL) != NULL) {
+ ERRNO_SET(EINVAL);
+ return (-1);
+ }
+ nvl = nvlist_clone(value);
+ if (nvl == NULL) {
+ return (-1);
+ }
+ flags = nvlist_flags(nvl) | NV_FLAG_IN_ARRAY;
+ nvlist_set_flags(nvl, flags);
+
+ tmpnvp = NULL;
+ if (nvp->nvp_nitems > 0) {
+ nvlist_t **nvls = (void *)(uintptr_t)nvp->nvp_data;
+
+ prev = nvls[nvp->nvp_nitems - 1];
+ PJDLOG_ASSERT(prev != NULL);
+
+ tmpnvp = nvpair_allocv(" ", NV_TYPE_NVLIST,
+ (uint64_t)(uintptr_t)nvl, 0, 0);
+ if (tmpnvp == NULL) {
+ goto fail;
+ }
+ }
+ if (nvpair_append(nvp, &nvl, sizeof(nvl), 0) == -1) {
+ goto fail;
+ }
+ if (tmpnvp) {
+ NVPAIR_ASSERT(tmpnvp);
+ nvlist_set_array_next(prev, tmpnvp);
+ }
+ nvlist_set_parent(nvl, nvp);
+ return (0);
+fail:
+ if (tmpnvp) {
+ nvpair_free(tmpnvp);
+ }
+ nvlist_destroy(nvl);
+ return (-1);
+}
+
+#ifndef _KERNEL
+int
+nvpair_append_descriptor_array(nvpair_t *nvp, const int value)
+{
+ int fd;
+
+ NVPAIR_ASSERT(nvp);
+ PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR_ARRAY);
+ if (value < 0 || !fd_is_valid(value)) {
+ ERRNO_SET(EBADF);
+ return -1;
+ }
+ fd = fcntl(value, F_DUPFD_CLOEXEC, 0);
+ if (fd == -1) {
+ return (-1);
+ }
+ if (nvpair_append(nvp, &fd, sizeof(fd), sizeof(fd)) == -1) {
+ close(fd);
+ return (-1);
+ }
+ return (0);
+}
+#endif
+
void
nvpair_free(nvpair_t *nvp)
{