1 /*- 2 * Copyright (c) 2012 The FreeBSD Foundation 3 * 4 * This software was developed by Pawel Jakub Dawidek under sponsorship from 5 * the FreeBSD Foundation. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/types.h> 30 #include <sys/capsicum.h> 31 #include <sys/procdesc.h> 32 #include <sys/socket.h> 33 #include <sys/wait.h> 34 35 #include <err.h> 36 #include <errno.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <unistd.h> 40 41 #include "misc.h" 42 43 static void 44 fcntl_tests_0(int fd) 45 { 46 uint32_t fcntlrights; 47 48 fcntlrights = 0; 49 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 50 CHECK(fcntlrights == CAP_FCNTL_ALL); 51 52 CHECK(fcntl(fd, F_GETFD) == 0); 53 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 54 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 55 CHECK(fcntl(fd, F_SETFD, 0) == 0); 56 CHECK(fcntl(fd, F_GETFD) == 0); 57 58 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 59 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0); 60 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK)); 61 CHECK(fcntl(fd, F_SETFL, 0) == 0); 62 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 63 64 errno = 0; 65 CHECK(cap_fcntls_limit(fd, ~CAP_FCNTL_ALL) == -1); 66 CHECK(errno == EINVAL); 67 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0); 68 fcntlrights = 0; 69 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 70 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL)); 71 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0); 72 fcntlrights = 0; 73 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 74 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL)); 75 76 CHECK(fcntl(fd, F_GETFD) == 0); 77 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 78 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 79 CHECK(fcntl(fd, F_SETFD, 0) == 0); 80 CHECK(fcntl(fd, F_GETFD) == 0); 81 82 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 83 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0); 84 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK)); 85 CHECK(fcntl(fd, F_SETFL, 0) == 0); 86 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 87 88 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0); 89 fcntlrights = 0; 90 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 91 CHECK(fcntlrights == CAP_FCNTL_GETFL); 92 errno = 0; 93 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1); 94 CHECK(errno == ENOTCAPABLE); 95 fcntlrights = 0; 96 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 97 CHECK(fcntlrights == CAP_FCNTL_GETFL); 98 99 CHECK(fcntl(fd, F_GETFD) == 0); 100 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 101 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 102 CHECK(fcntl(fd, F_SETFD, 0) == 0); 103 CHECK(fcntl(fd, F_GETFD) == 0); 104 105 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 106 errno = 0; 107 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1); 108 CHECK(errno == ENOTCAPABLE); 109 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 110 errno = 0; 111 CHECK(fcntl(fd, F_SETFL, 0) == -1); 112 CHECK(errno == ENOTCAPABLE); 113 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 114 115 CHECK(cap_fcntls_limit(fd, 0) == 0); 116 fcntlrights = CAP_FCNTL_ALL; 117 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 118 CHECK(fcntlrights == 0); 119 errno = 0; 120 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1); 121 CHECK(errno == ENOTCAPABLE); 122 fcntlrights = CAP_FCNTL_ALL; 123 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 124 CHECK(fcntlrights == 0); 125 errno = 0; 126 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1); 127 CHECK(errno == ENOTCAPABLE); 128 fcntlrights = CAP_FCNTL_ALL; 129 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 130 CHECK(fcntlrights == 0); 131 132 CHECK(fcntl(fd, F_GETFD) == 0); 133 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 134 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 135 CHECK(fcntl(fd, F_SETFD, 0) == 0); 136 CHECK(fcntl(fd, F_GETFD) == 0); 137 138 errno = 0; 139 CHECK(fcntl(fd, F_GETFL) == -1); 140 CHECK(errno == ENOTCAPABLE); 141 errno = 0; 142 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1); 143 CHECK(errno == ENOTCAPABLE); 144 errno = 0; 145 CHECK(fcntl(fd, F_SETFL, 0) == -1); 146 CHECK(errno == ENOTCAPABLE); 147 errno = 0; 148 CHECK(fcntl(fd, F_GETFL) == -1); 149 CHECK(errno == ENOTCAPABLE); 150 } 151 152 static void 153 fcntl_tests_1(int fd) 154 { 155 uint32_t fcntlrights; 156 cap_rights_t rights; 157 158 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0); 159 fcntlrights = 0; 160 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 161 CHECK(fcntlrights == CAP_FCNTL_GETFL); 162 163 CAP_ALL(&rights); 164 cap_rights_clear(&rights, CAP_FCNTL); 165 CHECK(cap_rights_limit(fd, &rights) == 0); 166 167 fcntlrights = CAP_FCNTL_ALL; 168 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 169 CHECK(fcntlrights == 0); 170 171 errno = 0; 172 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1); 173 CHECK(errno == ENOTCAPABLE); 174 fcntlrights = CAP_FCNTL_ALL; 175 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 176 CHECK(fcntlrights == 0); 177 errno = 0; 178 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1); 179 CHECK(errno == ENOTCAPABLE); 180 fcntlrights = CAP_FCNTL_ALL; 181 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 182 CHECK(fcntlrights == 0); 183 184 CHECK(fcntl(fd, F_GETFD) == 0); 185 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 186 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 187 CHECK(fcntl(fd, F_SETFD, 0) == 0); 188 CHECK(fcntl(fd, F_GETFD) == 0); 189 190 errno = 0; 191 CHECK(fcntl(fd, F_GETFL) == -1); 192 CHECK(errno == ENOTCAPABLE); 193 errno = 0; 194 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1); 195 CHECK(errno == ENOTCAPABLE); 196 errno = 0; 197 CHECK(fcntl(fd, F_SETFL, 0) == -1); 198 CHECK(errno == ENOTCAPABLE); 199 errno = 0; 200 CHECK(fcntl(fd, F_GETFL) == -1); 201 CHECK(errno == ENOTCAPABLE); 202 } 203 204 static void 205 fcntl_tests_2(int fd) 206 { 207 uint32_t fcntlrights; 208 cap_rights_t rights; 209 210 CAP_ALL(&rights); 211 cap_rights_clear(&rights, CAP_FCNTL); 212 CHECK(cap_rights_limit(fd, &rights) == 0); 213 214 fcntlrights = CAP_FCNTL_ALL; 215 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 216 CHECK(fcntlrights == 0); 217 218 errno = 0; 219 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1); 220 CHECK(errno == ENOTCAPABLE); 221 fcntlrights = CAP_FCNTL_ALL; 222 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 223 CHECK(fcntlrights == 0); 224 errno = 0; 225 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1); 226 CHECK(errno == ENOTCAPABLE); 227 fcntlrights = CAP_FCNTL_ALL; 228 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 229 CHECK(fcntlrights == 0); 230 231 CHECK(fcntl(fd, F_GETFD) == 0); 232 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 233 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 234 CHECK(fcntl(fd, F_SETFD, 0) == 0); 235 CHECK(fcntl(fd, F_GETFD) == 0); 236 237 errno = 0; 238 CHECK(fcntl(fd, F_GETFL) == -1); 239 CHECK(errno == ENOTCAPABLE); 240 errno = 0; 241 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1); 242 CHECK(errno == ENOTCAPABLE); 243 errno = 0; 244 CHECK(fcntl(fd, F_SETFL, 0) == -1); 245 CHECK(errno == ENOTCAPABLE); 246 errno = 0; 247 CHECK(fcntl(fd, F_GETFL) == -1); 248 CHECK(errno == ENOTCAPABLE); 249 } 250 251 static void 252 fcntl_tests_send_0(int sock) 253 { 254 int fd; 255 256 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 257 CHECK(descriptor_send(sock, fd) == 0); 258 CHECK(close(fd) == 0); 259 260 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 261 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0); 262 CHECK(descriptor_send(sock, fd) == 0); 263 CHECK(close(fd) == 0); 264 265 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 266 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0); 267 CHECK(descriptor_send(sock, fd) == 0); 268 CHECK(close(fd) == 0); 269 270 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 271 CHECK(cap_fcntls_limit(fd, 0) == 0); 272 CHECK(descriptor_send(sock, fd) == 0); 273 CHECK(close(fd) == 0); 274 } 275 276 static void 277 fcntl_tests_recv_0(int sock) 278 { 279 uint32_t fcntlrights; 280 int fd; 281 282 CHECK(descriptor_recv(sock, &fd) == 0); 283 284 fcntlrights = 0; 285 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 286 CHECK(fcntlrights == CAP_FCNTL_ALL); 287 288 CHECK(fcntl(fd, F_GETFD) == 0); 289 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 290 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 291 CHECK(fcntl(fd, F_SETFD, 0) == 0); 292 CHECK(fcntl(fd, F_GETFD) == 0); 293 294 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 295 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0); 296 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK)); 297 CHECK(fcntl(fd, F_SETFL, 0) == 0); 298 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 299 300 CHECK(close(fd) == 0); 301 302 CHECK(descriptor_recv(sock, &fd) == 0); 303 304 fcntlrights = 0; 305 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 306 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL)); 307 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0); 308 fcntlrights = 0; 309 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 310 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL)); 311 312 CHECK(fcntl(fd, F_GETFD) == 0); 313 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 314 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 315 CHECK(fcntl(fd, F_SETFD, 0) == 0); 316 CHECK(fcntl(fd, F_GETFD) == 0); 317 318 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 319 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0); 320 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK)); 321 CHECK(fcntl(fd, F_SETFL, 0) == 0); 322 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 323 324 CHECK(close(fd) == 0); 325 326 CHECK(descriptor_recv(sock, &fd) == 0); 327 328 fcntlrights = 0; 329 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 330 CHECK(fcntlrights == CAP_FCNTL_GETFL); 331 errno = 0; 332 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1); 333 CHECK(errno == ENOTCAPABLE); 334 fcntlrights = 0; 335 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 336 CHECK(fcntlrights == CAP_FCNTL_GETFL); 337 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0); 338 fcntlrights = 0; 339 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 340 CHECK(fcntlrights == CAP_FCNTL_GETFL); 341 342 CHECK(fcntl(fd, F_GETFD) == 0); 343 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 344 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 345 CHECK(fcntl(fd, F_SETFD, 0) == 0); 346 CHECK(fcntl(fd, F_GETFD) == 0); 347 348 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 349 errno = 0; 350 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1); 351 CHECK(errno == ENOTCAPABLE); 352 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 353 errno = 0; 354 CHECK(fcntl(fd, F_SETFL, 0) == -1); 355 CHECK(errno == ENOTCAPABLE); 356 CHECK(fcntl(fd, F_GETFL) == O_RDWR); 357 358 CHECK(close(fd) == 0); 359 360 CHECK(descriptor_recv(sock, &fd) == 0); 361 362 fcntlrights = 0; 363 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 364 CHECK(fcntlrights == 0); 365 errno = 0; 366 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1); 367 CHECK(errno == ENOTCAPABLE); 368 fcntlrights = 0; 369 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 370 CHECK(fcntlrights == 0); 371 errno = 0; 372 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1); 373 CHECK(errno == ENOTCAPABLE); 374 fcntlrights = 0; 375 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 376 CHECK(fcntlrights == 0); 377 errno = 0; 378 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_SETFL) == -1); 379 CHECK(errno == ENOTCAPABLE); 380 fcntlrights = 0; 381 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0); 382 CHECK(fcntlrights == 0); 383 384 CHECK(fcntl(fd, F_GETFD) == 0); 385 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0); 386 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC); 387 CHECK(fcntl(fd, F_SETFD, 0) == 0); 388 CHECK(fcntl(fd, F_GETFD) == 0); 389 390 errno = 0; 391 CHECK(fcntl(fd, F_GETFL) == -1); 392 CHECK(errno == ENOTCAPABLE); 393 errno = 0; 394 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1); 395 CHECK(errno == ENOTCAPABLE); 396 errno = 0; 397 CHECK(fcntl(fd, F_SETFL, 0) == -1); 398 CHECK(errno == ENOTCAPABLE); 399 errno = 0; 400 CHECK(fcntl(fd, F_GETFL) == -1); 401 CHECK(errno == ENOTCAPABLE); 402 403 CHECK(close(fd) == 0); 404 } 405 406 int 407 main(void) 408 { 409 int fd, pfd, sp[2]; 410 pid_t pid; 411 412 printf("1..870\n"); 413 414 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 415 fcntl_tests_0(fd); 416 CHECK(close(fd) == 0); 417 418 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 419 fcntl_tests_1(fd); 420 CHECK(close(fd) == 0); 421 422 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 423 fcntl_tests_2(fd); 424 CHECK(close(fd) == 0); 425 426 /* Child inherits descriptor and operates on it first. */ 427 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 428 CHECK((pid = fork()) >= 0); 429 if (pid == 0) { 430 fcntl_tests_0(fd); 431 CHECK(close(fd) == 0); 432 exit(0); 433 } else { 434 CHECK(waitpid(pid, NULL, 0) == pid); 435 fcntl_tests_0(fd); 436 } 437 CHECK(close(fd) == 0); 438 439 /* Child inherits descriptor, but operates on it after parent. */ 440 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 441 CHECK((pid = fork()) >= 0); 442 if (pid == 0) { 443 sleep(1); 444 fcntl_tests_0(fd); 445 CHECK(close(fd) == 0); 446 exit(0); 447 } else { 448 fcntl_tests_0(fd); 449 CHECK(waitpid(pid, NULL, 0) == pid); 450 } 451 CHECK(close(fd) == 0); 452 453 /* Child inherits descriptor and operates on it first. */ 454 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 455 CHECK((pid = pdfork(&pfd, 0)) >= 0); 456 if (pid == 0) { 457 fcntl_tests_1(fd); 458 exit(0); 459 } else { 460 CHECK(pdwait(pfd) == 0); 461 /* 462 It fails with EBADF, which I believe is a bug. 463 CHECK(close(pfd) == 0); 464 */ 465 fcntl_tests_1(fd); 466 } 467 CHECK(close(fd) == 0); 468 469 /* Child inherits descriptor, but operates on it after parent. */ 470 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 471 CHECK((pid = pdfork(&pfd, 0)) >= 0); 472 if (pid == 0) { 473 sleep(1); 474 fcntl_tests_1(fd); 475 exit(0); 476 } else { 477 fcntl_tests_1(fd); 478 CHECK(pdwait(pfd) == 0); 479 /* 480 It fails with EBADF, which I believe is a bug. 481 CHECK(close(pfd) == 0); 482 */ 483 } 484 CHECK(close(fd) == 0); 485 486 /* Child inherits descriptor and operates on it first. */ 487 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 488 CHECK((pid = fork()) >= 0); 489 if (pid == 0) { 490 fcntl_tests_2(fd); 491 exit(0); 492 } else { 493 CHECK(waitpid(pid, NULL, 0) == pid); 494 fcntl_tests_2(fd); 495 } 496 CHECK(close(fd) == 0); 497 498 /* Child inherits descriptor, but operates on it after parent. */ 499 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0); 500 CHECK((pid = fork()) >= 0); 501 if (pid == 0) { 502 sleep(1); 503 fcntl_tests_2(fd); 504 exit(0); 505 } else { 506 fcntl_tests_2(fd); 507 CHECK(waitpid(pid, NULL, 0) == pid); 508 } 509 CHECK(close(fd) == 0); 510 511 /* Send descriptors from parent to child. */ 512 CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0); 513 CHECK((pid = fork()) >= 0); 514 if (pid == 0) { 515 CHECK(close(sp[0]) == 0); 516 fcntl_tests_recv_0(sp[1]); 517 CHECK(close(sp[1]) == 0); 518 exit(0); 519 } else { 520 CHECK(close(sp[1]) == 0); 521 fcntl_tests_send_0(sp[0]); 522 CHECK(waitpid(pid, NULL, 0) == pid); 523 CHECK(close(sp[0]) == 0); 524 } 525 526 /* Send descriptors from child to parent. */ 527 CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0); 528 CHECK((pid = fork()) >= 0); 529 if (pid == 0) { 530 CHECK(close(sp[0]) == 0); 531 fcntl_tests_send_0(sp[1]); 532 CHECK(close(sp[1]) == 0); 533 exit(0); 534 } else { 535 CHECK(close(sp[1]) == 0); 536 fcntl_tests_recv_0(sp[0]); 537 CHECK(waitpid(pid, NULL, 0) == pid); 538 CHECK(close(sp[0]) == 0); 539 } 540 541 exit(0); 542 } 543