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>
This commit is contained in:
Pawel Jakub Dawidek 2015-01-30 10:08:38 +00:00
parent 00294559aa
commit aa2e2bdaf2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=277921
3 changed files with 41 additions and 19 deletions

View File

@ -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 ,

View File

@ -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

View File

@ -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);
}
}