summaryrefslogtreecommitdiffstats
path: root/lib/libnv
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2015-01-30 10:08:38 +0000
committerpjd <pjd@FreeBSD.org>2015-01-30 10:08:38 +0000
commit798c260360aa2655668a54cde1ccf742a182f923 (patch)
tree8169f47c68f89cbe2c23c200acc1f7acbd1f39c1 /lib/libnv
parentd08c53259eac79d61d0f15af9d8a2c5e09e4f89d (diff)
downloadFreeBSD-src-798c260360aa2655668a54cde1ccf742a182f923.zip
FreeBSD-src-798c260360aa2655668a54cde1ccf742a182f923.tar.gz
Modify nvlist_get_parent() API to take additional cookie argument.
This allow for non-recursive iteration over nested nvlists, as in documented example. Submitted by: Mariusz Zaborski <oshogbo@FreeBSD.org>
Diffstat (limited to 'lib/libnv')
-rw-r--r--lib/libnv/nv.326
-rw-r--r--lib/libnv/nv.h2
-rw-r--r--lib/libnv/nvlist.c32
3 files changed, 41 insertions, 19 deletions
diff --git a/lib/libnv/nv.3 b/lib/libnv/nv.3
index 29ba744..6ff6329 100644
--- a/lib/libnv/nv.3
+++ b/lib/libnv/nv.3
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 25, 2014
+.Dd January 30, 2015
.Dt NV 3
.Os
.Sh NAME
@@ -151,7 +151,7 @@
.Ft "const void *"
.Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep"
.Ft "const nvlist_t *"
-.Fn nvlist_get_parent "const nvlist_t *nvl"
+.Fn nvlist_get_parent "const nvlist_t *nvl" "void **cookiep"
.\"
.Ft bool
.Fn nvlist_take_bool "nvlist_t *nvl" "const char *name"
@@ -588,6 +588,28 @@ while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
printf("\\n");
}
.Ed
+.Pp
+Iterating over every nested nvlist:
+.Bd -literal
+nvlist_t *nvl;
+const char *name;
+void *cookie;
+int type;
+
+nvl = nvlist_recv(sock);
+if (nvl == NULL)
+ err(1, "nvlist_recv() failed");
+
+cookie = NULL;
+do {
+ while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
+ if (type == NV_TYPE_NVLIST) {
+ nvl = nvlist_get_nvlist(nvl, name);
+ cookie = NULL;
+ }
+ }
+} while ((nvl = nvlist_get_parent(nvl, &cookie)) != NULL);
+.Ed
.Sh SEE ALSO
.Xr close 2 ,
.Xr dup 2 ,
diff --git a/lib/libnv/nv.h b/lib/libnv/nv.h
index 1b55be1..9f0bb5d 100644
--- a/lib/libnv/nv.h
+++ b/lib/libnv/nv.h
@@ -83,7 +83,7 @@ nvlist_t *nvlist_xfer(int sock, nvlist_t *nvl);
const char *nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep);
-const nvlist_t *nvlist_get_parent(const nvlist_t *nvl);
+const nvlist_t *nvlist_get_parent(const nvlist_t *nvl, void **cookiep);
/*
* The nvlist_exists functions check if the given name (optionally of the given
diff --git a/lib/libnv/nvlist.c b/lib/libnv/nvlist.c
index b495441..a94b3da 100644
--- a/lib/libnv/nvlist.c
+++ b/lib/libnv/nvlist.c
@@ -159,15 +159,19 @@ nvlist_get_nvpair_parent(const nvlist_t *nvl)
}
const nvlist_t *
-nvlist_get_parent(const nvlist_t *nvl)
+nvlist_get_parent(const nvlist_t *nvl, void **cookiep)
{
+ nvpair_t *nvp;
NVLIST_ASSERT(nvl);
- if (nvl->nvl_parent == NULL)
+ nvp = nvl->nvl_parent;
+ if (cookiep != NULL)
+ *cookiep = nvp;
+ if (nvp == NULL)
return (NULL);
- return (nvpair_nvlist(nvl->nvl_parent));
+ return (nvpair_nvlist(nvp));
}
void
@@ -384,11 +388,10 @@ nvlist_dump(const nvlist_t *nvl, int fd)
dprintf(fd, "\n");
nvl = nvpair_get_nvlist(nvp);
if (nvlist_dump_error_check(nvl, fd, level + 1)) {
- nvl = nvlist_get_parent(nvl);
+ nvl = nvlist_get_parent(nvl, (void **)&nvp);
break;
}
- level += 1;
- nvp = nvlist_first_nvpair(nvl);
+ level++;
continue;
case NV_TYPE_DESCRIPTOR:
dprintf(fd, " %d\n", nvpair_get_descriptor(nvp));
@@ -411,11 +414,10 @@ nvlist_dump(const nvlist_t *nvl, int fd)
}
while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
- nvp = nvlist_get_nvpair_parent(nvl);
- if (nvp == NULL)
+ nvl = nvlist_get_parent(nvl, (void **)&nvp);
+ if (nvl == NULL)
return;
- nvl = nvlist_get_parent(nvl);
- level --;
+ level--;
}
}
}
@@ -457,10 +459,9 @@ nvlist_size(const nvlist_t *nvl)
}
while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
- nvp = nvlist_get_nvpair_parent(nvl);
- if (nvp == NULL)
+ nvl = nvlist_get_parent(nvl, (void **)&nvp);
+ if (nvl == NULL)
goto out;
- nvl = nvlist_get_parent(nvl);
}
}
@@ -635,13 +636,12 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
return (NULL);
}
while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
- nvp = nvlist_get_nvpair_parent(nvl);
- if (nvp == NULL)
+ nvl = nvlist_get_parent(nvl, (void **)&nvp);
+ if (nvl == NULL)
goto out;
ptr = nvpair_pack_nvlist_up(ptr, &left);
if (ptr == NULL)
goto out;
- nvl = nvlist_get_parent(nvl);
}
}
OpenPOWER on IntegriCloud