1258070Spjd/*- 2258070Spjd * Copyright (c) 2013 The FreeBSD Foundation 3258070Spjd * All rights reserved. 4258070Spjd * 5258070Spjd * This software was developed by Pawel Jakub Dawidek under sponsorship from 6258070Spjd * the FreeBSD Foundation. 7258070Spjd * 8258070Spjd * Redistribution and use in source and binary forms, with or without 9258070Spjd * modification, are permitted provided that the following conditions 10258070Spjd * are met: 11258070Spjd * 1. Redistributions of source code must retain the above copyright 12258070Spjd * notice, this list of conditions and the following disclaimer. 13258070Spjd * 2. Redistributions in binary form must reproduce the above copyright 14258070Spjd * notice, this list of conditions and the following disclaimer in the 15258070Spjd * documentation and/or other materials provided with the distribution. 16258070Spjd * 17258070Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18258070Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19258070Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20258070Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21258070Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22258070Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23258070Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24258070Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25258070Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26258070Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27258070Spjd * SUCH DAMAGE. 28258070Spjd * 29258070Spjd * $FreeBSD: releng/10.3/lib/libnv/tests/nvlist_send_recv_test.c 292634 2015-12-22 23:08:50Z ngie $ 30258070Spjd */ 31258070Spjd 32258070Spjd#include <sys/types.h> 33258070Spjd#include <sys/socket.h> 34258070Spjd#include <sys/wait.h> 35258070Spjd 36258070Spjd#include <err.h> 37258070Spjd#include <errno.h> 38258070Spjd#include <fcntl.h> 39258070Spjd#include <stdio.h> 40258070Spjd#include <string.h> 41258070Spjd#include <unistd.h> 42258070Spjd 43258070Spjd#include <nv.h> 44258070Spjd 45258070Spjdstatic int ntest = 1; 46258070Spjd 47258070Spjd#define CHECK(expr) do { \ 48258070Spjd if ((expr)) \ 49258070Spjd printf("ok # %d %s:%u\n", ntest, __FILE__, __LINE__); \ 50258070Spjd else \ 51258070Spjd printf("not ok # %d %s:%u\n", ntest, __FILE__, __LINE__);\ 52258070Spjd ntest++; \ 53258070Spjd} while (0) 54258070Spjd 55258070Spjd#define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF) 56258070Spjd 57258070Spjdstatic void 58258070Spjdchild(int sock) 59258070Spjd{ 60258070Spjd nvlist_t *nvl; 61292634Sngie nvlist_t *empty; 62258070Spjd 63258070Spjd nvl = nvlist_create(0); 64292634Sngie empty = nvlist_create(0); 65258070Spjd 66258070Spjd nvlist_add_bool(nvl, "nvlist/bool/true", true); 67258070Spjd nvlist_add_bool(nvl, "nvlist/bool/false", false); 68258070Spjd nvlist_add_number(nvl, "nvlist/number/0", 0); 69258070Spjd nvlist_add_number(nvl, "nvlist/number/1", 1); 70258070Spjd nvlist_add_number(nvl, "nvlist/number/-1", -1); 71258070Spjd nvlist_add_number(nvl, "nvlist/number/UINT64_MAX", UINT64_MAX); 72258070Spjd nvlist_add_number(nvl, "nvlist/number/INT64_MIN", INT64_MIN); 73258070Spjd nvlist_add_number(nvl, "nvlist/number/INT64_MAX", INT64_MAX); 74258070Spjd nvlist_add_string(nvl, "nvlist/string/", ""); 75258070Spjd nvlist_add_string(nvl, "nvlist/string/x", "x"); 76258070Spjd nvlist_add_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"); 77258070Spjd nvlist_add_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO", STDERR_FILENO); 78258070Spjd nvlist_add_binary(nvl, "nvlist/binary/x", "x", 1); 79258070Spjd nvlist_add_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")); 80292634Sngie nvlist_move_nvlist(nvl, "nvlist/nvlist/empty", empty); 81258070Spjd nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl); 82258070Spjd 83258070Spjd nvlist_send(sock, nvl); 84258070Spjd 85258070Spjd nvlist_destroy(nvl); 86258070Spjd} 87258070Spjd 88258070Spjdstatic void 89258070Spjdparent(int sock) 90258070Spjd{ 91258070Spjd nvlist_t *nvl; 92292634Sngie const nvlist_t *cnvl, *empty; 93258070Spjd const char *name, *cname; 94258070Spjd void *cookie, *ccookie; 95258070Spjd int type, ctype; 96258070Spjd size_t size; 97258070Spjd 98258070Spjd nvl = nvlist_recv(sock); 99258070Spjd CHECK(nvlist_error(nvl) == 0); 100258070Spjd if (nvlist_error(nvl) != 0) 101258070Spjd err(1, "nvlist_recv() failed"); 102258070Spjd 103258070Spjd cookie = NULL; 104258070Spjd 105258070Spjd name = nvlist_next(nvl, &type, &cookie); 106258070Spjd CHECK(name != NULL); 107258070Spjd CHECK(type == NV_TYPE_BOOL); 108258070Spjd CHECK(strcmp(name, "nvlist/bool/true") == 0); 109258070Spjd CHECK(nvlist_get_bool(nvl, name) == true); 110258070Spjd 111258070Spjd name = nvlist_next(nvl, &type, &cookie); 112258070Spjd CHECK(name != NULL); 113258070Spjd CHECK(type == NV_TYPE_BOOL); 114258070Spjd CHECK(strcmp(name, "nvlist/bool/false") == 0); 115258070Spjd CHECK(nvlist_get_bool(nvl, name) == false); 116258070Spjd 117258070Spjd name = nvlist_next(nvl, &type, &cookie); 118258070Spjd CHECK(name != NULL); 119258070Spjd CHECK(type == NV_TYPE_NUMBER); 120258070Spjd CHECK(strcmp(name, "nvlist/number/0") == 0); 121258070Spjd CHECK(nvlist_get_number(nvl, name) == 0); 122258070Spjd 123258070Spjd name = nvlist_next(nvl, &type, &cookie); 124258070Spjd CHECK(name != NULL); 125258070Spjd CHECK(type == NV_TYPE_NUMBER); 126258070Spjd CHECK(strcmp(name, "nvlist/number/1") == 0); 127258070Spjd CHECK(nvlist_get_number(nvl, name) == 1); 128258070Spjd 129258070Spjd name = nvlist_next(nvl, &type, &cookie); 130258070Spjd CHECK(name != NULL); 131258070Spjd CHECK(type == NV_TYPE_NUMBER); 132258070Spjd CHECK(strcmp(name, "nvlist/number/-1") == 0); 133258070Spjd CHECK((int)nvlist_get_number(nvl, name) == -1); 134258070Spjd 135258070Spjd name = nvlist_next(nvl, &type, &cookie); 136258070Spjd CHECK(name != NULL); 137258070Spjd CHECK(type == NV_TYPE_NUMBER); 138258070Spjd CHECK(strcmp(name, "nvlist/number/UINT64_MAX") == 0); 139258070Spjd CHECK(nvlist_get_number(nvl, name) == UINT64_MAX); 140258070Spjd 141258070Spjd name = nvlist_next(nvl, &type, &cookie); 142258070Spjd CHECK(name != NULL); 143258070Spjd CHECK(type == NV_TYPE_NUMBER); 144258070Spjd CHECK(strcmp(name, "nvlist/number/INT64_MIN") == 0); 145258070Spjd CHECK((int64_t)nvlist_get_number(nvl, name) == INT64_MIN); 146258070Spjd 147258070Spjd name = nvlist_next(nvl, &type, &cookie); 148258070Spjd CHECK(name != NULL); 149258070Spjd CHECK(type == NV_TYPE_NUMBER); 150258070Spjd CHECK(strcmp(name, "nvlist/number/INT64_MAX") == 0); 151258070Spjd CHECK((int64_t)nvlist_get_number(nvl, name) == INT64_MAX); 152258070Spjd 153258070Spjd name = nvlist_next(nvl, &type, &cookie); 154258070Spjd CHECK(name != NULL); 155258070Spjd CHECK(type == NV_TYPE_STRING); 156258070Spjd CHECK(strcmp(name, "nvlist/string/") == 0); 157258070Spjd CHECK(strcmp(nvlist_get_string(nvl, name), "") == 0); 158258070Spjd 159258070Spjd name = nvlist_next(nvl, &type, &cookie); 160258070Spjd CHECK(name != NULL); 161258070Spjd CHECK(type == NV_TYPE_STRING); 162258070Spjd CHECK(strcmp(name, "nvlist/string/x") == 0); 163258070Spjd CHECK(strcmp(nvlist_get_string(nvl, name), "x") == 0); 164258070Spjd 165258070Spjd name = nvlist_next(nvl, &type, &cookie); 166258070Spjd CHECK(name != NULL); 167258070Spjd CHECK(type == NV_TYPE_STRING); 168258070Spjd CHECK(strcmp(name, "nvlist/string/abcdefghijklmnopqrstuvwxyz") == 0); 169258070Spjd CHECK(strcmp(nvlist_get_string(nvl, name), "abcdefghijklmnopqrstuvwxyz") == 0); 170258070Spjd 171258070Spjd name = nvlist_next(nvl, &type, &cookie); 172258070Spjd CHECK(name != NULL); 173258070Spjd CHECK(type == NV_TYPE_DESCRIPTOR); 174258070Spjd CHECK(strcmp(name, "nvlist/descriptor/STDERR_FILENO") == 0); 175258070Spjd CHECK(fd_is_valid(nvlist_get_descriptor(nvl, name))); 176258070Spjd 177258070Spjd name = nvlist_next(nvl, &type, &cookie); 178258070Spjd CHECK(name != NULL); 179258070Spjd CHECK(type == NV_TYPE_BINARY); 180258070Spjd CHECK(strcmp(name, "nvlist/binary/x") == 0); 181258070Spjd CHECK(memcmp(nvlist_get_binary(nvl, name, NULL), "x", 1) == 0); 182258070Spjd CHECK(memcmp(nvlist_get_binary(nvl, name, &size), "x", 1) == 0); 183258070Spjd CHECK(size == 1); 184258070Spjd 185258070Spjd name = nvlist_next(nvl, &type, &cookie); 186258070Spjd CHECK(name != NULL); 187258070Spjd CHECK(type == NV_TYPE_BINARY); 188258070Spjd CHECK(strcmp(name, "nvlist/binary/abcdefghijklmnopqrstuvwxyz") == 0); 189258070Spjd CHECK(memcmp(nvlist_get_binary(nvl, name, NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); 190258070Spjd CHECK(memcmp(nvlist_get_binary(nvl, name, &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); 191258070Spjd CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz")); 192258070Spjd 193258070Spjd name = nvlist_next(nvl, &type, &cookie); 194258070Spjd CHECK(name != NULL); 195258070Spjd CHECK(type == NV_TYPE_NVLIST); 196292634Sngie CHECK(strcmp(name, "nvlist/nvlist/empty") == 0); 197292634Sngie cnvl = nvlist_get_nvlist(nvl, name); 198292634Sngie CHECK(nvlist_empty(cnvl)); 199292634Sngie 200292634Sngie name = nvlist_next(nvl, &type, &cookie); 201292634Sngie CHECK(name != NULL); 202292634Sngie CHECK(type == NV_TYPE_NVLIST); 203258070Spjd CHECK(strcmp(name, "nvlist/nvlist") == 0); 204258070Spjd cnvl = nvlist_get_nvlist(nvl, name); 205258070Spjd 206258070Spjd ccookie = NULL; 207258070Spjd 208258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 209258070Spjd CHECK(cname != NULL); 210258070Spjd CHECK(ctype == NV_TYPE_BOOL); 211258070Spjd CHECK(strcmp(cname, "nvlist/bool/true") == 0); 212258070Spjd CHECK(nvlist_get_bool(cnvl, cname) == true); 213258070Spjd 214258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 215258070Spjd CHECK(cname != NULL); 216258070Spjd CHECK(ctype == NV_TYPE_BOOL); 217258070Spjd CHECK(strcmp(cname, "nvlist/bool/false") == 0); 218258070Spjd CHECK(nvlist_get_bool(cnvl, cname) == false); 219258070Spjd 220258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 221258070Spjd CHECK(cname != NULL); 222258070Spjd CHECK(ctype == NV_TYPE_NUMBER); 223258070Spjd CHECK(strcmp(cname, "nvlist/number/0") == 0); 224258070Spjd CHECK(nvlist_get_number(cnvl, cname) == 0); 225258070Spjd 226258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 227258070Spjd CHECK(cname != NULL); 228258070Spjd CHECK(ctype == NV_TYPE_NUMBER); 229258070Spjd CHECK(strcmp(cname, "nvlist/number/1") == 0); 230258070Spjd CHECK(nvlist_get_number(cnvl, cname) == 1); 231258070Spjd 232258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 233258070Spjd CHECK(cname != NULL); 234258070Spjd CHECK(ctype == NV_TYPE_NUMBER); 235258070Spjd CHECK(strcmp(cname, "nvlist/number/-1") == 0); 236258070Spjd CHECK((int)nvlist_get_number(cnvl, cname) == -1); 237258070Spjd 238258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 239258070Spjd CHECK(cname != NULL); 240258070Spjd CHECK(ctype == NV_TYPE_NUMBER); 241258070Spjd CHECK(strcmp(cname, "nvlist/number/UINT64_MAX") == 0); 242258070Spjd CHECK(nvlist_get_number(cnvl, cname) == UINT64_MAX); 243258070Spjd 244258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 245258070Spjd CHECK(cname != NULL); 246258070Spjd CHECK(ctype == NV_TYPE_NUMBER); 247258070Spjd CHECK(strcmp(cname, "nvlist/number/INT64_MIN") == 0); 248258070Spjd CHECK((int64_t)nvlist_get_number(cnvl, cname) == INT64_MIN); 249258070Spjd 250258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 251258070Spjd CHECK(cname != NULL); 252258070Spjd CHECK(ctype == NV_TYPE_NUMBER); 253258070Spjd CHECK(strcmp(cname, "nvlist/number/INT64_MAX") == 0); 254258070Spjd CHECK((int64_t)nvlist_get_number(cnvl, cname) == INT64_MAX); 255258070Spjd 256258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 257258070Spjd CHECK(cname != NULL); 258258070Spjd CHECK(ctype == NV_TYPE_STRING); 259258070Spjd CHECK(strcmp(cname, "nvlist/string/") == 0); 260258070Spjd CHECK(strcmp(nvlist_get_string(cnvl, cname), "") == 0); 261258070Spjd 262258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 263258070Spjd CHECK(cname != NULL); 264258070Spjd CHECK(ctype == NV_TYPE_STRING); 265258070Spjd CHECK(strcmp(cname, "nvlist/string/x") == 0); 266258070Spjd CHECK(strcmp(nvlist_get_string(cnvl, cname), "x") == 0); 267258070Spjd 268258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 269258070Spjd CHECK(cname != NULL); 270258070Spjd CHECK(ctype == NV_TYPE_STRING); 271258070Spjd CHECK(strcmp(cname, "nvlist/string/abcdefghijklmnopqrstuvwxyz") == 0); 272258070Spjd CHECK(strcmp(nvlist_get_string(cnvl, cname), "abcdefghijklmnopqrstuvwxyz") == 0); 273258070Spjd 274258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 275258070Spjd CHECK(cname != NULL); 276258070Spjd CHECK(ctype == NV_TYPE_DESCRIPTOR); 277258070Spjd CHECK(strcmp(cname, "nvlist/descriptor/STDERR_FILENO") == 0); 278258070Spjd CHECK(fd_is_valid(nvlist_get_descriptor(cnvl, cname))); 279258070Spjd 280258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 281258070Spjd CHECK(cname != NULL); 282258070Spjd CHECK(ctype == NV_TYPE_BINARY); 283258070Spjd CHECK(strcmp(cname, "nvlist/binary/x") == 0); 284258070Spjd CHECK(memcmp(nvlist_get_binary(cnvl, cname, NULL), "x", 1) == 0); 285258070Spjd CHECK(memcmp(nvlist_get_binary(cnvl, cname, &size), "x", 1) == 0); 286258070Spjd CHECK(size == 1); 287258070Spjd 288258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 289258070Spjd CHECK(cname != NULL); 290258070Spjd CHECK(ctype == NV_TYPE_BINARY); 291258070Spjd CHECK(strcmp(cname, "nvlist/binary/abcdefghijklmnopqrstuvwxyz") == 0); 292258070Spjd CHECK(memcmp(nvlist_get_binary(cnvl, cname, NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); 293258070Spjd CHECK(memcmp(nvlist_get_binary(cnvl, cname, &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); 294258070Spjd CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz")); 295258070Spjd 296258070Spjd cname = nvlist_next(cnvl, &ctype, &ccookie); 297292634Sngie CHECK(cname != NULL); 298292634Sngie CHECK(ctype == NV_TYPE_NVLIST); 299292634Sngie CHECK(strcmp(cname, "nvlist/nvlist/empty") == 0); 300292634Sngie empty = nvlist_get_nvlist(cnvl, cname); 301292634Sngie CHECK(nvlist_empty(empty)); 302292634Sngie 303292634Sngie cname = nvlist_next(cnvl, &ctype, &ccookie); 304258070Spjd CHECK(cname == NULL); 305258070Spjd 306258070Spjd name = nvlist_next(nvl, &type, &cookie); 307258070Spjd CHECK(name == NULL); 308258070Spjd} 309258070Spjd 310258070Spjdint 311258070Spjdmain(void) 312258070Spjd{ 313258070Spjd int status, socks[2]; 314258070Spjd pid_t pid; 315258070Spjd 316292634Sngie printf("1..134\n"); 317258070Spjd fflush(stdout); 318258070Spjd 319258070Spjd if (socketpair(PF_UNIX, SOCK_STREAM, 0, socks) < 0) 320258070Spjd err(1, "socketpair() failed"); 321258070Spjd pid = fork(); 322258070Spjd switch (pid) { 323258070Spjd case -1: 324258070Spjd /* Failure. */ 325258070Spjd err(1, "unable to fork"); 326258070Spjd case 0: 327258070Spjd /* Child. */ 328258070Spjd close(socks[0]); 329258070Spjd child(socks[1]); 330258070Spjd return (0); 331258070Spjd default: 332258070Spjd /* Parent. */ 333258070Spjd close(socks[1]); 334258070Spjd parent(socks[0]); 335258070Spjd break; 336258070Spjd } 337258070Spjd 338258070Spjd if (waitpid(pid, &status, 0) < 0) 339258070Spjd err(1, "waitpid() failed"); 340258070Spjd 341258070Spjd return (0); 342258070Spjd} 343