2 * Copyright (c) 2009-2013 The FreeBSD Foundation
5 * This software was developed by Pawel Jakub Dawidek under sponsorship from
6 * the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/endian.h>
35 #include <sys/queue.h>
36 #include <sys/socket.h>
55 #include "nvlist_impl.h"
56 #include "nvpair_impl.h"
60 #define PJDLOG_ASSERT(...) assert(__VA_ARGS__)
61 #define PJDLOG_RASSERT(expr, ...) assert(expr)
62 #define PJDLOG_ABORT(...) do { \
63 fprintf(stderr, "%s:%u: ", __FILE__, __LINE__); \
64 fprintf(stderr, __VA_ARGS__); \
65 fprintf(stderr, "\n"); \
70 #define NV_FLAG_PRIVATE_MASK (NV_FLAG_BIG_ENDIAN)
71 #define NV_FLAG_PUBLIC_MASK (NV_FLAG_IGNORE_CASE)
72 #define NV_FLAG_ALL_MASK (NV_FLAG_PRIVATE_MASK | NV_FLAG_PUBLIC_MASK)
74 #define NVLIST_MAGIC 0x6e766c /* "nvl" */
79 struct nvl_head nvl_head;
82 #define NVLIST_ASSERT(nvl) do { \
83 PJDLOG_ASSERT((nvl) != NULL); \
84 PJDLOG_ASSERT((nvl)->nvl_magic == NVLIST_MAGIC); \
87 #define NVPAIR_ASSERT(nvp) nvpair_assert(nvp)
89 #define NVLIST_HEADER_MAGIC 0x6c
90 #define NVLIST_HEADER_VERSION 0x00
91 struct nvlist_header {
95 uint64_t nvlh_descriptors;
100 nvlist_create(int flags)
104 PJDLOG_ASSERT((flags & ~(NV_FLAG_PUBLIC_MASK)) == 0);
106 nvl = malloc(sizeof(*nvl));
108 nvl->nvl_flags = flags;
109 TAILQ_INIT(&nvl->nvl_head);
110 nvl->nvl_magic = NVLIST_MAGIC;
116 nvlist_destroy(nvlist_t *nvl)
128 while ((nvp = nvlist_first_nvpair(nvl)) != NULL) {
129 nvlist_remove_nvpair(nvl, nvp);
139 nvlist_error(const nvlist_t *nvl)
147 return (nvl->nvl_error);
151 nvlist_empty(const nvlist_t *nvl)
155 PJDLOG_ASSERT(nvl->nvl_error == 0);
157 return (nvlist_first_nvpair(nvl) == NULL);
161 nvlist_report_missing(int type, const char *namefmt, va_list nameap)
165 vasprintf(&name, namefmt, nameap);
166 PJDLOG_ABORT("Element '%s' of type %s doesn't exist.",
167 name != NULL ? name : "N/A", nvpair_type_string(type));
171 nvlist_findv(const nvlist_t *nvl, int type, const char *namefmt, va_list nameap)
177 PJDLOG_ASSERT(nvl->nvl_error == 0);
178 PJDLOG_ASSERT(type == NV_TYPE_NONE ||
179 (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST));
181 if (vasprintf(&name, namefmt, nameap) < 0)
184 for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
185 nvp = nvlist_next_nvpair(nvl, nvp)) {
186 if (type != NV_TYPE_NONE && nvpair_type(nvp) != type)
188 if ((nvl->nvl_flags & NV_FLAG_IGNORE_CASE) != 0) {
189 if (strcasecmp(nvpair_name(nvp), name) != 0)
192 if (strcmp(nvpair_name(nvp), name) != 0)
207 nvlist_exists_type(const nvlist_t *nvl, const char *name, int type)
210 return (nvlist_existsf_type(nvl, type, "%s", name));
214 nvlist_existsf_type(const nvlist_t *nvl, int type, const char *namefmt, ...)
219 va_start(nameap, namefmt);
220 ret = nvlist_existsv_type(nvl, type, namefmt, nameap);
227 nvlist_existsv_type(const nvlist_t *nvl, int type, const char *namefmt,
232 PJDLOG_ASSERT(nvl->nvl_error == 0);
233 PJDLOG_ASSERT(type == NV_TYPE_NONE ||
234 (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST));
236 return (nvlist_findv(nvl, type, namefmt, nameap) != NULL);
240 nvlist_free_type(nvlist_t *nvl, const char *name, int type)
243 nvlist_freef_type(nvl, type, "%s", name);
247 nvlist_freef_type(nvlist_t *nvl, int type, const char *namefmt, ...)
251 va_start(nameap, namefmt);
252 nvlist_freev_type(nvl, type, namefmt, nameap);
257 nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap)
263 PJDLOG_ASSERT(nvl->nvl_error == 0);
264 PJDLOG_ASSERT(type == NV_TYPE_NONE ||
265 (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST));
267 va_copy(cnameap, nameap);
268 nvp = nvlist_findv(nvl, type, namefmt, cnameap);
271 nvlist_free_nvpair(nvl, nvp);
273 nvlist_report_missing(type, namefmt, nameap);
277 nvlist_clone(const nvlist_t *nvl)
280 nvpair_t *nvp, *newnvp;
284 if (nvl->nvl_error != 0) {
285 errno = nvl->nvl_error;
289 newnvl = nvlist_create(nvl->nvl_flags & NV_FLAG_PUBLIC_MASK);
290 for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
291 nvp = nvlist_next_nvpair(nvl, nvp)) {
292 newnvp = nvpair_clone(nvp);
295 nvlist_move_nvpair(newnvl, newnvp);
298 nvlist_destroy(newnvl);
305 * Dump content of nvlist.
308 nvlist_xdump(const nvlist_t *nvl, int fd, int level)
312 PJDLOG_ASSERT(level < 3);
314 if (nvlist_error(nvl) != 0) {
315 dprintf(fd, "%*serror: %d\n", level * 4, "",
320 for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
321 nvp = nvlist_next_nvpair(nvl, nvp)) {
322 dprintf(fd, "%*s%s (%s):", level * 4, "", nvpair_name(nvp),
323 nvpair_type_string(nvpair_type(nvp)));
324 switch (nvpair_type(nvp)) {
326 dprintf(fd, " null\n");
329 dprintf(fd, " %s\n", nvpair_get_bool(nvp) ?
333 dprintf(fd, " %ju (%jd) (0x%jx)\n",
334 (uintmax_t)nvpair_get_number(nvp),
335 (intmax_t)nvpair_get_number(nvp),
336 (uintmax_t)nvpair_get_number(nvp));
339 dprintf(fd, " [%s]\n", nvpair_get_string(nvp));
343 nvlist_xdump(nvpair_get_nvlist(nvp), fd, level + 1);
345 case NV_TYPE_DESCRIPTOR:
346 dprintf(fd, " %d\n", nvpair_get_descriptor(nvp));
350 const unsigned char *binary;
354 binary = nvpair_get_binary(nvp, &size);
355 dprintf(fd, " %zu ", size);
356 for (ii = 0; ii < size; ii++)
357 dprintf(fd, "%02hhx", binary[ii]);
362 PJDLOG_ABORT("Unknown type: %d.", nvpair_type(nvp));
368 nvlist_dump(const nvlist_t *nvl, int fd)
371 nvlist_xdump(nvl, fd, 0);
375 nvlist_fdump(const nvlist_t *nvl, FILE *fp)
379 nvlist_dump(nvl, fileno(fp));
383 * The function obtains size of the nvlist after nvlist_pack().
384 * Additional argument 'level' allows to track how deep are we as we obtain
385 * size of the NV_TYPE_NVLIST elements using recursion. We allow at most
386 * three levels of recursion.
389 nvlist_xsize(const nvlist_t *nvl, int level)
395 PJDLOG_ASSERT(nvl->nvl_error == 0);
396 PJDLOG_ASSERT(level < 3);
398 size = sizeof(struct nvlist_header);
399 for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
400 nvp = nvlist_next_nvpair(nvl, nvp)) {
401 size += nvpair_header_size();
402 size += strlen(nvpair_name(nvp)) + 1;
403 if (nvpair_type(nvp) == NV_TYPE_NVLIST)
404 size += nvlist_xsize(nvpair_get_nvlist(nvp), level + 1);
406 size += nvpair_size(nvp);
413 nvlist_size(const nvlist_t *nvl)
416 return (nvlist_xsize(nvl, 0));
420 nvlist_xdescriptors(const nvlist_t *nvl, int *descs, int level)
425 PJDLOG_ASSERT(nvl->nvl_error == 0);
426 PJDLOG_ASSERT(level < 3);
428 for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
429 nvp = nvlist_next_nvpair(nvl, nvp)) {
430 switch (nvpair_type(nvp)) {
431 case NV_TYPE_DESCRIPTOR:
432 *descs = nvpair_get_descriptor(nvp);
436 descs = nvlist_xdescriptors(nvpair_get_nvlist(nvp),
446 nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp)
451 nitems = nvlist_ndescriptors(nvl);
452 fds = malloc(sizeof(fds[0]) * (nitems + 1));
456 nvlist_xdescriptors(nvl, fds, 0);
464 nvlist_xndescriptors(const nvlist_t *nvl, int level)
470 PJDLOG_ASSERT(nvl->nvl_error == 0);
471 PJDLOG_ASSERT(level < 3);
474 for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
475 nvp = nvlist_next_nvpair(nvl, nvp)) {
476 switch (nvpair_type(nvp)) {
477 case NV_TYPE_DESCRIPTOR:
481 ndescs += nvlist_xndescriptors(nvpair_get_nvlist(nvp),
491 nvlist_ndescriptors(const nvlist_t *nvl)
494 return (nvlist_xndescriptors(nvl, 0));
497 static unsigned char *
498 nvlist_pack_header(const nvlist_t *nvl, unsigned char *ptr, size_t *leftp)
500 struct nvlist_header nvlhdr;
504 nvlhdr.nvlh_magic = NVLIST_HEADER_MAGIC;
505 nvlhdr.nvlh_version = NVLIST_HEADER_VERSION;
506 nvlhdr.nvlh_flags = nvl->nvl_flags;
507 #if BYTE_ORDER == BIG_ENDIAN
508 nvlhdr.nvlh_flags |= NV_FLAG_BIG_ENDIAN;
510 nvlhdr.nvlh_descriptors = nvlist_ndescriptors(nvl);
511 nvlhdr.nvlh_size = *leftp - sizeof(nvlhdr);
512 PJDLOG_ASSERT(*leftp >= sizeof(nvlhdr));
513 memcpy(ptr, &nvlhdr, sizeof(nvlhdr));
514 ptr += sizeof(nvlhdr);
515 *leftp -= sizeof(nvlhdr);
521 nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
523 unsigned char *buf, *ptr;
529 if (nvl->nvl_error != 0) {
530 errno = nvl->nvl_error;
534 size = nvlist_size(nvl);
542 ptr = nvlist_pack_header(nvl, ptr, &left);
544 for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
545 nvp = nvlist_next_nvpair(nvl, nvp)) {
546 ptr = nvpair_pack(nvp, ptr, fdidxp, &left);
559 nvlist_pack(const nvlist_t *nvl, size_t *sizep)
564 if (nvl->nvl_error != 0) {
565 errno = nvl->nvl_error;
569 if (nvlist_ndescriptors(nvl) > 0) {
574 return (nvlist_xpack(nvl, NULL, sizep));
578 nvlist_check_header(struct nvlist_header *nvlhdrp)
581 if (nvlhdrp->nvlh_magic != NVLIST_HEADER_MAGIC) {
585 if ((nvlhdrp->nvlh_flags &= ~NV_FLAG_ALL_MASK) != 0) {
589 #if BYTE_ORDER == BIG_ENDIAN
590 if ((nvlhdrp->nvlh_flags & NV_FLAG_BIG_ENDIAN) == 0) {
591 nvlhdrp->nvlh_size = le64toh(nvlhdrp->nvlh_size);
592 nvlhdrp->nvlh_descriptors = le64toh(nvlhdrp->nvlh_descriptors);
595 if ((nvlhdrp->nvlh_flags & NV_FLAG_BIG_ENDIAN) != 0) {
596 nvlhdrp->nvlh_size = be64toh(nvlhdrp->nvlh_size);
597 nvlhdrp->nvlh_descriptors = be64toh(nvlhdrp->nvlh_descriptors);
603 static const unsigned char *
604 nvlist_unpack_header(nvlist_t *nvl, const unsigned char *ptr, size_t nfds,
605 int *flagsp, size_t *leftp)
607 struct nvlist_header nvlhdr;
609 if (*leftp < sizeof(nvlhdr))
612 memcpy(&nvlhdr, ptr, sizeof(nvlhdr));
614 if (!nvlist_check_header(&nvlhdr))
617 if (nvlhdr.nvlh_size != *leftp - sizeof(nvlhdr))
621 * nvlh_descriptors might be smaller than nfds in embedded nvlists.
623 if (nvlhdr.nvlh_descriptors > nfds)
626 if ((nvlhdr.nvlh_flags & ~NV_FLAG_ALL_MASK) != 0)
629 nvl->nvl_flags = (nvlhdr.nvlh_flags & NV_FLAG_PUBLIC_MASK);
631 ptr += sizeof(nvlhdr);
632 *flagsp = (int)nvlhdr.nvlh_flags;
633 *leftp -= sizeof(nvlhdr);
642 nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds)
644 const unsigned char *ptr;
653 nvl = nvlist_create(0);
657 ptr = nvlist_unpack_header(nvl, ptr, nfds, &flags, &left);
662 ptr = nvpair_unpack(flags, ptr, &left, fds, nfds, &nvp);
665 nvlist_move_nvpair(nvl, nvp);
675 nvlist_unpack(const void *buf, size_t size)
678 return (nvlist_xunpack(buf, size, NULL, 0));
682 nvlist_send(int sock, const nvlist_t *nvl)
684 size_t datasize, nfds;
690 if (nvlist_error(nvl) != 0) {
691 errno = nvlist_error(nvl);
695 fds = nvlist_descriptors(nvl, &nfds);
703 data = nvlist_xpack(nvl, &fdidx, &datasize);
707 if (buf_send(sock, data, datasize) == -1)
711 if (fd_send(sock, fds, nfds) == -1)
725 nvlist_recv(int sock)
727 struct nvlist_header nvlhdr;
733 if (buf_recv(sock, &nvlhdr, sizeof(nvlhdr)) == -1)
736 if (!nvlist_check_header(&nvlhdr))
739 nfds = (size_t)nvlhdr.nvlh_descriptors;
740 size = sizeof(nvlhdr) + (size_t)nvlhdr.nvlh_size;
746 memcpy(buf, &nvlhdr, sizeof(nvlhdr));
751 if (buf_recv(sock, buf + sizeof(nvlhdr), size - sizeof(nvlhdr)) == -1)
755 fds = malloc(nfds * sizeof(fds[0]));
758 if (fd_recv(sock, fds, nfds) == -1)
762 nvl = nvlist_xunpack(buf, size, fds, nfds);
777 nvlist_xfer(int sock, nvlist_t *nvl)
780 if (nvlist_send(sock, nvl) < 0) {
785 return (nvlist_recv(sock));
789 nvlist_first_nvpair(const nvlist_t *nvl)
794 return (TAILQ_FIRST(&nvl->nvl_head));
798 nvlist_next_nvpair(const nvlist_t *nvl, const nvpair_t *nvp)
804 PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl);
806 retnvp = nvpair_next(nvp);
807 PJDLOG_ASSERT(retnvp == NULL || nvpair_nvlist(retnvp) == nvl);
814 nvlist_prev_nvpair(const nvlist_t *nvl, const nvpair_t *nvp)
820 PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl);
822 retnvp = nvpair_prev(nvp);
823 PJDLOG_ASSERT(nvpair_nvlist(retnvp) == nvl);
829 nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep)
834 PJDLOG_ASSERT(cookiep != NULL);
836 if (*cookiep == NULL)
837 nvp = nvlist_first_nvpair(nvl);
839 nvp = nvlist_next_nvpair(nvl, *cookiep);
843 *typep = nvpair_type(nvp);
845 return (nvpair_name(nvp));
849 nvlist_exists(const nvlist_t *nvl, const char *name)
852 return (nvlist_existsf(nvl, "%s", name));
855 #define NVLIST_EXISTS(type) \
857 nvlist_exists_##type(const nvlist_t *nvl, const char *name) \
860 return (nvlist_existsf_##type(nvl, "%s", name)); \
865 NVLIST_EXISTS(number)
866 NVLIST_EXISTS(string)
867 NVLIST_EXISTS(nvlist)
868 NVLIST_EXISTS(descriptor)
869 NVLIST_EXISTS(binary)
874 nvlist_existsf(const nvlist_t *nvl, const char *namefmt, ...)
879 va_start(nameap, namefmt);
880 ret = nvlist_existsv(nvl, namefmt, nameap);
885 #define NVLIST_EXISTSF(type) \
887 nvlist_existsf_##type(const nvlist_t *nvl, const char *namefmt, ...) \
892 va_start(nameap, namefmt); \
893 ret = nvlist_existsv_##type(nvl, namefmt, nameap); \
900 NVLIST_EXISTSF(number)
901 NVLIST_EXISTSF(string)
902 NVLIST_EXISTSF(nvlist)
903 NVLIST_EXISTSF(descriptor)
904 NVLIST_EXISTSF(binary)
906 #undef NVLIST_EXISTSF
909 nvlist_existsv(const nvlist_t *nvl, const char *namefmt, va_list nameap)
912 return (nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap) != NULL);
915 #define NVLIST_EXISTSV(type, TYPE) \
917 nvlist_existsv_##type(const nvlist_t *nvl, const char *namefmt, \
921 return (nvlist_findv(nvl, NV_TYPE_##TYPE, namefmt, nameap) != \
925 NVLIST_EXISTSV(null, NULL)
926 NVLIST_EXISTSV(bool, BOOL)
927 NVLIST_EXISTSV(number, NUMBER)
928 NVLIST_EXISTSV(string, STRING)
929 NVLIST_EXISTSV(nvlist, NVLIST)
930 NVLIST_EXISTSV(descriptor, DESCRIPTOR)
931 NVLIST_EXISTSV(binary, BINARY)
933 #undef NVLIST_EXISTSV
936 nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp)
942 if (nvlist_error(nvl) != 0) {
943 errno = nvlist_error(nvl);
946 if (nvlist_exists(nvl, nvpair_name(nvp))) {
947 nvl->nvl_error = errno = EEXIST;
951 newnvp = nvpair_clone(nvp);
952 if (newnvp == NULL) {
953 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
957 nvpair_insert(&nvl->nvl_head, newnvp, nvl);
961 nvlist_add_null(nvlist_t *nvl, const char *name)
964 nvlist_addf_null(nvl, "%s", name);
968 nvlist_add_bool(nvlist_t *nvl, const char *name, bool value)
971 nvlist_addf_bool(nvl, value, "%s", name);
975 nvlist_add_number(nvlist_t *nvl, const char *name, uint64_t value)
978 nvlist_addf_number(nvl, value, "%s", name);
982 nvlist_add_string(nvlist_t *nvl, const char *name, const char *value)
985 nvlist_addf_string(nvl, value, "%s", name);
989 nvlist_add_stringf(nvlist_t *nvl, const char *name, const char *valuefmt, ...)
993 va_start(valueap, valuefmt);
994 nvlist_add_stringv(nvl, name, valuefmt, valueap);
999 nvlist_add_stringv(nvlist_t *nvl, const char *name, const char *valuefmt,
1004 if (nvlist_error(nvl) != 0) {
1005 errno = nvlist_error(nvl);
1009 nvp = nvpair_create_stringv(name, valuefmt, valueap);
1011 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1013 nvlist_move_nvpair(nvl, nvp);
1017 nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value)
1020 nvlist_addf_nvlist(nvl, value, "%s", name);
1024 nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value)
1027 nvlist_addf_descriptor(nvl, value, "%s", name);
1031 nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value,
1035 nvlist_addf_binary(nvl, value, size, "%s", name);
1039 nvlist_addf_null(nvlist_t *nvl, const char *namefmt, ...)
1043 va_start(nameap, namefmt);
1044 nvlist_addv_null(nvl, namefmt, nameap);
1049 nvlist_addf_bool(nvlist_t *nvl, bool value, const char *namefmt, ...)
1053 va_start(nameap, namefmt);
1054 nvlist_addv_bool(nvl, value, namefmt, nameap);
1059 nvlist_addf_number(nvlist_t *nvl, uint64_t value, const char *namefmt, ...)
1063 va_start(nameap, namefmt);
1064 nvlist_addv_number(nvl, value, namefmt, nameap);
1069 nvlist_addf_string(nvlist_t *nvl, const char *value, const char *namefmt, ...)
1073 va_start(nameap, namefmt);
1074 nvlist_addv_string(nvl, value, namefmt, nameap);
1079 nvlist_addf_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt,
1084 va_start(nameap, namefmt);
1085 nvlist_addv_nvlist(nvl, value, namefmt, nameap);
1090 nvlist_addf_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...)
1094 va_start(nameap, namefmt);
1095 nvlist_addv_descriptor(nvl, value, namefmt, nameap);
1100 nvlist_addf_binary(nvlist_t *nvl, const void *value, size_t size,
1101 const char *namefmt, ...)
1105 va_start(nameap, namefmt);
1106 nvlist_addv_binary(nvl, value, size, namefmt, nameap);
1111 nvlist_addv_null(nvlist_t *nvl, const char *namefmt, va_list nameap)
1115 if (nvlist_error(nvl) != 0) {
1116 errno = nvlist_error(nvl);
1120 nvp = nvpair_createv_null(namefmt, nameap);
1122 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1124 nvlist_move_nvpair(nvl, nvp);
1128 nvlist_addv_bool(nvlist_t *nvl, bool value, const char *namefmt, va_list nameap)
1132 if (nvlist_error(nvl) != 0) {
1133 errno = nvlist_error(nvl);
1137 nvp = nvpair_createv_bool(value, namefmt, nameap);
1139 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1141 nvlist_move_nvpair(nvl, nvp);
1145 nvlist_addv_number(nvlist_t *nvl, uint64_t value, const char *namefmt,
1150 if (nvlist_error(nvl) != 0) {
1151 errno = nvlist_error(nvl);
1155 nvp = nvpair_createv_number(value, namefmt, nameap);
1157 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1159 nvlist_move_nvpair(nvl, nvp);
1163 nvlist_addv_string(nvlist_t *nvl, const char *value, const char *namefmt,
1168 if (nvlist_error(nvl) != 0) {
1169 errno = nvlist_error(nvl);
1173 nvp = nvpair_createv_string(value, namefmt, nameap);
1175 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1177 nvlist_move_nvpair(nvl, nvp);
1181 nvlist_addv_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt,
1186 if (nvlist_error(nvl) != 0) {
1187 errno = nvlist_error(nvl);
1191 nvp = nvpair_createv_nvlist(value, namefmt, nameap);
1193 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1195 nvlist_move_nvpair(nvl, nvp);
1199 nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt,
1204 if (nvlist_error(nvl) != 0) {
1205 errno = nvlist_error(nvl);
1209 nvp = nvpair_createv_descriptor(value, namefmt, nameap);
1211 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1213 nvlist_move_nvpair(nvl, nvp);
1217 nvlist_addv_binary(nvlist_t *nvl, const void *value, size_t size,
1218 const char *namefmt, va_list nameap)
1222 if (nvlist_error(nvl) != 0) {
1223 errno = nvlist_error(nvl);
1227 nvp = nvpair_createv_binary(value, size, namefmt, nameap);
1229 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1231 nvlist_move_nvpair(nvl, nvp);
1235 nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1239 PJDLOG_ASSERT(nvpair_nvlist(nvp) == NULL);
1241 if (nvlist_error(nvl) != 0) {
1243 errno = nvlist_error(nvl);
1246 if (nvlist_exists(nvl, nvpair_name(nvp))) {
1248 nvl->nvl_error = errno = EEXIST;
1252 nvpair_insert(&nvl->nvl_head, nvp, nvl);
1255 #define NVLIST_MOVE(vtype, type) \
1257 nvlist_move_##type(nvlist_t *nvl, const char *name, vtype value) \
1260 nvlist_movef_##type(nvl, value, "%s", name); \
1263 NVLIST_MOVE(char *, string)
1264 NVLIST_MOVE(nvlist_t *, nvlist)
1265 NVLIST_MOVE(int, descriptor)
1270 nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size)
1273 nvlist_movef_binary(nvl, value, size, "%s", name);
1276 #define NVLIST_MOVEF(vtype, type) \
1278 nvlist_movef_##type(nvlist_t *nvl, vtype value, const char *namefmt, \
1283 va_start(nameap, namefmt); \
1284 nvlist_movev_##type(nvl, value, namefmt, nameap); \
1288 NVLIST_MOVEF(char *, string)
1289 NVLIST_MOVEF(nvlist_t *, nvlist)
1290 NVLIST_MOVEF(int, descriptor)
1295 nvlist_movef_binary(nvlist_t *nvl, void *value, size_t size,
1296 const char *namefmt, ...)
1300 va_start(nameap, namefmt);
1301 nvlist_movev_binary(nvl, value, size, namefmt, nameap);
1306 nvlist_movev_string(nvlist_t *nvl, char *value, const char *namefmt,
1311 if (nvlist_error(nvl) != 0) {
1313 errno = nvlist_error(nvl);
1317 nvp = nvpair_movev_string(value, namefmt, nameap);
1319 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1321 nvlist_move_nvpair(nvl, nvp);
1325 nvlist_movev_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt,
1330 if (nvlist_error(nvl) != 0) {
1331 nvlist_destroy(value);
1332 errno = nvlist_error(nvl);
1336 nvp = nvpair_movev_nvlist(value, namefmt, nameap);
1338 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1340 nvlist_move_nvpair(nvl, nvp);
1344 nvlist_movev_descriptor(nvlist_t *nvl, int value, const char *namefmt,
1349 if (nvlist_error(nvl) != 0) {
1351 errno = nvlist_error(nvl);
1355 nvp = nvpair_movev_descriptor(value, namefmt, nameap);
1357 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1359 nvlist_move_nvpair(nvl, nvp);
1363 nvlist_movev_binary(nvlist_t *nvl, void *value, size_t size,
1364 const char *namefmt, va_list nameap)
1368 if (nvlist_error(nvl) != 0) {
1370 errno = nvlist_error(nvl);
1374 nvp = nvpair_movev_binary(value, size, namefmt, nameap);
1376 nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
1378 nvlist_move_nvpair(nvl, nvp);
1381 #define NVLIST_GET(ftype, type) \
1383 nvlist_get_##type(const nvlist_t *nvl, const char *name) \
1386 return (nvlist_getf_##type(nvl, "%s", name)); \
1389 NVLIST_GET(const nvpair_t *, nvpair)
1390 NVLIST_GET(bool, bool)
1391 NVLIST_GET(uint64_t, number)
1392 NVLIST_GET(const char *, string)
1393 NVLIST_GET(const nvlist_t *, nvlist)
1394 NVLIST_GET(int, descriptor)
1399 nvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep)
1402 return (nvlist_getf_binary(nvl, sizep, "%s", name));
1405 #define NVLIST_GETF(ftype, type) \
1407 nvlist_getf_##type(const nvlist_t *nvl, const char *namefmt, ...) \
1412 va_start(nameap, namefmt); \
1413 value = nvlist_getv_##type(nvl, namefmt, nameap); \
1419 NVLIST_GETF(const nvpair_t *, nvpair)
1420 NVLIST_GETF(bool, bool)
1421 NVLIST_GETF(uint64_t, number)
1422 NVLIST_GETF(const char *, string)
1423 NVLIST_GETF(const nvlist_t *, nvlist)
1424 NVLIST_GETF(int, descriptor)
1429 nvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, ...)
1434 va_start(nameap, namefmt);
1435 value = nvlist_getv_binary(nvl, sizep, namefmt, nameap);
1442 nvlist_getv_nvpair(const nvlist_t *nvl, const char *namefmt, va_list nameap)
1445 return (nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap));
1448 #define NVLIST_GETV(ftype, type, TYPE) \
1450 nvlist_getv_##type(const nvlist_t *nvl, const char *namefmt, \
1454 const nvpair_t *nvp; \
1456 va_copy(cnameap, nameap); \
1457 nvp = nvlist_findv(nvl, NV_TYPE_##TYPE, namefmt, cnameap); \
1460 nvlist_report_missing(NV_TYPE_##TYPE, namefmt, nameap); \
1461 return (nvpair_get_##type(nvp)); \
1464 NVLIST_GETV(bool, bool, BOOL)
1465 NVLIST_GETV(uint64_t, number, NUMBER)
1466 NVLIST_GETV(const char *, string, STRING)
1467 NVLIST_GETV(const nvlist_t *, nvlist, NVLIST)
1468 NVLIST_GETV(int, descriptor, DESCRIPTOR)
1473 nvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt,
1477 const nvpair_t *nvp;
1479 va_copy(cnameap, nameap);
1480 nvp = nvlist_findv(nvl, NV_TYPE_BINARY, namefmt, cnameap);
1483 nvlist_report_missing(NV_TYPE_BINARY, namefmt, nameap);
1485 return (nvpair_get_binary(nvp, sizep));
1488 #define NVLIST_TAKE(ftype, type) \
1490 nvlist_take_##type(nvlist_t *nvl, const char *name) \
1493 return (nvlist_takef_##type(nvl, "%s", name)); \
1496 NVLIST_TAKE(nvpair_t *, nvpair)
1497 NVLIST_TAKE(bool, bool)
1498 NVLIST_TAKE(uint64_t, number)
1499 NVLIST_TAKE(char *, string)
1500 NVLIST_TAKE(nvlist_t *, nvlist)
1501 NVLIST_TAKE(int, descriptor)
1506 nvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep)
1509 return (nvlist_takef_binary(nvl, sizep, "%s", name));
1512 #define NVLIST_TAKEF(ftype, type) \
1514 nvlist_takef_##type(nvlist_t *nvl, const char *namefmt, ...) \
1519 va_start(nameap, namefmt); \
1520 value = nvlist_takev_##type(nvl, namefmt, nameap); \
1526 NVLIST_TAKEF(nvpair_t *, nvpair)
1527 NVLIST_TAKEF(bool, bool)
1528 NVLIST_TAKEF(uint64_t, number)
1529 NVLIST_TAKEF(char *, string)
1530 NVLIST_TAKEF(nvlist_t *, nvlist)
1531 NVLIST_TAKEF(int, descriptor)
1536 nvlist_takef_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, ...)
1541 va_start(nameap, namefmt);
1542 value = nvlist_takev_binary(nvl, sizep, namefmt, nameap);
1549 nvlist_takev_nvpair(nvlist_t *nvl, const char *namefmt, va_list nameap)
1553 nvp = nvlist_findv(nvl, NV_TYPE_NONE, namefmt, nameap);
1555 nvlist_remove_nvpair(nvl, nvp);
1559 #define NVLIST_TAKEV(ftype, type, TYPE) \
1561 nvlist_takev_##type(nvlist_t *nvl, const char *namefmt, va_list nameap) \
1567 va_copy(cnameap, nameap); \
1568 nvp = nvlist_findv(nvl, NV_TYPE_##TYPE, namefmt, cnameap); \
1571 nvlist_report_missing(NV_TYPE_##TYPE, namefmt, nameap); \
1572 value = (ftype)(intptr_t)nvpair_get_##type(nvp); \
1573 nvlist_remove_nvpair(nvl, nvp); \
1574 nvpair_free_structure(nvp); \
1578 NVLIST_TAKEV(bool, bool, BOOL)
1579 NVLIST_TAKEV(uint64_t, number, NUMBER)
1580 NVLIST_TAKEV(char *, string, STRING)
1581 NVLIST_TAKEV(nvlist_t *, nvlist, NVLIST)
1582 NVLIST_TAKEV(int, descriptor, DESCRIPTOR)
1587 nvlist_takev_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt,
1594 va_copy(cnameap, nameap);
1595 nvp = nvlist_findv(nvl, NV_TYPE_BINARY, namefmt, cnameap);
1598 nvlist_report_missing(NV_TYPE_BINARY, namefmt, nameap);
1600 value = (void *)(intptr_t)nvpair_get_binary(nvp, sizep);
1601 nvlist_remove_nvpair(nvl, nvp);
1602 nvpair_free_structure(nvp);
1607 nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1612 PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl);
1614 nvpair_remove(&nvl->nvl_head, nvp, nvl);
1618 nvlist_free(nvlist_t *nvl, const char *name)
1621 nvlist_freef(nvl, "%s", name);
1624 #define NVLIST_FREE(type) \
1626 nvlist_free_##type(nvlist_t *nvl, const char *name) \
1629 nvlist_freef_##type(nvl, "%s", name); \
1637 NVLIST_FREE(descriptor)
1643 nvlist_freef(nvlist_t *nvl, const char *namefmt, ...)
1647 va_start(nameap, namefmt);
1648 nvlist_freev(nvl, namefmt, nameap);
1652 #define NVLIST_FREEF(type) \
1654 nvlist_freef_##type(nvlist_t *nvl, const char *namefmt, ...) \
1658 va_start(nameap, namefmt); \
1659 nvlist_freev_##type(nvl, namefmt, nameap); \
1665 NVLIST_FREEF(number)
1666 NVLIST_FREEF(string)
1667 NVLIST_FREEF(nvlist)
1668 NVLIST_FREEF(descriptor)
1669 NVLIST_FREEF(binary)
1674 nvlist_freev(nvlist_t *nvl, const char *namefmt, va_list nameap)
1677 nvlist_freev_type(nvl, NV_TYPE_NONE, namefmt, nameap);
1680 #define NVLIST_FREEV(type, TYPE) \
1682 nvlist_freev_##type(nvlist_t *nvl, const char *namefmt, va_list nameap) \
1685 nvlist_freev_type(nvl, NV_TYPE_##TYPE, namefmt, nameap); \
1688 NVLIST_FREEV(null, NULL)
1689 NVLIST_FREEV(bool, BOOL)
1690 NVLIST_FREEV(number, NUMBER)
1691 NVLIST_FREEV(string, STRING)
1692 NVLIST_FREEV(nvlist, NVLIST)
1693 NVLIST_FREEV(descriptor, DESCRIPTOR)
1694 NVLIST_FREEV(binary, BINARY)
1698 nvlist_free_nvpair(nvlist_t *nvl, nvpair_t *nvp)
1703 PJDLOG_ASSERT(nvpair_nvlist(nvp) == nvl);
1705 nvlist_remove_nvpair(nvl, nvp);