| 1295 | } |
| 1296 | |
| 1297 | nvlist_t * |
| 1298 | nvlist_recv(int sock, int flags) |
| 1299 | { |
| 1300 | struct nvlist_header nvlhdr; |
| 1301 | nvlist_t *nvl, *ret; |
| 1302 | unsigned char *buf; |
| 1303 | size_t nfds, size, i; |
| 1304 | int *fds; |
| 1305 | |
| 1306 | if (buf_recv(sock, &nvlhdr, sizeof(nvlhdr)) == -1) |
| 1307 | return (NULL); |
| 1308 | |
| 1309 | if (!nvlist_check_header(&nvlhdr)) |
| 1310 | return (NULL); |
| 1311 | |
| 1312 | nfds = (size_t)nvlhdr.nvlh_descriptors; |
| 1313 | size = sizeof(nvlhdr) + (size_t)nvlhdr.nvlh_size; |
| 1314 | |
| 1315 | buf = nv_malloc(size); |
| 1316 | if (buf == NULL) |
| 1317 | return (NULL); |
| 1318 | |
| 1319 | memcpy(buf, &nvlhdr, sizeof(nvlhdr)); |
| 1320 | |
| 1321 | ret = NULL; |
| 1322 | fds = NULL; |
| 1323 | |
| 1324 | if (buf_recv(sock, buf + sizeof(nvlhdr), size - sizeof(nvlhdr)) == -1) |
| 1325 | goto out; |
| 1326 | |
| 1327 | if (nfds > 0) { |
| 1328 | fds = nv_malloc(nfds * sizeof(fds[0])); |
| 1329 | if (fds == NULL) |
| 1330 | goto out; |
| 1331 | if (fd_recv(sock, fds, nfds) == -1) |
| 1332 | goto out; |
| 1333 | } |
| 1334 | |
| 1335 | nvl = nvlist_xunpack(buf, size, fds, nfds, flags); |
| 1336 | if (nvl == NULL) { |
| 1337 | ERRNO_SAVE(); |
| 1338 | for (i = 0; i < nfds; i++) |
| 1339 | close(fds[i]); |
| 1340 | ERRNO_RESTORE(); |
| 1341 | goto out; |
| 1342 | } |
| 1343 | |
| 1344 | ret = nvl; |
| 1345 | out: |
| 1346 | ERRNO_SAVE(); |
| 1347 | nv_free(buf); |
| 1348 | nv_free(fds); |
| 1349 | ERRNO_RESTORE(); |
| 1350 | |
| 1351 | return (ret); |
| 1352 | } |
| 1353 | |
| 1354 | nvlist_t * |
no test coverage detected