| 1116 | } |
| 1117 | |
| 1118 | static nvlist_t * |
| 1119 | nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds, |
| 1120 | int flags) |
| 1121 | { |
| 1122 | const unsigned char *ptr; |
| 1123 | nvlist_t *nvl, *retnvl, *tmpnvl, *array; |
| 1124 | nvpair_t *nvp; |
| 1125 | size_t left; |
| 1126 | bool isbe; |
| 1127 | |
| 1128 | PJDLOG_ASSERT((flags & ~(NV_FLAG_PUBLIC_MASK)) == 0); |
| 1129 | |
| 1130 | left = size; |
| 1131 | ptr = buf; |
| 1132 | |
| 1133 | tmpnvl = array = NULL; |
| 1134 | nvl = retnvl = nvlist_create(0); |
| 1135 | if (nvl == NULL) |
| 1136 | goto fail; |
| 1137 | |
| 1138 | ptr = nvlist_unpack_header(nvl, ptr, nfds, &isbe, &left); |
| 1139 | if (ptr == NULL) |
| 1140 | goto fail; |
| 1141 | if (nvl->nvl_flags != flags) { |
| 1142 | ERRNO_SET(EILSEQ); |
| 1143 | goto fail; |
| 1144 | } |
| 1145 | |
| 1146 | while (left > 0) { |
| 1147 | ptr = nvpair_unpack(isbe, ptr, &left, &nvp); |
| 1148 | if (ptr == NULL) |
| 1149 | goto fail; |
| 1150 | switch (nvpair_type(nvp)) { |
| 1151 | case NV_TYPE_NULL: |
| 1152 | ptr = nvpair_unpack_null(isbe, nvp, ptr, &left); |
| 1153 | break; |
| 1154 | case NV_TYPE_BOOL: |
| 1155 | ptr = nvpair_unpack_bool(isbe, nvp, ptr, &left); |
| 1156 | break; |
| 1157 | case NV_TYPE_NUMBER: |
| 1158 | ptr = nvpair_unpack_number(isbe, nvp, ptr, &left); |
| 1159 | break; |
| 1160 | case NV_TYPE_STRING: |
| 1161 | ptr = nvpair_unpack_string(isbe, nvp, ptr, &left); |
| 1162 | break; |
| 1163 | case NV_TYPE_NVLIST: |
| 1164 | ptr = nvpair_unpack_nvlist(isbe, nvp, ptr, &left, nfds, |
| 1165 | &tmpnvl); |
| 1166 | if (tmpnvl == NULL || ptr == NULL) |
| 1167 | goto fail; |
| 1168 | nvlist_set_parent(tmpnvl, nvp); |
| 1169 | break; |
| 1170 | #ifndef _KERNEL |
| 1171 | case NV_TYPE_DESCRIPTOR: |
| 1172 | ptr = nvpair_unpack_descriptor(isbe, nvp, ptr, &left, |
| 1173 | fds, nfds); |
| 1174 | break; |
| 1175 | case NV_TYPE_DESCRIPTOR_ARRAY: |
no test coverage detected