1247606Spjd/*- 2247606Spjd * Copyright (c) 2012 The FreeBSD Foundation 3247606Spjd * All rights reserved. 4247606Spjd * 5247606Spjd * This software was developed by Pawel Jakub Dawidek under sponsorship from 6247606Spjd * the FreeBSD Foundation. 7247606Spjd * 8247606Spjd * Redistribution and use in source and binary forms, with or without 9247606Spjd * modification, are permitted provided that the following conditions 10247606Spjd * are met: 11247606Spjd * 1. Redistributions of source code must retain the above copyright 12247606Spjd * notice, this list of conditions and the following disclaimer. 13247606Spjd * 2. Redistributions in binary form must reproduce the above copyright 14247606Spjd * notice, this list of conditions and the following disclaimer in the 15247606Spjd * documentation and/or other materials provided with the distribution. 16247606Spjd * 17247606Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18247606Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19247606Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20247606Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21247606Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22247606Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23247606Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24247606Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25247606Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26247606Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27247606Spjd * SUCH DAMAGE. 28247606Spjd */ 29247606Spjd 30247606Spjd#include <sys/cdefs.h> 31247606Spjd__FBSDID("$FreeBSD: releng/11.0/tools/regression/capsicum/syscalls/cap_ioctls_limit.c 263234 2014-03-16 11:04:44Z rwatson $"); 32247606Spjd 33247606Spjd#include <sys/param.h> 34263234Srwatson#include <sys/capsicum.h> 35247606Spjd#include <sys/ioctl.h> 36247606Spjd#include <sys/procdesc.h> 37247606Spjd#include <sys/socket.h> 38247606Spjd#include <sys/wait.h> 39247606Spjd 40247606Spjd#include <err.h> 41247606Spjd#include <errno.h> 42247606Spjd#include <limits.h> 43247606Spjd#include <stdio.h> 44247606Spjd#include <stdlib.h> 45247606Spjd#include <unistd.h> 46247606Spjd 47247606Spjd#include "misc.h" 48247606Spjd 49247606Spjdstatic void 50247606Spjdioctl_tests_0(int fd) 51247606Spjd{ 52247606Spjd unsigned long cmds[2]; 53247606Spjd 54247676Spjd CHECK(cap_ioctls_get(fd, NULL, 0) == CAP_IOCTLS_ALL); 55247606Spjd 56247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 57247606Spjd CHECK(ioctl(fd, FIOCLEX) == 0); 58247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 59247606Spjd CHECK(ioctl(fd, FIONCLEX) == 0); 60247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 61247606Spjd 62247606Spjd cmds[0] = FIOCLEX; 63247606Spjd cmds[1] = FIONCLEX; 64247606Spjd CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == 0); 65247606Spjd cmds[0] = cmds[1] = 0; 66247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == nitems(cmds)); 67247606Spjd CHECK((cmds[0] == FIOCLEX && cmds[1] == FIONCLEX) || 68247606Spjd (cmds[0] == FIONCLEX && cmds[1] == FIOCLEX)); 69247606Spjd cmds[0] = FIOCLEX; 70247606Spjd cmds[1] = FIONCLEX; 71247606Spjd CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == 0); 72247606Spjd cmds[0] = cmds[1] = 0; 73247606Spjd CHECK(cap_ioctls_get(fd, cmds, 1) == nitems(cmds)); 74247606Spjd CHECK(cmds[0] == FIOCLEX || cmds[0] == FIONCLEX); 75247606Spjd CHECK(cmds[1] == 0); 76247606Spjd 77247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 78247606Spjd CHECK(ioctl(fd, FIOCLEX) == 0); 79247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 80247606Spjd CHECK(ioctl(fd, FIONCLEX) == 0); 81247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 82247606Spjd 83247606Spjd cmds[0] = FIOCLEX; 84247606Spjd CHECK(cap_ioctls_limit(fd, cmds, 1) == 0); 85247606Spjd cmds[0] = cmds[1] = 0; 86247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 1); 87247606Spjd CHECK(cmds[0] == FIOCLEX); 88247606Spjd cmds[0] = FIOCLEX; 89247606Spjd cmds[1] = FIONCLEX; 90247606Spjd errno = 0; 91247606Spjd CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == -1); 92247606Spjd CHECK(errno == ENOTCAPABLE); 93247606Spjd cmds[0] = cmds[1] = 0; 94247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 1); 95247606Spjd CHECK(cmds[0] == FIOCLEX); 96247606Spjd 97247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 98247606Spjd CHECK(ioctl(fd, FIOCLEX) == 0); 99247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 100247606Spjd errno = 0; 101247606Spjd CHECK(ioctl(fd, FIONCLEX) == -1); 102247606Spjd CHECK(errno == ENOTCAPABLE); 103247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 104247606Spjd CHECK(fcntl(fd, F_SETFD, 0) == 0); 105247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 106247606Spjd 107247606Spjd CHECK(cap_ioctls_limit(fd, NULL, 0) == 0); 108247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 109247606Spjd cmds[0] = FIOCLEX; 110247606Spjd errno = 0; 111247606Spjd CHECK(cap_ioctls_limit(fd, cmds, 1) == -1); 112247606Spjd CHECK(errno == ENOTCAPABLE); 113247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 114247606Spjd 115247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 116247606Spjd errno = 0; 117247606Spjd CHECK(ioctl(fd, FIOCLEX) == -1); 118247606Spjd CHECK(errno == ENOTCAPABLE); 119247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 120247606Spjd CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 121247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 122247606Spjd errno = 0; 123247606Spjd CHECK(ioctl(fd, FIONCLEX) == -1); 124247606Spjd CHECK(errno == ENOTCAPABLE); 125247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 126247606Spjd CHECK(fcntl(fd, F_SETFD, 0) == 0); 127247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 128247606Spjd} 129247606Spjd 130247606Spjdstatic void 131247606Spjdioctl_tests_1(int fd) 132247606Spjd{ 133247606Spjd unsigned long cmds[2]; 134247606Spjd 135247606Spjd cmds[0] = FIOCLEX; 136247606Spjd CHECK(cap_ioctls_limit(fd, cmds, 1) == 0); 137247606Spjd cmds[0] = cmds[1] = 0; 138247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 1); 139247606Spjd CHECK(cmds[0] == FIOCLEX); 140247606Spjd CHECK(cmds[1] == 0); 141247606Spjd 142247606Spjd CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_IOCTL) == 0); 143247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 144247606Spjd 145247606Spjd cmds[0] = FIOCLEX; 146247606Spjd cmds[1] = FIONCLEX; 147247606Spjd errno = 0; 148247606Spjd CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == -1); 149247606Spjd CHECK(errno == ENOTCAPABLE); 150247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 151247606Spjd cmds[0] = FIOCLEX; 152247606Spjd errno = 0; 153247606Spjd CHECK(cap_ioctls_limit(fd, cmds, 1) == -1); 154247606Spjd CHECK(errno == ENOTCAPABLE); 155247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 156247606Spjd 157247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 158247606Spjd errno = 0; 159247606Spjd CHECK(ioctl(fd, FIOCLEX) == -1); 160247606Spjd CHECK(errno == ENOTCAPABLE); 161247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 162247606Spjd CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 163247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 164247606Spjd errno = 0; 165247606Spjd CHECK(ioctl(fd, FIONCLEX) == -1); 166247606Spjd CHECK(errno == ENOTCAPABLE); 167247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 168247606Spjd CHECK(fcntl(fd, F_SETFD, 0) == 0); 169247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 170247606Spjd} 171247606Spjd 172247606Spjdstatic void 173247606Spjdioctl_tests_2(int fd) 174247606Spjd{ 175247606Spjd unsigned long cmds[2]; 176247606Spjd 177247606Spjd CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_IOCTL) == 0); 178247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 179247606Spjd 180247606Spjd cmds[0] = FIOCLEX; 181247606Spjd cmds[1] = FIONCLEX; 182247606Spjd errno = 0; 183247606Spjd CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == -1); 184247606Spjd CHECK(errno == ENOTCAPABLE); 185247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 186247606Spjd cmds[0] = FIOCLEX; 187247606Spjd errno = 0; 188247606Spjd CHECK(cap_ioctls_limit(fd, cmds, 1) == -1); 189247606Spjd CHECK(errno == ENOTCAPABLE); 190247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 191247606Spjd 192247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 193247606Spjd errno = 0; 194247606Spjd CHECK(ioctl(fd, FIOCLEX) == -1); 195247606Spjd CHECK(errno == ENOTCAPABLE); 196247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 197247606Spjd CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 198247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 199247606Spjd errno = 0; 200247606Spjd CHECK(ioctl(fd, FIONCLEX) == -1); 201247606Spjd CHECK(errno == ENOTCAPABLE); 202247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 203247606Spjd CHECK(fcntl(fd, F_SETFD, 0) == 0); 204247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 205247606Spjd} 206247606Spjd 207247606Spjdstatic void 208247606Spjdioctl_tests_send_0(int sock) 209247606Spjd{ 210247606Spjd unsigned long cmds[2]; 211247606Spjd int fd; 212247606Spjd 213247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 214247606Spjd CHECK(descriptor_send(sock, fd) == 0); 215247606Spjd CHECK(close(fd) == 0); 216247606Spjd 217247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 218247606Spjd cmds[0] = FIOCLEX; 219247606Spjd cmds[1] = FIONCLEX; 220247606Spjd CHECK(cap_ioctls_limit(fd, cmds, nitems(cmds)) == 0); 221247606Spjd CHECK(descriptor_send(sock, fd) == 0); 222247606Spjd CHECK(close(fd) == 0); 223247606Spjd 224247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 225247606Spjd cmds[0] = FIOCLEX; 226247606Spjd CHECK(cap_ioctls_limit(fd, cmds, 1) == 0); 227247606Spjd CHECK(descriptor_send(sock, fd) == 0); 228247606Spjd CHECK(close(fd) == 0); 229247606Spjd 230247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 231247606Spjd CHECK(cap_ioctls_limit(fd, NULL, 0) == 0); 232247606Spjd CHECK(descriptor_send(sock, fd) == 0); 233247606Spjd CHECK(close(fd) == 0); 234247606Spjd} 235247606Spjd 236247606Spjdstatic void 237247606Spjdioctl_tests_recv_0(int sock) 238247606Spjd{ 239247606Spjd unsigned long cmds[2]; 240247606Spjd int fd; 241247606Spjd 242247606Spjd CHECK(descriptor_recv(sock, &fd) == 0); 243247606Spjd 244247676Spjd CHECK(cap_ioctls_get(fd, NULL, 0) == CAP_IOCTLS_ALL); 245247606Spjd 246247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 247247606Spjd CHECK(ioctl(fd, FIOCLEX) == 0); 248247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 249247606Spjd CHECK(ioctl(fd, FIONCLEX) == 0); 250247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 251247606Spjd 252247606Spjd CHECK(close(fd) == 0); 253247606Spjd 254247606Spjd CHECK(descriptor_recv(sock, &fd) == 0); 255247606Spjd 256247606Spjd cmds[0] = cmds[1] = 0; 257247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == nitems(cmds)); 258247606Spjd CHECK((cmds[0] == FIOCLEX && cmds[1] == FIONCLEX) || 259247606Spjd (cmds[0] == FIONCLEX && cmds[1] == FIOCLEX)); 260247606Spjd 261247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 262247606Spjd CHECK(ioctl(fd, FIOCLEX) == 0); 263247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 264247606Spjd CHECK(ioctl(fd, FIONCLEX) == 0); 265247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 266247606Spjd 267247606Spjd CHECK(close(fd) == 0); 268247606Spjd 269247606Spjd CHECK(descriptor_recv(sock, &fd) == 0); 270247606Spjd 271247606Spjd cmds[0] = cmds[1] = 0; 272247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 1); 273247606Spjd CHECK(cmds[0] == FIOCLEX); 274247606Spjd 275247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 276247606Spjd CHECK(ioctl(fd, FIOCLEX) == 0); 277247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 278247606Spjd errno = 0; 279247606Spjd CHECK(ioctl(fd, FIONCLEX) == -1); 280247606Spjd CHECK(errno == ENOTCAPABLE); 281247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 282247606Spjd CHECK(fcntl(fd, F_SETFD, 0) == 0); 283247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 284247606Spjd 285247606Spjd CHECK(close(fd) == 0); 286247606Spjd 287247606Spjd CHECK(descriptor_recv(sock, &fd) == 0); 288247606Spjd 289247606Spjd CHECK(cap_ioctls_get(fd, cmds, nitems(cmds)) == 0); 290247606Spjd 291247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 292247606Spjd errno = 0; 293247606Spjd CHECK(ioctl(fd, FIOCLEX) == -1); 294247606Spjd CHECK(errno == ENOTCAPABLE); 295247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 296247606Spjd CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 297247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 298247606Spjd errno = 0; 299247606Spjd CHECK(ioctl(fd, FIONCLEX) == -1); 300247606Spjd CHECK(errno == ENOTCAPABLE); 301247606Spjd CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 302247606Spjd CHECK(fcntl(fd, F_SETFD, 0) == 0); 303247606Spjd CHECK(fcntl(fd, F_GETFD) == 0); 304247606Spjd 305247606Spjd CHECK(close(fd) == 0); 306247606Spjd} 307247606Spjd 308247606Spjdint 309247606Spjdmain(void) 310247606Spjd{ 311247606Spjd int fd, pfd, sp[2]; 312247606Spjd pid_t pid; 313247606Spjd 314247606Spjd printf("1..607\n"); 315247606Spjd 316247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 317247606Spjd ioctl_tests_0(fd); 318247606Spjd CHECK(close(fd) == 0); 319247606Spjd 320247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 321247606Spjd ioctl_tests_1(fd); 322247606Spjd CHECK(close(fd) == 0); 323247606Spjd 324247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 325247606Spjd ioctl_tests_2(fd); 326247606Spjd CHECK(close(fd) == 0); 327247606Spjd 328247606Spjd /* Child inherits descriptor and operates on it first. */ 329247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 330247606Spjd pid = fork(); 331247606Spjd switch (pid) { 332247606Spjd case -1: 333247606Spjd err(1, "fork() failed"); 334247606Spjd case 0: 335247606Spjd ioctl_tests_0(fd); 336247606Spjd CHECK(close(fd) == 0); 337247606Spjd exit(0); 338247606Spjd default: 339247606Spjd if (waitpid(pid, NULL, 0) == -1) 340247606Spjd err(1, "waitpid() failed"); 341247606Spjd ioctl_tests_0(fd); 342247606Spjd } 343247606Spjd CHECK(close(fd) == 0); 344247606Spjd 345247606Spjd /* Child inherits descriptor, but operates on it after parent. */ 346247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 347247606Spjd pid = fork(); 348247606Spjd switch (pid) { 349247606Spjd case -1: 350247606Spjd err(1, "fork() failed"); 351247606Spjd case 0: 352247606Spjd sleep(1); 353247606Spjd ioctl_tests_0(fd); 354247606Spjd CHECK(close(fd) == 0); 355247606Spjd exit(0); 356247606Spjd default: 357247606Spjd ioctl_tests_0(fd); 358247606Spjd if (waitpid(pid, NULL, 0) == -1) 359247606Spjd err(1, "waitpid() failed"); 360247606Spjd } 361247606Spjd CHECK(close(fd) == 0); 362247606Spjd 363247606Spjd /* Child inherits descriptor and operates on it first. */ 364247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 365247606Spjd pid = pdfork(&pfd, 0); 366247606Spjd switch (pid) { 367247606Spjd case -1: 368247606Spjd err(1, "pdfork() failed"); 369247606Spjd case 0: 370247606Spjd ioctl_tests_1(fd); 371247606Spjd exit(0); 372247606Spjd default: 373247606Spjd if (pdwait(pfd) == -1) 374247606Spjd err(1, "pdwait() failed"); 375247606Spjd close(pfd); 376247606Spjd ioctl_tests_1(fd); 377247606Spjd } 378247606Spjd CHECK(close(fd) == 0); 379247606Spjd 380247606Spjd /* Child inherits descriptor, but operates on it after parent. */ 381247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 382247606Spjd pid = pdfork(&pfd, 0); 383247606Spjd switch (pid) { 384247606Spjd case -1: 385247606Spjd err(1, "pdfork() failed"); 386247606Spjd case 0: 387247606Spjd sleep(1); 388247606Spjd ioctl_tests_1(fd); 389247606Spjd exit(0); 390247606Spjd default: 391247606Spjd ioctl_tests_1(fd); 392247606Spjd if (pdwait(pfd) == -1) 393247606Spjd err(1, "pdwait() failed"); 394247606Spjd close(pfd); 395247606Spjd } 396247606Spjd CHECK(close(fd) == 0); 397247606Spjd 398247606Spjd /* Child inherits descriptor and operates on it first. */ 399247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 400247606Spjd pid = fork(); 401247606Spjd switch (pid) { 402247606Spjd case -1: 403247606Spjd err(1, "fork() failed"); 404247606Spjd case 0: 405247606Spjd ioctl_tests_2(fd); 406247606Spjd exit(0); 407247606Spjd default: 408247606Spjd if (waitpid(pid, NULL, 0) == -1) 409247606Spjd err(1, "waitpid() failed"); 410247606Spjd ioctl_tests_2(fd); 411247606Spjd } 412247606Spjd CHECK(close(fd) == 0); 413247606Spjd 414247606Spjd /* Child inherits descriptor, but operates on it after parent. */ 415247606Spjd CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 416247606Spjd pid = fork(); 417247606Spjd switch (pid) { 418247606Spjd case -1: 419247606Spjd err(1, "fork() failed"); 420247606Spjd case 0: 421247606Spjd sleep(1); 422247606Spjd ioctl_tests_2(fd); 423247606Spjd exit(0); 424247606Spjd default: 425247606Spjd ioctl_tests_2(fd); 426247606Spjd if (waitpid(pid, NULL, 0) == -1) 427247606Spjd err(1, "waitpid() failed"); 428247606Spjd } 429247606Spjd CHECK(close(fd) == 0); 430247606Spjd 431247606Spjd /* Send descriptors from parent to child. */ 432247606Spjd CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0); 433247606Spjd CHECK((pid = fork()) >= 0); 434247606Spjd if (pid == 0) { 435247606Spjd CHECK(close(sp[0]) == 0); 436247606Spjd ioctl_tests_recv_0(sp[1]); 437247606Spjd CHECK(close(sp[1]) == 0); 438247606Spjd exit(0); 439247606Spjd } else { 440247606Spjd CHECK(close(sp[1]) == 0); 441247606Spjd ioctl_tests_send_0(sp[0]); 442247606Spjd CHECK(waitpid(pid, NULL, 0) == pid); 443247606Spjd CHECK(close(sp[0]) == 0); 444247606Spjd } 445247606Spjd 446247606Spjd /* Send descriptors from child to parent. */ 447247606Spjd CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0); 448247606Spjd CHECK((pid = fork()) >= 0); 449247606Spjd if (pid == 0) { 450247606Spjd CHECK(close(sp[0]) == 0); 451247606Spjd ioctl_tests_send_0(sp[1]); 452247606Spjd CHECK(close(sp[1]) == 0); 453247606Spjd exit(0); 454247606Spjd } else { 455247606Spjd CHECK(close(sp[1]) == 0); 456247606Spjd ioctl_tests_recv_0(sp[0]); 457247606Spjd CHECK(waitpid(pid, NULL, 0) == pid); 458247606Spjd CHECK(close(sp[0]) == 0); 459247606Spjd } 460247606Spjd 461247606Spjd exit(0); 462247606Spjd} 463