1 /* 2 * Test Program for Unix Domain Sockets 3 * 4 * Overview: This program tests Unix Domain Sockets. It attempts 5 * to exercise the functions associated with Unix Domain Sockets. 6 * It also attempts to make sure all of the functions which handle 7 * file/socket descriptors work correctly when given a socket 8 * descriptor for a Unix domain socket. It also implicitly checks 9 * for the existance of constants like AF_UNIX and structures like 10 * sockaddr_un (it won't compile if they aren't defined). Besides 11 * checking that the sockets work properly, this test program also 12 * checks that the errors returned conform to the POSIX 2008 13 * standards. Some tests are omitted as they could adversely affect 14 * the operation of the host system. For example, implementing a test 15 * for socket() failing with errno = ENFILE would require using up all 16 * of the file descriptors supported by the OS (defined in 17 * /proc/sys/fs/file-max on Linux); this could cause problems for 18 * daemons and other processes running on the system. Some tests are 19 * omitted because they would require changes to libc or the kernel. 20 * For example, getting EINTR would require delaying the system call 21 * execution time long enough to raise a signal to interupt it. Some 22 * tests were omitted because the particular errors cannot occur when 23 * using Unix domain sockets. For example, write() will never fail with 24 * ENETDOWN because Unix domain sockets don't use network interfaces. 25 * 26 * Structure: Some functions can be tested or partially tested without 27 * making a connection, socket() for example. These have test 28 * functions like test_NAME(). The functionality that needs two way 29 * communication is contained within test_xfer(). 30 * 31 * Functions Tested: accept(), bind(), close(), connect(), dup(), 32 * dup2(), fstat(), getpeername(), getsockname(), getsockopt(), 33 * listen(), read(), readv(), recv(), recvfrom(), recvmsg(), select(), 34 * send(), sendmsg(), sendto(), setsockopt(), shutdown(), socket(), 35 * socketpair(), write(), writev() 36 */ 37 38 #define DEBUG 0 39 40 #include <ctype.h> 41 #include <errno.h> 42 #include <fcntl.h> 43 #include <signal.h> 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <string.h> 47 #include <sys/socket.h> 48 #include <sys/ucred.h> 49 #include <sys/stat.h> 50 #include <sys/time.h> 51 #include <sys/types.h> 52 #include <sys/uio.h> 53 #include <sys/un.h> 54 #include <sys/wait.h> 55 #include <time.h> 56 #include <unistd.h> 57 58 /* Maximum number of errors that we'll allow to occur before this test 59 * program gives us and quits. 60 */ 61 int max_error = 4; 62 #include "common.h" 63 64 65 /* Use the common testing code instead of reinventing the wheel. */ 66 67 /* path of the unix domain socket */ 68 #define TEST_SUN_PATH "test.sock" 69 #define TEST_SUN_PATHB "testb.sock" 70 71 /* filenames for symlinks -- we link these to each other to test ELOOP .*/ 72 #define TEST_SYM_A "test.a" 73 #define TEST_SYM_B "test.b" 74 75 /* text file and test phrase for testing file descriptor passing */ 76 #define TEST_TXT_FILE "test.txt" 77 #define MSG "This raccoon loves to eat bugs.\n" 78 79 /* buffer for send/recv */ 80 #define BUFSIZE (128) 81 82 #define ISO8601_FORMAT "%Y-%m-%dT%H:%M:%S" 83 84 /* socket types supported */ 85 int types[3] = {SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM}; 86 char sock_fullpath[PATH_MAX + 1]; 87 88 void test_abort_client_server(int abort_type); 89 void test_abort_client(int abort_type); 90 void test_abort_server(pid_t pid, int abort_type); 91 92 /* timestamps for debug and error logs */ 93 char *get_timestamp(void) 94 { 95 struct tm *tm; 96 time_t t; 97 size_t len; 98 char *s; 99 100 len = sizeof(char) * 32; 101 102 t = time(NULL); 103 if (t == -1) { 104 return NULL; 105 } 106 tm = gmtime(&t); 107 if (tm == NULL) { 108 return NULL; 109 } 110 111 s = (char *) malloc(len); 112 if (!s) { 113 perror("malloc"); 114 return NULL; 115 } 116 memset(s, '\0', len); 117 118 strftime(s, len - 1, ISO8601_FORMAT, tm); 119 return s; 120 } 121 122 /* macro to display information about a failed test and increment the errct */ 123 void test_fail_fl(char *msg, char *file, int line) 124 { 125 char *timestamp; 126 timestamp = get_timestamp(); 127 if (errct == 0) fprintf(stderr, "\n"); 128 fprintf(stderr, "[ERROR][%s] (%s Line %d) %s [pid=%d:errno=%d:%s]\n", 129 timestamp, file, line, msg, getpid(), 130 errno, strerror(errno)); 131 fflush(stderr); 132 if (timestamp != NULL) { 133 free(timestamp); 134 timestamp = NULL; 135 } 136 e(7); 137 } 138 #define test_fail(msg) test_fail_fl(msg, __FILE__, __LINE__) 139 140 /* Convert name to the full path of the socket. Assumes name is in cwd. */ 141 char *fullpath(char *name) 142 { 143 char cwd[PATH_MAX + 1]; 144 145 if (realpath(".", cwd) == NULL) 146 test_fail("Couldn't retrieve current working dir"); 147 148 snprintf(sock_fullpath, PATH_MAX, "%s/%s", cwd, name); 149 150 return(sock_fullpath); 151 } 152 153 #if DEBUG == 1 154 /* macros to display debugging information */ 155 void debug_fl(char *msg, char *file, int line) 156 { 157 char *timestamp; 158 timestamp = get_timestamp(); 159 fprintf(stdout,"[DEBUG][%s] (%s:%d) %s [pid=%d]\n", 160 timestamp, __FILE__, __LINE__, msg, getpid()); 161 fflush(stdout); 162 if (timestamp != NULL) { 163 free(timestamp); 164 timestamp = NULL; 165 } 166 } 167 #define debug(msg) debug_fl(msg, __FILE__, __LINE__) 168 #else 169 #define debug(msg) 170 #endif 171 172 #define SOCKET(sd,domain,type,protocol) \ 173 do { \ 174 errno = 0; \ 175 sd = socket(domain, type, protocol); \ 176 if (sd == -1) { \ 177 test_fail("sd = socket(domain, type, protocol) failed");\ 178 } \ 179 } while (0) 180 181 #define UNLINK(path) \ 182 do { \ 183 int rc; \ 184 errno = 0; \ 185 rc = unlink(path); \ 186 if (rc == -1 && errno != ENOENT) { \ 187 test_fail("unlink(path) failed"); \ 188 } \ 189 } while(0) 190 191 #define SYMLINK(oldpath,newpath) \ 192 do { \ 193 int rc; \ 194 errno = 0; \ 195 rc = symlink(oldpath,newpath); \ 196 if (rc == -1) { \ 197 test_fail("symlink(oldpath,newpath) failed"); \ 198 } \ 199 } while(0) 200 201 #define CLOSE(sd) \ 202 do { \ 203 int rc; \ 204 errno = 0; \ 205 rc = close(sd); \ 206 if (rc == -1) { \ 207 test_fail("close(sd) failed"); \ 208 } \ 209 } while (0) 210 211 void test_socket(void) 212 { 213 struct stat statbuf, statbuf2; 214 int sd, sd2; 215 int rc; 216 int i; 217 218 debug("entering test_socket()"); 219 220 debug("Test socket() with an unsupported address family"); 221 222 errno = 0; 223 sd = socket(-1, SOCK_STREAM, 0); 224 if (!(sd == -1 && errno == EAFNOSUPPORT)) { 225 test_fail("socket"); 226 if (sd != -1) { 227 CLOSE(sd); 228 } 229 } 230 231 debug("Test socket() with all available FDs open by this process"); 232 233 for (i = 3; i < getdtablesize(); i++) { 234 rc = open("/dev/null", O_RDONLY); 235 if (rc == -1) { 236 test_fail("we couldn't open /dev/null for read"); 237 } 238 } 239 240 errno = 0; 241 sd = socket(PF_UNIX, SOCK_STREAM, 0); 242 if (!(sd == -1 && errno == EMFILE)) { 243 test_fail("socket() call with all fds open should fail"); 244 if (sd != -1) { 245 CLOSE(sd); 246 } 247 } 248 249 for (i = 3; i < getdtablesize(); i++) { 250 CLOSE(i); 251 } 252 253 debug("Test socket() with an mismatched protocol"); 254 255 errno = 0; 256 sd = socket(PF_UNIX, SOCK_STREAM, 4); 257 if (!(sd == -1 && errno == EPROTONOSUPPORT)) { 258 test_fail("socket() should fail with errno = EPROTONOSUPPORT"); 259 if (sd != -1) { 260 CLOSE(sd); 261 } 262 } 263 264 debug("Test socket() success"); 265 266 /* 267 * open 2 sockets at once and *then* close them. 268 * This will test that /dev/uds is cloning properly. 269 */ 270 271 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 272 SOCKET(sd2, PF_UNIX, SOCK_STREAM, 0); 273 274 rc = fstat(sd, &statbuf); 275 if (rc == -1) { 276 test_fail("fstat failed on sd"); 277 } 278 279 rc = fstat(sd2, &statbuf2); 280 if (rc == -1) { 281 test_fail("fstat failed on sd2"); 282 } 283 284 285 if (statbuf.st_dev == statbuf2.st_dev) { 286 test_fail("/dev/uds isn't being cloned"); 287 } 288 289 CLOSE(sd2); 290 CLOSE(sd); 291 292 debug("leaving test_socket()"); 293 } 294 295 void test_header(void) 296 { 297 struct sockaddr_un sun; 298 debug("entering test_header()"); 299 300 sun.sun_family = AF_UNIX; 301 sun.sun_path[0] = 'x'; 302 sun.sun_path[1] = 'x'; 303 sun.sun_path[2] = 'x'; 304 sun.sun_path[3] = '\0'; 305 306 if (SUN_LEN(&sun) != 5) { 307 test_fail("SUN_LEN(&sun) should be 5"); 308 } 309 310 if (PF_UNIX != PF_LOCAL || PF_UNIX != AF_UNIX) { 311 test_fail("PF_UNIX, PF_LOCAL and AF_UNIX"); 312 } 313 } 314 315 void test_socketpair(void) 316 { 317 char buf[128]; 318 struct sockaddr_un addr; 319 int socket_vector[2]; 320 int rc; 321 int i; 322 323 debug("entering test_socketpair()"); 324 325 UNLINK(TEST_SUN_PATH); 326 memset(&addr, '\0', sizeof(struct sockaddr_un)); 327 addr.sun_family = AF_UNIX; 328 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 329 330 debug("Testing socketpair() success"); 331 332 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector); 333 if (rc == -1) { 334 test_fail("socketpair() should have worked"); 335 } 336 337 debug("Testing a simple read/write using sockets from socketpair()"); 338 memset(buf, '\0', sizeof(buf)); 339 340 strncpy(buf, "Howdy Partner", sizeof(buf) - 1); 341 342 rc = write(socket_vector[0], buf, sizeof(buf)); 343 if (rc == -1) { 344 test_fail("write(sd, buf, sizeof(buf)) failed unexpectedly"); 345 } 346 347 memset(buf, '\0', sizeof(buf)); 348 349 rc = read(socket_vector[1], buf, sizeof(buf)); 350 if (rc == -1) { 351 test_fail("read() failed unexpectedly"); 352 } 353 354 if (strncmp(buf, "Howdy Partner", strlen("Howdy Partner")) != 0) { 355 test_fail("We did not read what we wrote"); 356 } 357 358 CLOSE(socket_vector[0]); 359 CLOSE(socket_vector[1]); 360 361 debug("Test socketpair() with all FDs open by this process"); 362 363 for (i = 3; i < getdtablesize(); i++) { 364 rc = open("/dev/null", O_RDONLY); 365 if (rc == -1) { 366 test_fail("we couldn't open /dev/null for read"); 367 } 368 } 369 370 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector); 371 if (!(rc == -1 && errno == EMFILE)) { 372 test_fail("socketpair() should have failed with EMFILE"); 373 } 374 375 for (i = 3; i < getdtablesize(); i++) { 376 CLOSE(i); 377 } 378 379 rc = socketpair(PF_UNIX, SOCK_STREAM, 4, socket_vector); 380 if (!(rc == -1 && errno == EPROTONOSUPPORT)) { 381 test_fail("socketpair() should have failed"); 382 } 383 384 debug("leaving test_socketpair()"); 385 } 386 387 void test_ucred(void) 388 { 389 struct uucred credentials; 390 socklen_t ucred_length; 391 uid_t euid = geteuid(); 392 gid_t egid = getegid(); 393 int sv[2]; 394 int rc; 395 396 debug("Test credentials passing"); 397 398 ucred_length = sizeof(struct uucred); 399 400 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sv); 401 if (rc == -1) { 402 test_fail("socketpair(PF_UNIX, SOCK_STREAM, 0, sv) failed"); 403 } 404 405 memset(&credentials, '\0', ucred_length); 406 rc = getsockopt(sv[0], SOL_SOCKET, SO_PEERCRED, &credentials, 407 &ucred_length); 408 if (rc == -1) { 409 test_fail("getsockopt(SO_PEERCRED) failed"); 410 } else if (credentials.cr_ngroups != 0 || 411 credentials.cr_uid != geteuid() || 412 credentials.cr_gid != getegid()) { 413 /* printf("%d=%d %d=%d %d=%d",credentials.cr_ngroups, 0, 414 credentials.cr_uid, geteuid(), credentials.cr_gid, getegid()); */ 415 test_fail("Credential passing gave us the wrong cred"); 416 } 417 418 rc = getpeereid(sv[0], &euid, &egid); 419 if (rc == -1) { 420 test_fail("getpeereid(sv[0], &euid, &egid) failed"); 421 } else if (credentials.cr_uid != euid || credentials.cr_gid != egid) { 422 test_fail("getpeereid() didn't give the correct euid/egid"); 423 } 424 425 CLOSE(sv[0]); 426 CLOSE(sv[1]); 427 } 428 429 void test_getsockname(void) 430 { 431 int sd; 432 int rc; 433 struct sockaddr_un addr, sock_addr; 434 socklen_t sock_addr_len; 435 436 memset(&addr, '\0', sizeof(struct sockaddr_un)); 437 addr.sun_family = AF_UNIX; 438 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 439 440 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 441 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 442 if (rc == -1) { 443 test_fail("bind() should have worked"); 444 } 445 446 debug("Test getsockname() success"); 447 448 memset(&sock_addr, '\0', sizeof(struct sockaddr_un)); 449 sock_addr_len = sizeof(struct sockaddr_un); 450 451 rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len); 452 if (rc == -1) { 453 test_fail("getsockname() should have worked"); 454 } 455 456 if (!(sock_addr.sun_family == AF_UNIX && strncmp(sock_addr.sun_path, 457 fullpath(TEST_SUN_PATH), 458 sizeof(sock_addr.sun_path) - 1) == 0)) { 459 test_fail("getsockname() did return the right address"); 460 fprintf(stderr, "exp: '%s' | got: '%s'\n", addr.sun_path, 461 sock_addr.sun_path); 462 } 463 464 CLOSE(sd); 465 } 466 467 void test_bind(void) 468 { 469 struct sockaddr_un addr; 470 struct sockaddr_un sock_addr; 471 socklen_t sock_addr_len; 472 int sd; 473 int sd2; 474 int rc; 475 476 debug("entering test_bind()"); 477 UNLINK(TEST_SUN_PATH); 478 memset(&addr, '\0', sizeof(struct sockaddr_un)); 479 addr.sun_family = AF_UNIX; 480 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 481 482 debug("Test bind() success"); 483 484 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 485 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 486 if (rc == -1) { 487 test_fail("bind() should have worked"); 488 } 489 490 debug("Test getsockname() success"); 491 492 memset(&sock_addr, '\0', sizeof(struct sockaddr_un)); 493 sock_addr_len = sizeof(struct sockaddr_un); 494 495 rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len); 496 if (rc == -1) { 497 test_fail("getsockname() should have worked"); 498 } 499 500 if (!(sock_addr.sun_family == AF_UNIX && 501 strncmp(sock_addr.sun_path, 502 fullpath(TEST_SUN_PATH), 503 sizeof(sock_addr.sun_path) - 1) == 0)) { 504 505 test_fail("getsockname() didn't return the right addr"); 506 fprintf(stderr, "exp: '%s' | got: '%s'\n", addr.sun_path, 507 sock_addr.sun_path); 508 } 509 510 debug("Test bind() with a address that has already been bind()'d"); 511 512 SOCKET(sd2, PF_UNIX, SOCK_STREAM, 0); 513 errno = 0; 514 rc = bind(sd2, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 515 if (!((rc == -1) && (errno == EADDRINUSE))) { 516 test_fail("bind() should have failed with EADDRINUSE"); 517 } 518 CLOSE(sd2); 519 CLOSE(sd); 520 UNLINK(TEST_SUN_PATH); 521 522 debug("Test bind() with an empty sun_path"); 523 524 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 525 memset(addr.sun_path, '\0', sizeof(addr.sun_path)); 526 errno = 0; 527 528 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 529 if (!(rc == -1 && errno == ENOENT)) { 530 test_fail("bind() should have failed with ENOENT"); 531 } 532 CLOSE(sd); 533 534 debug("Test bind() with a NULL address"); 535 536 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 537 errno = 0; 538 rc = bind(sd, (struct sockaddr *) NULL, sizeof(struct sockaddr_un)); 539 if (!((rc == -1) && (errno == EFAULT))) { 540 test_fail("bind() should have failed with EFAULT"); 541 } 542 CLOSE(sd); 543 544 debug("Test bind() using a symlink loop"); 545 546 UNLINK(TEST_SUN_PATH); 547 UNLINK(TEST_SYM_A); 548 UNLINK(TEST_SYM_B); 549 550 SYMLINK(TEST_SYM_A, TEST_SYM_B); 551 SYMLINK(TEST_SYM_B, TEST_SYM_A); 552 553 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 554 555 strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1); 556 errno = 0; 557 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 558 if (!((rc == -1) && (errno == ELOOP))) { 559 test_fail("bind() should have failed with ELOOP"); 560 } 561 CLOSE(sd); 562 563 UNLINK(TEST_SUN_PATH); 564 UNLINK(TEST_SYM_A); 565 UNLINK(TEST_SYM_B); 566 567 /* Test bind with garbage in sockaddr_un */ 568 memset(&addr, '?', sizeof(struct sockaddr_un)); 569 addr.sun_family = AF_UNIX; 570 addr.sun_path[0] = 'f'; 571 addr.sun_path[1] = 'o'; 572 addr.sun_path[2] = 'o'; 573 addr.sun_path[3] = '\0'; 574 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 575 rc = bind(sd, (struct sockaddr *) &addr, strlen(addr.sun_path) + 1); 576 if (rc == -1) { 577 test_fail("bind() should have worked"); 578 } 579 CLOSE(sd); 580 UNLINK("foo"); 581 582 debug("leaving test_bind()"); 583 } 584 585 void test_listen(void) 586 { 587 int rc; 588 589 debug("entering test_listen()"); 590 591 debug("Test listen() with a bad file descriptor"); 592 593 errno = 0; 594 rc = listen(-1, 0); 595 if (!(rc == -1 && errno == EBADF)) { 596 test_fail("listen(-1, 0) should have failed"); 597 } 598 599 debug("Test listen() with a non-socket file descriptor"); 600 601 errno = 0; 602 rc = listen(0, 0); 603 /* Test on errno disabled here: there's currently no telling what this 604 * will return. POSIX says it should be ENOTSOCK, MINIX3 libc returns 605 * ENOSYS, and we used to test for ENOTTY here.. 606 */ 607 if (!(rc == -1)) { 608 test_fail("listen(0, 0) should have failed"); 609 } 610 611 debug("leaving test_listen()"); 612 } 613 614 void test_shutdown(void) 615 { 616 int how[3] = { SHUT_RD, SHUT_WR, SHUT_RDWR }; 617 int sd; 618 int rc; 619 int i; 620 621 debug("entering test_shutdown()"); 622 623 /* test for each direction (read, write, read-write) */ 624 for (i = 0; i < 3; i++) { 625 626 debug("test shutdown() with an invalid descriptor"); 627 628 errno = 0; 629 rc = shutdown(-1, how[i]); 630 if (!(rc == -1 && errno == EBADF)) { 631 test_fail("shutdown(-1, how[i]) should have failed"); 632 } 633 634 debug("test shutdown() with a non-socket descriptor"); 635 636 errno = 0; 637 rc = shutdown(0, how[i]); 638 if (!(rc == -1 && errno == ENOSYS)) { 639 test_fail("shutdown() should have failed with ENOSYS"); 640 } 641 642 debug("test shutdown() with a socket that is not connected"); 643 644 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 645 errno = 0; 646 rc = shutdown(sd, how[i]); 647 if (!(rc == -1 && errno == ENOTCONN)) { 648 test_fail("shutdown() should have failed"); 649 } 650 CLOSE(sd); 651 } 652 653 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 654 errno = 0; 655 rc = shutdown(sd, -1); 656 if (!(rc == -1 && errno == ENOTCONN)) { 657 test_fail("shutdown(sd, -1) should have failed with ENOTCONN"); 658 } 659 CLOSE(sd); 660 661 debug("leaving test_shutdown()"); 662 } 663 664 void test_close(void) 665 { 666 struct sockaddr_un addr; 667 int sd, sd2; 668 int rc, i; 669 670 debug("entering test_close()"); 671 672 UNLINK(TEST_SUN_PATH); 673 674 memset(&addr, '\0', sizeof(struct sockaddr_un)); 675 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 676 addr.sun_family = AF_UNIX; 677 678 debug("Test close() success"); 679 680 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 681 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 682 if (rc != 0) { 683 test_fail("bind() should have worked"); 684 } 685 686 CLOSE(sd); 687 688 debug("Close an already closed file descriptor"); 689 690 errno = 0; 691 rc = close(sd); 692 if (!(rc == -1 && errno == EBADF)) { 693 test_fail("close(sd) should have failed with EBADF"); 694 } 695 696 UNLINK(TEST_SUN_PATH); 697 698 debug("dup()'ing a file descriptor and closing both should work"); 699 700 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 701 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 702 if (rc != 0) { 703 test_fail("bind() should have worked"); 704 } 705 706 errno = 0; 707 sd2 = dup(sd); 708 if (sd2 == -1) { 709 test_fail("dup(sd) should have worked"); 710 } else { 711 CLOSE(sd2); 712 CLOSE(sd); 713 } 714 715 UNLINK(TEST_SUN_PATH); 716 717 /* Create and close a socket a bunch of times. 718 * If the implementation doesn't properly free the 719 * socket during close(), eventually socket() will 720 * fail when the internal descriptor table is full. 721 */ 722 for (i = 0; i < 1024; i++) { 723 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 724 CLOSE(sd); 725 } 726 727 debug("leaving test_close()"); 728 } 729 730 void test_sockopts(void) 731 { 732 int i; 733 int rc; 734 int sd; 735 int option_value; 736 socklen_t option_len; 737 738 debug("entering test_sockopts()"); 739 740 for (i = 0; i < 3; i++) { 741 742 SOCKET(sd, PF_UNIX, types[i], 0); 743 744 debug("Test setsockopt() works"); 745 746 option_value = 0; 747 option_len = sizeof(option_value); 748 errno = 0; 749 rc = getsockopt(sd, SOL_SOCKET, SO_TYPE, &option_value, 750 &option_len); 751 if (rc != 0) { 752 test_fail("setsockopt() should have worked"); 753 } 754 755 if (option_value != types[i]) { 756 test_fail("SO_TYPE didn't seem to work."); 757 } 758 759 CLOSE(sd); 760 } 761 762 763 764 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 765 766 debug("Test setsockopt() works"); 767 768 option_value = 0; 769 option_len = sizeof(option_value); 770 errno = 0; 771 rc = getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &option_value, &option_len); 772 if (rc != 0) { 773 test_fail("getsockopt() should have worked"); 774 } 775 776 if (option_value != PIPE_BUF) { 777 test_fail("SO_SNDBUF didn't seem to work."); 778 } 779 780 CLOSE(sd); 781 782 783 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 784 785 debug("Test setsockopt() works"); 786 787 option_value = 0; 788 option_len = sizeof(option_value); 789 errno = 0; 790 rc = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &option_value, &option_len); 791 if (rc != 0) { 792 test_fail("getsockopt() should have worked"); 793 } 794 795 if (option_value != PIPE_BUF) { 796 test_fail("SO_RCVBUF didn't seem to work."); 797 } 798 799 CLOSE(sd); 800 801 802 debug("leaving test_sockopts()"); 803 } 804 805 void test_read(void) 806 { 807 int rc; 808 int fd; 809 char buf[BUFSIZE]; 810 811 debug("entering test_read()"); 812 813 errno = 0; 814 rc = read(-1, buf, sizeof(buf)); 815 if (!(rc == -1 && errno == EBADF)) { 816 test_fail("read() should have failed with EBADF"); 817 } 818 819 fd = open("/tmp", O_RDONLY); 820 if (fd == -1) { 821 test_fail("open(\"/tmp\", O_RDONLY) should have worked"); 822 } 823 824 CLOSE(fd); 825 826 debug("leaving test_read()"); 827 } 828 829 void test_write(void) 830 { 831 int rc; 832 char buf[BUFSIZE]; 833 834 debug("entering test_write()"); 835 836 errno = 0; 837 rc = write(-1, buf, sizeof(buf)); 838 if (!(rc == -1 && errno == EBADF)) { 839 test_fail("write() should have failed with EBADF"); 840 } 841 842 debug("leaving test_write()"); 843 } 844 845 void test_dup(void) 846 { 847 struct stat info1; 848 struct stat info2; 849 struct sockaddr_un addr; 850 int sd, sd2; 851 int rc; 852 int i; 853 854 debug("entering test_dup()"); 855 856 UNLINK(TEST_SUN_PATH); 857 858 memset(&addr, '\0', sizeof(struct sockaddr_un)); 859 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 860 addr.sun_family = AF_UNIX; 861 862 debug("Test dup()"); 863 864 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 865 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 866 if (rc != 0) { 867 test_fail("bind() should have worked"); 868 } 869 870 errno = 0; 871 sd2 = dup(sd); 872 if (sd2 == -1) { 873 test_fail("dup(sd) should have worked"); 874 } 875 876 rc = fstat(sd, &info1); 877 if (rc == -1) { 878 test_fail("fstat(fd, &info1) failed"); 879 } 880 881 rc = fstat(sd2, &info2); 882 if (rc == -1) { 883 test_fail("fstat(sd, &info2) failed"); 884 } 885 886 if (info1.st_ino != info2.st_ino) { 887 test_fail("dup() failed info1.st_ino != info2.st_ino"); 888 } 889 890 CLOSE(sd); 891 CLOSE(sd2); 892 893 debug("Test dup() with a closed socket"); 894 895 errno = 0; 896 rc = dup(sd); 897 if (!(rc == -1 && errno == EBADF)) { 898 test_fail("dup(sd) on a closed socket shouldn't have worked"); 899 } 900 901 debug("Test dup() with socket descriptor of -1"); 902 903 errno = 0; 904 rc = dup(-1); 905 if (!(rc == -1 && errno == EBADF)) { 906 test_fail("dup(-1) shouldn't have worked"); 907 } 908 909 debug("Test dup() when all of the file descriptors are taken"); 910 911 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 912 913 for (i = 4; i < getdtablesize(); i++) { 914 rc = open("/dev/null", O_RDONLY); 915 if (rc == -1) { 916 test_fail("we couldn't open /dev/null for read"); 917 } 918 } 919 920 errno = 0; 921 sd2 = dup(sd); 922 if (!(sd2 == -1 && errno == EMFILE)) { 923 test_fail("dup(sd) should have failed with errno = EMFILE"); 924 } 925 926 for (i = 3; i < getdtablesize(); i++) { 927 CLOSE(i); 928 } 929 930 UNLINK(TEST_SUN_PATH); 931 932 debug("leaving test_dup()"); 933 } 934 935 void test_dup2(void) 936 { 937 struct stat info1; 938 struct stat info2; 939 struct sockaddr_un addr; 940 int sd; 941 int fd; 942 int rc; 943 944 debug("entering test_dup2()"); 945 UNLINK(TEST_SUN_PATH); 946 947 memset(&addr, '\0', sizeof(struct sockaddr_un)); 948 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 949 addr.sun_family = AF_UNIX; 950 951 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 952 953 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 954 if (rc != 0) { 955 test_fail("bind() should have worked"); 956 } 957 958 fd = open("/dev/null", O_RDONLY); 959 if (fd == -1) { 960 test_fail("open(\"/dev/null\", O_RDONLY) failed"); 961 } 962 963 fd = dup2(sd, fd); 964 if (fd == -1) { 965 test_fail("dup2(sd, fd) failed."); 966 } 967 968 memset(&info1, '\0', sizeof(struct stat)); 969 memset(&info2, '\0', sizeof(struct stat)); 970 971 rc = fstat(fd, &info1); 972 if (rc == -1) { 973 test_fail("fstat(fd, &info1) failed"); 974 } 975 976 rc = fstat(sd, &info2); 977 if (rc == -1) { 978 test_fail("fstat(sd, &info2) failed"); 979 } 980 981 if (!(info1.st_ino == info2.st_ino && 982 major(info1.st_dev) == major(info2.st_dev) && 983 minor(info1.st_dev) == minor(info2.st_dev))) { 984 985 test_fail("dup2() failed"); 986 } 987 988 CLOSE(fd); 989 CLOSE(sd); 990 991 UNLINK(TEST_SUN_PATH); 992 debug("leaving test_dup2()"); 993 994 } 995 996 /* 997 * A toupper() server. This toy server converts a string to upper case. 998 */ 999 void test_xfer_server(pid_t pid) 1000 { 1001 int i; 1002 struct timeval tv; 1003 fd_set readfds; 1004 int status; 1005 int rc; 1006 int sd; 1007 char buf[BUFSIZE]; 1008 socklen_t client_addr_size; 1009 int client_sd; 1010 struct sockaddr_un addr; 1011 struct sockaddr_un client_addr; 1012 1013 status = 0; 1014 rc = 0; 1015 sd = 0; 1016 client_sd = 0; 1017 client_addr_size = sizeof(struct sockaddr_un); 1018 1019 memset(&buf, '\0', sizeof(buf)); 1020 memset(&addr, '\0', sizeof(struct sockaddr_un)); 1021 memset(&client_addr, '\0', sizeof(struct sockaddr_un)); 1022 1023 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 1024 addr.sun_family = AF_UNIX; 1025 1026 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 1027 1028 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 1029 if (rc == -1) { 1030 test_fail("bind() should have worked"); 1031 } 1032 1033 rc = listen(sd, 8); 1034 if (rc == -1) { 1035 test_fail("listen(sd, 8) should have worked"); 1036 } 1037 1038 /* we're ready for connections, time to tell the client to start 1039 * the test 1040 */ 1041 kill(pid, SIGUSR1); 1042 1043 tv.tv_sec = 10; 1044 tv.tv_usec = 0; 1045 1046 FD_ZERO(&readfds); 1047 FD_SET(sd, &readfds); 1048 1049 /* use select() in case the client is really broken and never 1050 * attempts to connect (we don't want to block on accept() 1051 * forever). 1052 */ 1053 rc = select(sd + 1, &readfds, NULL, NULL, &tv); 1054 if (rc == -1) { 1055 test_fail("[server] select() should not have failed"); 1056 } 1057 1058 if (rc != 1) { 1059 test_fail("[server] select() should have returned 1"); 1060 printf("[server] select returned %d\n", rc); 1061 } 1062 1063 if (!(FD_ISSET(sd, &readfds))) { 1064 test_fail("[server] client didn't connect within 10 seconds"); 1065 kill(pid, SIGKILL); 1066 return; 1067 } 1068 1069 client_sd = accept(sd, (struct sockaddr *) &client_addr, 1070 &client_addr_size); 1071 1072 if (client_sd == -1) { 1073 test_fail("accept() should have worked"); 1074 kill(pid, SIGKILL); 1075 return; 1076 } else { 1077 debug("[server] client accept()'d"); 1078 } 1079 1080 debug("[server] Reading message"); 1081 rc = read(client_sd, buf, sizeof(buf)); 1082 if (rc == -1) { 1083 test_fail("read() failed unexpectedly"); 1084 kill(pid, SIGKILL); 1085 return; 1086 } 1087 debug("[server] we got the following message:"); 1088 debug(buf); 1089 1090 for (i = 0; i < rc && i < 127; i++) { 1091 buf[i] = toupper(buf[i]); 1092 } 1093 1094 debug("[server] Writing message..."); 1095 rc = write(client_sd, buf, sizeof(buf)); 1096 if (rc == -1) { 1097 test_fail("write(client_sd, buf, sizeof(buf)) failed"); 1098 kill(pid, SIGKILL); 1099 return; 1100 } 1101 1102 if (rc < strlen(buf)) { 1103 test_fail("[server] write didn't write all the bytes"); 1104 } 1105 1106 memset(&buf, '\0', sizeof(buf)); 1107 1108 debug("[server] Recv message"); 1109 rc = recv(client_sd, buf, sizeof(buf), 0); 1110 if (rc == -1) { 1111 test_fail("recv() failed unexpectedly"); 1112 kill(pid, SIGKILL); 1113 return; 1114 } 1115 debug("[server] we got the following message:"); 1116 debug(buf); 1117 1118 for (i = 0; i < rc && i < 127; i++) { 1119 buf[i] = toupper(buf[i]); 1120 } 1121 1122 debug("[server] Sending message..."); 1123 rc = send(client_sd, buf, sizeof(buf), 0); 1124 if (rc == -1) { 1125 test_fail("send(client_sd, buf, sizeof(buf), 0) failed"); 1126 kill(pid, SIGKILL); 1127 return; 1128 } 1129 1130 if (rc < strlen(buf)) { 1131 test_fail("[server] write didn't write all the bytes"); 1132 } 1133 1134 memset(&buf, '\0', sizeof(buf)); 1135 1136 debug("[server] Recvfrom message"); 1137 rc = recvfrom(client_sd, buf, sizeof(buf), 0, NULL, 0); 1138 if (rc == -1) { 1139 test_fail("recvfrom() failed unexpectedly"); 1140 kill(pid, SIGKILL); 1141 return; 1142 } 1143 debug("[server] we got the following message:"); 1144 debug(buf); 1145 1146 for (i = 0; i < rc && i < 127; i++) { 1147 buf[i] = toupper(buf[i]); 1148 } 1149 1150 debug("[server] Sendto message..."); 1151 rc = sendto(client_sd, buf, sizeof(buf), 0, NULL, 0); 1152 if (rc == -1) { 1153 test_fail("sendto() failed"); 1154 kill(pid, SIGKILL); 1155 return; 1156 } 1157 1158 if (rc < strlen(buf)) { 1159 test_fail("[server] write didn't write all the bytes"); 1160 } 1161 1162 shutdown(client_sd, SHUT_RDWR); 1163 CLOSE(client_sd); 1164 1165 shutdown(sd, SHUT_RDWR); 1166 CLOSE(sd); 1167 1168 /* wait for client to exit */ 1169 do { 1170 errno = 0; 1171 rc = waitpid(pid, &status, 0); 1172 } while (rc == -1 && errno == EINTR); 1173 1174 /* we use the exit status to get its error count */ 1175 errct += WEXITSTATUS(status); 1176 } 1177 1178 int server_ready = 0; 1179 1180 /* signal handler for the client */ 1181 void test_xfer_sighdlr(int sig) 1182 { 1183 debug("entering signal handler"); 1184 switch (sig) { 1185 /* the server will send SIGUSR1 when it is time for us 1186 * to start the tests 1187 */ 1188 case SIGUSR1: 1189 server_ready = 1; 1190 debug("got SIGUSR1, the server is ready for the client"); 1191 break; 1192 default: 1193 debug("didn't get SIGUSR1"); 1194 } 1195 debug("leaving signal handler"); 1196 } 1197 1198 /* 1199 * A toupper() client. 1200 */ 1201 void test_xfer_client(void) 1202 { 1203 struct uucred credentials; 1204 socklen_t ucred_length; 1205 struct timeval tv; 1206 fd_set readfds; 1207 struct sockaddr_un addr; 1208 struct sockaddr_un peer_addr; 1209 socklen_t peer_addr_len; 1210 int sd; 1211 int rc; 1212 char buf[BUFSIZE]; 1213 1214 debug("[client] entering test_xfer_client()"); 1215 errct = 0; /* reset error count */ 1216 ucred_length = sizeof(struct uucred); 1217 memset(&buf, '\0', sizeof(buf)); 1218 1219 while (server_ready == 0) { 1220 debug("[client] waiting for the server to signal"); 1221 sleep(1); 1222 } 1223 1224 peer_addr_len = sizeof(struct sockaddr_un); 1225 1226 1227 debug("Creating symlink to TEST_SUN_PATH"); 1228 1229 SYMLINK(TEST_SUN_PATH, TEST_SYM_A); 1230 1231 memset(&addr, '\0', sizeof(struct sockaddr_un)); 1232 strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1); 1233 addr.sun_family = AF_UNIX; 1234 1235 debug("[client] creating client socket"); 1236 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 1237 1238 debug("[client] connecting to server through the symlink"); 1239 rc = connect(sd, (struct sockaddr *) &addr, 1240 sizeof(struct sockaddr_un)); 1241 if (rc == -1) { 1242 test_fail("[client] connect() should have worked"); 1243 } else { 1244 debug("[client] connected"); 1245 } 1246 1247 debug("[client] testing getpeername()"); 1248 memset(&peer_addr, '\0', sizeof(struct sockaddr_un)); 1249 rc = getpeername(sd, (struct sockaddr *) &peer_addr, &peer_addr_len); 1250 if (rc == -1) { 1251 test_fail("[client] getpeername() should have worked"); 1252 } 1253 1254 /* we need to use the full path "/usr/src/test/DIR_56/test.sock" 1255 * because that is what is returned by getpeername(). 1256 */ 1257 1258 if (!(peer_addr.sun_family == AF_UNIX && 1259 strncmp(peer_addr.sun_path, 1260 fullpath(TEST_SUN_PATH), 1261 sizeof(peer_addr.sun_path) - 1) == 0)) { 1262 1263 test_fail("getpeername() didn't return the right address"); 1264 } 1265 1266 strncpy(buf, "Hello, World!", sizeof(buf) - 1); 1267 debug("[client] send to server"); 1268 rc = write(sd, buf, sizeof(buf)); 1269 if (rc == -1) { 1270 test_fail("[client] write() failed unexpectedly"); 1271 } 1272 1273 memset(buf, '\0', sizeof(buf)); 1274 debug("[client] read from server"); 1275 rc = read(sd, buf, sizeof(buf)); 1276 if (rc == -1) { 1277 test_fail("[client] read() failed unexpectedly"); 1278 } else { 1279 debug("[client] we got the following message:"); 1280 debug(buf); 1281 } 1282 1283 if (strncmp(buf, "HELLO, WORLD!", sizeof(buf)) != 0) { 1284 test_fail("[client] We didn't get the correct response"); 1285 } 1286 1287 memset(&buf, '\0', sizeof(buf)); 1288 strncpy(buf, "Bonjour!", sizeof(buf) - 1); 1289 1290 debug("[client] send to server"); 1291 rc = send(sd, buf, sizeof(buf), 0); 1292 if (rc == -1) { 1293 test_fail("[client] send() failed unexpectedly"); 1294 } 1295 1296 debug("Test passing the client credentials to the server"); 1297 1298 memset(&credentials, '\0', ucred_length); 1299 rc = getsockopt(sd, SOL_SOCKET, SO_PEERCRED, &credentials, 1300 &ucred_length); 1301 1302 if (rc == -1) { 1303 test_fail("[client] getsockopt() failed"); 1304 } else if (credentials.cr_uid != geteuid() || 1305 credentials.cr_gid != getegid()) { 1306 printf("%d=%d=%d %d=%d=%d\n", credentials.cr_uid, getuid(), 1307 geteuid(), credentials.cr_gid, getgid(), getegid()); 1308 test_fail("[client] Credential passing gave us a bad UID/GID"); 1309 } 1310 1311 debug("Testing select()"); 1312 1313 tv.tv_sec = 2; 1314 tv.tv_usec = 500000; 1315 1316 FD_ZERO(&readfds); 1317 FD_SET(sd, &readfds); 1318 1319 rc = select(sd + 1, &readfds, NULL, NULL, &tv); 1320 if (rc == -1) { 1321 test_fail("[client] select() should not have failed"); 1322 } 1323 1324 if (rc != 1) { 1325 test_fail("[client] select() should have returned 1"); 1326 } 1327 1328 if (!(FD_ISSET(sd, &readfds))) { 1329 test_fail("The server didn't respond within 2.5 seconds"); 1330 } 1331 1332 memset(buf, '\0', sizeof(buf)); 1333 debug("[client] recv from server"); 1334 rc = recv(sd, buf, sizeof(buf), 0); 1335 if (rc == -1) { 1336 test_fail("[client] recv() failed unexpectedly"); 1337 } else { 1338 debug("[client] we got the following message:"); 1339 debug(buf); 1340 } 1341 1342 if (strncmp(buf, "BONJOUR!", sizeof(buf)) != 0) { 1343 test_fail("[client] We didn't get the right response."); 1344 } 1345 1346 memset(&buf, '\0', sizeof(buf)); 1347 strncpy(buf, "Hola!", sizeof(buf) - 1); 1348 1349 debug("[client] sendto to server"); 1350 rc = sendto(sd, buf, sizeof(buf), 0, NULL, 0); 1351 if (rc == -1) { 1352 test_fail("[client] sendto() failed"); 1353 } 1354 1355 debug("Testing select()"); 1356 1357 tv.tv_sec = 2; 1358 tv.tv_usec = 500000; 1359 1360 FD_ZERO(&readfds); 1361 FD_SET(sd, &readfds); 1362 1363 rc = select(sd + 1, &readfds, NULL, NULL, &tv); 1364 if (rc == -1) { 1365 test_fail("[client] select() should not have failed"); 1366 } 1367 1368 if (rc != 1) { 1369 test_fail("[client] select() should have returned 1"); 1370 } 1371 1372 if (!(FD_ISSET(sd, &readfds))) { 1373 test_fail("[client] The server didn't respond in 2.5 seconds"); 1374 } 1375 1376 memset(buf, '\0', sizeof(buf)); 1377 debug("[client] recvfrom from server"); 1378 rc = recvfrom(sd, buf, sizeof(buf), 0, NULL, 0); 1379 if (rc == -1) { 1380 test_fail("[cleint] recvfrom() failed unexpectedly"); 1381 } else { 1382 debug("[client] we got the following message:"); 1383 debug(buf); 1384 } 1385 1386 if (strncmp(buf, "HOLA!", sizeof(buf)) != 0) { 1387 test_fail("[client] We didn't get the right response."); 1388 } 1389 1390 debug("[client] closing socket"); 1391 CLOSE(sd); 1392 1393 debug("[client] leaving test_xfer_client()"); 1394 exit(errct); 1395 } 1396 1397 void test_xfer(void) 1398 { 1399 pid_t pid; 1400 1401 UNLINK(TEST_SYM_A); 1402 UNLINK(TEST_SUN_PATH); 1403 1404 /* the signal handler is only used by the client, but we have to 1405 * install it now. if we don't the server may signal the client 1406 * before the handler is installed. 1407 */ 1408 debug("installing signal handler"); 1409 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) { 1410 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed"); 1411 } 1412 1413 debug("signal handler installed"); 1414 1415 server_ready = 0; 1416 1417 pid = fork(); 1418 if (pid == -1) { 1419 test_fail("fork() failed"); 1420 return; 1421 } else if (pid == 0) { 1422 debug("child"); 1423 test_xfer_client(); 1424 test_fail("we should never get here"); 1425 exit(1); 1426 } else { 1427 debug("parent"); 1428 test_xfer_server(pid); 1429 debug("parent done"); 1430 } 1431 1432 UNLINK(TEST_SYM_A); 1433 UNLINK(TEST_SUN_PATH); 1434 } 1435 1436 void test_simple_client(int type) 1437 { 1438 char buf[BUFSIZE]; 1439 int sd, rc; 1440 struct sockaddr_un addr; 1441 1442 sd = socket(PF_UNIX, type, 0); 1443 if (sd == -1) { 1444 test_fail("socket"); 1445 exit(errct); 1446 } 1447 1448 while (server_ready == 0) { 1449 debug("[client] waiting for the server"); 1450 sleep(1); 1451 } 1452 1453 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 1454 addr.sun_family = AF_UNIX; 1455 1456 bzero(buf, BUFSIZE); 1457 snprintf(buf, BUFSIZE-1, "Hello, My Name is Client."); 1458 1459 if (type == SOCK_DGRAM) { 1460 1461 rc = sendto(sd, buf, strlen(buf) + 1, 0, 1462 (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 1463 if (rc == -1) { 1464 test_fail("sendto"); 1465 exit(errct); 1466 } 1467 1468 } else { 1469 1470 rc = connect(sd, (struct sockaddr *) &addr, 1471 sizeof(struct sockaddr_un)); 1472 if (rc == -1) { 1473 test_fail("connect"); 1474 exit(errct); 1475 } 1476 1477 rc = write(sd, buf, strlen(buf) + 1); 1478 1479 if (rc == -1) { 1480 test_fail("write"); 1481 } 1482 1483 memset(buf, '\0', BUFSIZE); 1484 rc = read(sd, buf, BUFSIZE); 1485 if (rc == -1) { 1486 test_fail("read"); 1487 } 1488 1489 if (strcmp("Hello, My Name is Server.", buf) != 0) { 1490 test_fail("didn't read the correct string"); 1491 } 1492 } 1493 1494 rc = close(sd); 1495 if (rc == -1) { 1496 test_fail("close"); 1497 } 1498 1499 exit(errct); 1500 } 1501 1502 void test_simple_server(int type, pid_t pid) 1503 { 1504 char buf[BUFSIZE]; 1505 int sd, rc, client_sd, status; 1506 struct sockaddr_un addr; 1507 socklen_t addr_len; 1508 1509 addr_len = sizeof(struct sockaddr_un); 1510 1511 sd = socket(PF_UNIX, type, 0); 1512 if (sd == -1) { 1513 test_fail("socket"); 1514 } 1515 1516 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 1517 addr.sun_family = AF_UNIX; 1518 1519 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 1520 if (rc == -1) { 1521 test_fail("bind"); 1522 } 1523 1524 if (type == SOCK_DGRAM) { 1525 1526 /* ready for client */ 1527 kill(pid, SIGUSR1); 1528 1529 rc = recvfrom(sd, buf, BUFSIZE, 0, 1530 (struct sockaddr *) &addr, &addr_len); 1531 if (rc == -1) { 1532 test_fail("recvfrom"); 1533 } 1534 1535 } else { 1536 1537 rc = listen(sd, 5); 1538 if (rc == -1) { 1539 test_fail("listen"); 1540 } 1541 1542 /* we're ready for connections, time to tell the client 1543 * to start the test 1544 */ 1545 kill(pid, SIGUSR1); 1546 1547 client_sd = accept(sd, (struct sockaddr *) &addr, &addr_len); 1548 if (client_sd == -1) { 1549 test_fail("accept"); 1550 } 1551 1552 memset(buf, '\0', BUFSIZE); 1553 rc = read(client_sd, buf, BUFSIZE); 1554 if (rc == -1) { 1555 test_fail("read"); 1556 } 1557 1558 if (strcmp("Hello, My Name is Client.", buf) != 0) { 1559 test_fail("didn't read the correct string"); 1560 } 1561 1562 /* added for extra fun to make the client block on read() */ 1563 sleep(1); 1564 1565 bzero(buf, BUFSIZE); 1566 snprintf(buf, BUFSIZE-1, "Hello, My Name is Server."); 1567 1568 rc = write(client_sd, buf, strlen(buf) + 1); 1569 if (rc == -1) { 1570 test_fail("write"); 1571 } 1572 rc = close(client_sd); 1573 if (rc == -1) { 1574 test_fail("close"); 1575 } 1576 } 1577 1578 rc = close(sd); 1579 if (rc == -1) { 1580 test_fail("close"); 1581 } 1582 1583 /* wait for client to exit */ 1584 do { 1585 errno = 0; 1586 rc = waitpid(pid, &status, 0); 1587 } while (rc == -1 && errno == EINTR); 1588 1589 /* we use the exit status to get its error count */ 1590 errct += WEXITSTATUS(status); 1591 } 1592 1593 void test_abort_client_server(int abort_type) 1594 { 1595 pid_t pid; 1596 debug("test_simple_client_server()"); 1597 1598 UNLINK(TEST_SUN_PATH); 1599 1600 /* the signal handler is only used by the client, but we have to 1601 * install it now. if we don't the server may signal the client 1602 * before the handler is installed. 1603 */ 1604 debug("installing signal handler"); 1605 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) { 1606 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed"); 1607 } 1608 1609 debug("signal handler installed"); 1610 1611 server_ready = 0; 1612 1613 pid = fork(); 1614 if (pid == -1) { 1615 test_fail("fork() failed"); 1616 return; 1617 } else if (pid == 0) { 1618 debug("child"); 1619 test_abort_client(abort_type); 1620 test_fail("we should never get here"); 1621 exit(1); 1622 } else { 1623 debug("parent"); 1624 test_abort_server(pid, abort_type); 1625 debug("parent done"); 1626 } 1627 1628 UNLINK(TEST_SUN_PATH); 1629 } 1630 1631 void test_abort_client(int abort_type) 1632 { 1633 char buf[BUFSIZE]; 1634 int sd, rc; 1635 struct sockaddr_un addr; 1636 1637 sd = socket(PF_UNIX, SOCK_STREAM, 0); 1638 if (sd == -1) { 1639 test_fail("socket"); 1640 exit(errct); 1641 } 1642 1643 while (server_ready == 0) { 1644 debug("[client] waiting for the server"); 1645 sleep(1); 1646 } 1647 1648 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 1649 addr.sun_family = AF_UNIX; 1650 1651 bzero(buf, BUFSIZE); 1652 snprintf(buf, BUFSIZE-1, "Hello, My Name is Client."); 1653 1654 rc = connect(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 1655 if (rc == -1) { 1656 test_fail("connect"); 1657 exit(errct); 1658 } 1659 1660 if (abort_type == 2) { 1661 /* Give server a chance to close connection */ 1662 sleep(2); 1663 rc = write(sd, buf, strlen(buf) + 1); 1664 if (rc != -1) { 1665 test_fail("write should have failed\n"); 1666 } 1667 if (errno != ECONNRESET) { 1668 test_fail("errno should've been ECONNRESET\n"); 1669 } 1670 } 1671 1672 rc = close(sd); 1673 if (rc == -1) { 1674 test_fail("close"); 1675 } 1676 1677 exit(errct); 1678 } 1679 1680 void test_abort_server(pid_t pid, int abort_type) 1681 { 1682 char buf[BUFSIZE]; 1683 int sd, rc, client_sd, status; 1684 struct sockaddr_un addr; 1685 socklen_t addr_len; 1686 1687 addr_len = sizeof(struct sockaddr_un); 1688 1689 sd = socket(PF_UNIX, SOCK_STREAM, 0); 1690 if (sd == -1) { 1691 test_fail("socket"); 1692 } 1693 1694 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 1695 addr.sun_family = AF_UNIX; 1696 1697 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 1698 if (rc == -1) { 1699 test_fail("bind"); 1700 } 1701 1702 rc = listen(sd, 5); 1703 if (rc == -1) { 1704 test_fail("listen"); 1705 } 1706 1707 /* we're ready for connections, time to tell the client 1708 * to start the test 1709 */ 1710 kill(pid, SIGUSR1); 1711 1712 client_sd = accept(sd, (struct sockaddr *) &addr, &addr_len); 1713 if (client_sd == -1) { 1714 test_fail("accept"); 1715 } 1716 1717 if (abort_type == 1) { 1718 memset(buf, '\0', BUFSIZE); 1719 rc = read(client_sd, buf, BUFSIZE); 1720 if (rc != -1) { 1721 test_fail("read should've failed\n"); 1722 } 1723 if (errno != ECONNRESET) { 1724 test_fail("errno should've been ECONNRESET\n"); 1725 } 1726 } /* else if (abort_type == 2) { */ 1727 rc = close(client_sd); 1728 if (rc == -1) { 1729 test_fail("close"); 1730 } 1731 /* } */ 1732 1733 rc = close(sd); 1734 if (rc == -1) { 1735 test_fail("close"); 1736 } 1737 1738 /* wait for client to exit */ 1739 do { 1740 errno = 0; 1741 rc = waitpid(pid, &status, 0); 1742 } while (rc == -1 && errno == EINTR); 1743 1744 /* we use the exit status to get its error count */ 1745 errct += WEXITSTATUS(status); 1746 } 1747 1748 void test_simple_client_server(int type) 1749 { 1750 pid_t pid; 1751 debug("test_simple_client_server()"); 1752 1753 UNLINK(TEST_SUN_PATH); 1754 1755 /* the signal handler is only used by the client, but we have to 1756 * install it now. if we don't the server may signal the client 1757 * before the handler is installed. 1758 */ 1759 debug("installing signal handler"); 1760 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) { 1761 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed"); 1762 } 1763 1764 debug("signal handler installed"); 1765 1766 server_ready = 0; 1767 1768 pid = fork(); 1769 if (pid == -1) { 1770 test_fail("fork() failed"); 1771 return; 1772 } else if (pid == 0) { 1773 debug("child"); 1774 test_simple_client(type); 1775 test_fail("we should never get here"); 1776 exit(1); 1777 } else { 1778 debug("parent"); 1779 test_simple_server(type, pid); 1780 debug("parent done"); 1781 } 1782 1783 UNLINK(TEST_SUN_PATH); 1784 } 1785 1786 void test_vectorio(int type) 1787 { 1788 int sv[2]; 1789 int rc; 1790 struct iovec iov[3]; 1791 char buf1[BUFSIZE]; 1792 char buf2[BUFSIZE]; 1793 char buf3[BUFSIZE]; 1794 char buf4[BUFSIZE*3]; 1795 const struct iovec *iovp = iov; 1796 1797 debug("begin vectorio tests"); 1798 1799 memset(buf1, '\0', BUFSIZE); 1800 strncpy(buf1, "HELLO ", BUFSIZE - 1); 1801 1802 memset(buf2, '\0', BUFSIZE); 1803 strncpy(buf2, "WORLD", BUFSIZE - 1); 1804 1805 memset(buf3, '\0', BUFSIZE); 1806 1807 rc = socketpair(PF_UNIX, type, 0, sv); 1808 if (rc == -1) { 1809 test_fail("socketpair"); 1810 } 1811 1812 iov[0].iov_base = buf1; 1813 iov[0].iov_len = strlen(buf1); 1814 iov[1].iov_base = buf2; 1815 iov[1].iov_len = strlen(buf2); 1816 iov[2].iov_base = buf3; 1817 iov[2].iov_len = 1; 1818 1819 rc = writev(sv[0], iovp, 3); 1820 if (rc == -1) { 1821 test_fail("writev"); 1822 } 1823 1824 memset(buf4, '\0', BUFSIZE*3); 1825 1826 rc = read(sv[1], buf4, BUFSIZE*3); 1827 if (rc == -1) { 1828 test_fail("read"); 1829 } 1830 1831 if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) { 1832 test_fail("the string we read was not 'HELLO WORLD'"); 1833 } 1834 1835 memset(buf1, '\0', BUFSIZE); 1836 strncpy(buf1, "Unit Test Time", BUFSIZE - 1); 1837 1838 rc = write(sv[1], buf1, strlen(buf1) + 1); 1839 if (rc == -1) { 1840 test_fail("write"); 1841 } 1842 1843 memset(buf2, '\0', BUFSIZE); 1844 memset(buf3, '\0', BUFSIZE); 1845 memset(buf4, '\0', BUFSIZE*3); 1846 1847 iov[0].iov_base = buf2; 1848 iov[0].iov_len = 5; 1849 iov[1].iov_base = buf3; 1850 iov[1].iov_len = 5; 1851 iov[2].iov_base = buf4; 1852 iov[2].iov_len = 32; 1853 1854 rc = readv(sv[0], iovp, 3); 1855 if (rc == -1) { 1856 test_fail("readv"); 1857 } 1858 1859 if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) || 1860 strncmp(buf4, "Time", 4)) { 1861 test_fail("readv"); 1862 } 1863 1864 rc = close(sv[0]); 1865 if (rc == -1) { 1866 test_fail("close"); 1867 } 1868 1869 rc = close(sv[1]); 1870 if (rc == -1) { 1871 test_fail("close"); 1872 } 1873 1874 debug("done vector io tests"); 1875 } 1876 1877 void test_msg(int type) 1878 { 1879 int sv[2]; 1880 int rc; 1881 struct msghdr msg1; 1882 struct msghdr msg2; 1883 struct iovec iov[3]; 1884 char buf1[BUFSIZE]; 1885 char buf2[BUFSIZE]; 1886 char buf3[BUFSIZE]; 1887 char buf4[BUFSIZE*3]; 1888 1889 debug("begin sendmsg/recvmsg tests"); 1890 1891 memset(buf1, '\0', BUFSIZE); 1892 strncpy(buf1, "HELLO ", BUFSIZE - 1); 1893 1894 memset(buf2, '\0', BUFSIZE); 1895 strncpy(buf2, "WORLD", BUFSIZE - 1); 1896 1897 memset(buf3, '\0', BUFSIZE); 1898 1899 rc = socketpair(PF_UNIX, type, 0, sv); 1900 if (rc == -1) { 1901 test_fail("socketpair"); 1902 } 1903 1904 iov[0].iov_base = buf1; 1905 iov[0].iov_len = strlen(buf1); 1906 iov[1].iov_base = buf2; 1907 iov[1].iov_len = strlen(buf2); 1908 iov[2].iov_base = buf3; 1909 iov[2].iov_len = 1; 1910 1911 memset(&msg1, '\0', sizeof(struct msghdr)); 1912 msg1.msg_name = NULL; 1913 msg1.msg_namelen = 0; 1914 msg1.msg_iov = iov; 1915 msg1.msg_iovlen = 3; 1916 msg1.msg_control = NULL; 1917 msg1.msg_controllen = 0; 1918 msg1.msg_flags = 0; 1919 1920 rc = sendmsg(sv[0], &msg1, 0); 1921 if (rc == -1) { 1922 test_fail("writev"); 1923 } 1924 1925 memset(buf4, '\0', BUFSIZE*3); 1926 1927 rc = read(sv[1], buf4, BUFSIZE*3); 1928 if (rc == -1) { 1929 test_fail("read"); 1930 } 1931 1932 if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) { 1933 test_fail("the string we read was not 'HELLO WORLD'"); 1934 } 1935 1936 memset(buf1, '\0', BUFSIZE); 1937 strncpy(buf1, "Unit Test Time", BUFSIZE - 1); 1938 1939 rc = write(sv[1], buf1, strlen(buf1) + 1); 1940 if (rc == -1) { 1941 test_fail("write"); 1942 } 1943 1944 memset(buf2, '\0', BUFSIZE); 1945 memset(buf3, '\0', BUFSIZE); 1946 memset(buf4, '\0', BUFSIZE*3); 1947 1948 iov[0].iov_base = buf2; 1949 iov[0].iov_len = 5; 1950 iov[1].iov_base = buf3; 1951 iov[1].iov_len = 5; 1952 iov[2].iov_base = buf4; 1953 iov[2].iov_len = 32; 1954 1955 memset(&msg2, '\0', sizeof(struct msghdr)); 1956 msg2.msg_name = NULL; 1957 msg2.msg_namelen = 0; 1958 msg2.msg_iov = iov; 1959 msg2.msg_iovlen = 3; 1960 msg2.msg_control = NULL; 1961 msg2.msg_controllen = 0; 1962 msg2.msg_flags = 0; 1963 1964 rc = recvmsg(sv[0], &msg2, 0); 1965 if (rc == -1) { 1966 test_fail("readv"); 1967 } 1968 1969 if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) || 1970 strncmp(buf4, "Time", 4)) { 1971 test_fail("readv"); 1972 } 1973 1974 rc = close(sv[0]); 1975 if (rc == -1) { 1976 test_fail("close"); 1977 } 1978 1979 rc = close(sv[1]); 1980 if (rc == -1) { 1981 test_fail("close"); 1982 } 1983 } 1984 1985 void test_msg_dgram(void) 1986 { 1987 int rc; 1988 int src; 1989 int dst; 1990 struct sockaddr_un addr; 1991 struct iovec iov[3]; 1992 struct msghdr msg1; 1993 struct msghdr msg2; 1994 char buf1[BUFSIZE]; 1995 char buf2[BUFSIZE]; 1996 char buf3[BUFSIZE]; 1997 socklen_t addrlen = sizeof(struct sockaddr_un); 1998 1999 debug("test msg_dgram"); 2000 2001 UNLINK(TEST_SUN_PATH); 2002 UNLINK(TEST_SUN_PATHB); 2003 2004 src = socket(PF_UNIX, SOCK_DGRAM, 0); 2005 if (src == -1) { 2006 test_fail("socket"); 2007 } 2008 2009 dst = socket(PF_UNIX, SOCK_DGRAM, 0); 2010 if (dst == -1) { 2011 test_fail("socket"); 2012 } 2013 2014 memset(&addr, '\0', sizeof(struct sockaddr_un)); 2015 addr.sun_family = AF_UNIX; 2016 strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1); 2017 rc = bind(src, (struct sockaddr *) &addr, addrlen); 2018 if (rc == -1) { 2019 test_fail("bind"); 2020 } 2021 2022 memset(&addr, '\0', sizeof(struct sockaddr_un)); 2023 addr.sun_family = AF_UNIX; 2024 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 2025 2026 rc = bind(dst, (struct sockaddr *) &addr, addrlen); 2027 if (rc == -1) { 2028 test_fail("bind"); 2029 } 2030 2031 memset(&buf1, '\0', BUFSIZE); 2032 memset(&buf2, '\0', BUFSIZE); 2033 memset(&buf3, '\0', BUFSIZE); 2034 2035 strncpy(buf1, "Minix ", BUFSIZE-1); 2036 strncpy(buf2, "is ", BUFSIZE-1); 2037 strncpy(buf3, "great!", BUFSIZE-1); 2038 2039 iov[0].iov_base = buf1; 2040 iov[0].iov_len = 6; 2041 iov[1].iov_base = buf2; 2042 iov[1].iov_len = 3; 2043 iov[2].iov_base = buf3; 2044 iov[2].iov_len = 32; 2045 2046 memset(&msg1, '\0', sizeof(struct msghdr)); 2047 msg1.msg_name = &addr; 2048 msg1.msg_namelen = addrlen; 2049 msg1.msg_iov = iov; 2050 msg1.msg_iovlen = 3; 2051 msg1.msg_control = NULL; 2052 msg1.msg_controllen = 0; 2053 msg1.msg_flags = 0; 2054 2055 rc = sendmsg(src, &msg1, 0); 2056 if (rc == -1) { 2057 test_fail("sendmsg"); 2058 } 2059 2060 memset(&buf1, '\0', BUFSIZE); 2061 memset(&buf2, '\0', BUFSIZE); 2062 2063 iov[0].iov_base = buf1; 2064 iov[0].iov_len = 9; 2065 iov[1].iov_base = buf2; 2066 iov[1].iov_len = 32; 2067 2068 memset(&addr, '\0', sizeof(struct sockaddr_un)); 2069 memset(&msg2, '\0', sizeof(struct msghdr)); 2070 msg2.msg_name = &addr; 2071 msg2.msg_namelen = sizeof(struct sockaddr_un); 2072 msg2.msg_iov = iov; 2073 msg2.msg_iovlen = 2; 2074 msg2.msg_control = NULL; 2075 msg2.msg_controllen = 0; 2076 msg2.msg_flags = 0; 2077 2078 rc = recvmsg(dst, &msg2, 0); 2079 if (rc == -1) { 2080 test_fail("recvmsg"); 2081 } 2082 2083 if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) { 2084 test_fail("recvmsg"); 2085 } 2086 2087 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock" 2088 * because that is what is returned by recvmsg(). 2089 */ 2090 if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path, 2091 fullpath(TEST_SUN_PATHB))) { 2092 test_fail("recvmsg"); 2093 } 2094 2095 rc = close(dst); 2096 if (rc == -1) { 2097 test_fail("close"); 2098 } 2099 2100 rc = close(src); 2101 if (rc == -1) { 2102 test_fail("close"); 2103 } 2104 2105 UNLINK(TEST_SUN_PATH); 2106 UNLINK(TEST_SUN_PATHB); 2107 } 2108 2109 void test_scm_credentials(void) 2110 { 2111 int rc; 2112 int src; 2113 int dst; 2114 struct uucred cred; 2115 struct cmsghdr *cmsg = NULL; 2116 struct sockaddr_un addr; 2117 struct iovec iov[3]; 2118 struct msghdr msg1; 2119 struct msghdr msg2; 2120 char buf1[BUFSIZE]; 2121 char buf2[BUFSIZE]; 2122 char buf3[BUFSIZE]; 2123 char ctrl[BUFSIZE]; 2124 socklen_t addrlen = sizeof(struct sockaddr_un); 2125 2126 debug("test_scm_credentials"); 2127 2128 UNLINK(TEST_SUN_PATH); 2129 UNLINK(TEST_SUN_PATHB); 2130 2131 debug("creating src socket"); 2132 2133 src = socket(PF_UNIX, SOCK_DGRAM, 0); 2134 if (src == -1) { 2135 test_fail("socket"); 2136 } 2137 2138 debug("creating dst socket"); 2139 2140 dst = socket(PF_UNIX, SOCK_DGRAM, 0); 2141 if (dst == -1) { 2142 test_fail("socket"); 2143 } 2144 2145 debug("binding src socket"); 2146 2147 memset(&addr, '\0', sizeof(struct sockaddr_un)); 2148 addr.sun_family = AF_UNIX; 2149 strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1); 2150 rc = bind(src, (struct sockaddr *) &addr, addrlen); 2151 if (rc == -1) { 2152 test_fail("bind"); 2153 } 2154 2155 debug("binding dst socket"); 2156 2157 memset(&addr, '\0', sizeof(struct sockaddr_un)); 2158 addr.sun_family = AF_UNIX; 2159 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 2160 2161 rc = bind(dst, (struct sockaddr *) &addr, addrlen); 2162 if (rc == -1) { 2163 test_fail("bind"); 2164 } 2165 2166 memset(&buf1, '\0', BUFSIZE); 2167 memset(&buf2, '\0', BUFSIZE); 2168 memset(&buf3, '\0', BUFSIZE); 2169 memset(&ctrl, '\0', BUFSIZE); 2170 2171 strncpy(buf1, "Minix ", BUFSIZE-1); 2172 strncpy(buf2, "is ", BUFSIZE-1); 2173 strncpy(buf3, "great!", BUFSIZE-1); 2174 2175 iov[0].iov_base = buf1; 2176 iov[0].iov_len = 6; 2177 iov[1].iov_base = buf2; 2178 iov[1].iov_len = 3; 2179 iov[2].iov_base = buf3; 2180 iov[2].iov_len = 32; 2181 2182 memset(&msg1, '\0', sizeof(struct msghdr)); 2183 msg1.msg_name = &addr; 2184 msg1.msg_namelen = addrlen; 2185 msg1.msg_iov = iov; 2186 msg1.msg_iovlen = 3; 2187 msg1.msg_control = NULL; 2188 msg1.msg_controllen = 0; 2189 msg1.msg_flags = 0; 2190 2191 debug("sending msg1"); 2192 2193 rc = sendmsg(src, &msg1, 0); 2194 if (rc == -1) { 2195 test_fail("sendmsg"); 2196 } 2197 2198 memset(&buf1, '\0', BUFSIZE); 2199 memset(&buf2, '\0', BUFSIZE); 2200 memset(&buf3, '\0', BUFSIZE); 2201 memset(&ctrl, '\0', BUFSIZE); 2202 2203 iov[0].iov_base = buf1; 2204 iov[0].iov_len = 9; 2205 iov[1].iov_base = buf2; 2206 iov[1].iov_len = 32; 2207 2208 memset(&addr, '\0', sizeof(struct sockaddr_un)); 2209 memset(&msg2, '\0', sizeof(struct msghdr)); 2210 msg2.msg_name = &addr; 2211 msg2.msg_namelen = sizeof(struct sockaddr_un); 2212 msg2.msg_iov = iov; 2213 msg2.msg_iovlen = 2; 2214 msg2.msg_control = ctrl; 2215 msg2.msg_controllen = BUFSIZE; 2216 msg2.msg_flags = 0; 2217 2218 debug("recv msg2"); 2219 2220 rc = recvmsg(dst, &msg2, 0); 2221 if (rc == -1) { 2222 test_fail("recvmsg"); 2223 } 2224 2225 debug("checking results"); 2226 2227 if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) { 2228 test_fail("recvmsg"); 2229 } 2230 2231 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock" 2232 * because that is what is returned by recvmsg(). 2233 */ 2234 if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path, 2235 fullpath(TEST_SUN_PATHB))) { 2236 test_fail("recvmsg"); 2237 } 2238 2239 debug("looking for credentials"); 2240 2241 memset(&cred, '\0', sizeof(struct uucred)); 2242 for (cmsg = CMSG_FIRSTHDR(&msg2); cmsg != NULL; 2243 cmsg = CMSG_NXTHDR(&msg2, cmsg)) { 2244 2245 if (cmsg->cmsg_level == SOL_SOCKET && 2246 cmsg->cmsg_type == SCM_CREDS) { 2247 2248 memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct uucred)); 2249 break; 2250 } 2251 } 2252 2253 if (cred.cr_ngroups != 0 || cred.cr_uid != geteuid() || 2254 cred.cr_gid != getegid()) { 2255 2256 test_fail("did no receive the proper credentials"); 2257 } 2258 2259 rc = close(dst); 2260 if (rc == -1) { 2261 test_fail("close"); 2262 } 2263 2264 rc = close(src); 2265 if (rc == -1) { 2266 test_fail("close"); 2267 } 2268 2269 UNLINK(TEST_SUN_PATH); 2270 UNLINK(TEST_SUN_PATHB); 2271 } 2272 2273 void test_connect(void) 2274 { 2275 int i, sd, sds[2], rc; 2276 2277 /* connect() is already tested throughout test56, but 2278 * in most cases the client and server end up on /dev/uds 2279 * minor 0 and minor 1. This test opens some sockets first and 2280 * then calls test_simple_client_server(). This forces the 2281 * client and server minor numbers higher in the descriptor table. 2282 */ 2283 2284 debug("starting test_connect()"); 2285 2286 sd = socket(AF_UNIX, SOCK_DGRAM, 0); 2287 if (sd == -1) { 2288 test_fail("couldn't create a socket"); 2289 } 2290 2291 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sds); 2292 if (rc == -1) { 2293 test_fail("couldn't create a socketpair"); 2294 } 2295 2296 for (i = 0; i < 3; i++) { 2297 test_simple_client_server(types[i]); 2298 } 2299 2300 rc = close(sds[1]); 2301 if (rc == -1) { 2302 test_fail("close() failed"); 2303 } 2304 2305 rc = close(sds[0]); 2306 if (rc == -1) { 2307 test_fail("close() failed"); 2308 } 2309 2310 rc = close(sd); 2311 if (rc == -1) { 2312 test_fail("close() failed"); 2313 } 2314 2315 debug("exiting test_connect()"); 2316 } 2317 2318 int test_multiproc_read(void) 2319 { 2320 /* test that when we fork() a process with an open socket descriptor, 2321 * the descriptor in each process points to the same thing. 2322 */ 2323 2324 pid_t pid; 2325 int sds[2]; 2326 int rc, status; 2327 char buf[3]; 2328 2329 debug("entering test_multiproc_read()"); 2330 2331 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds); 2332 if (rc == -1) { 2333 test_fail("socketpair"); 2334 return 1; 2335 } 2336 2337 memset(buf, '\0', 3); 2338 2339 2340 /* the signal handler is only used by the client, but we have to 2341 * install it now. if we don't the server may signal the client 2342 * before the handler is installed. 2343 */ 2344 debug("installing signal handler"); 2345 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) { 2346 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed"); 2347 return 1; 2348 } 2349 2350 debug("signal handler installed"); 2351 2352 server_ready = 0; 2353 2354 pid = fork(); 2355 2356 if (pid == -1) { 2357 2358 test_fail("fork"); 2359 return 1; 2360 2361 } else if (pid == 0) { 2362 2363 while (server_ready == 0) { 2364 debug("waiting for SIGUSR1 from parent"); 2365 sleep(1); 2366 } 2367 2368 rc = read(sds[1], buf, 2); 2369 if (rc == -1) { 2370 test_fail("read"); 2371 exit(1); 2372 } 2373 2374 if (!(buf[0] == 'X' && buf[1] == '3')) { 2375 test_fail("Didn't read X3"); 2376 exit(1); 2377 } 2378 2379 exit(0); 2380 } else { 2381 2382 rc = write(sds[0], "MNX3", 4); 2383 if (rc == -1) { 2384 test_fail("write"); 2385 } 2386 2387 rc = read(sds[1], buf, 2); 2388 if (rc == -1) { 2389 test_fail("read"); 2390 } 2391 2392 if (!(buf[0] == 'M' && buf[1] == 'N')) { 2393 test_fail("Didn't read MN"); 2394 } 2395 2396 /* time to tell the client to start the test */ 2397 kill(pid, SIGUSR1); 2398 2399 do { 2400 rc = waitpid(pid, &status, 0); 2401 } while (rc == -1 && errno == EINTR); 2402 2403 /* we use the exit status to get its error count */ 2404 errct += WEXITSTATUS(status); 2405 } 2406 2407 return 0; 2408 } 2409 2410 int test_multiproc_write(void) 2411 { 2412 /* test that when we fork() a process with an open socket descriptor, 2413 * the descriptor in each process points to the same thing. 2414 */ 2415 2416 pid_t pid; 2417 int sds[2]; 2418 int rc, status; 2419 char buf[7]; 2420 2421 debug("entering test_multiproc_write()"); 2422 2423 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds); 2424 if (rc == -1) { 2425 test_fail("socketpair"); 2426 return 1; 2427 } 2428 2429 memset(buf, '\0', 7); 2430 2431 2432 /* the signal handler is only used by the client, but we have to 2433 * install it now. if we don't the server may signal the client 2434 * before the handler is installed. 2435 */ 2436 debug("installing signal handler"); 2437 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) { 2438 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed"); 2439 return 1; 2440 } 2441 2442 debug("signal handler installed"); 2443 2444 server_ready = 0; 2445 2446 pid = fork(); 2447 2448 if (pid == -1) { 2449 2450 test_fail("fork"); 2451 return 1; 2452 2453 } else if (pid == 0) { 2454 2455 while (server_ready == 0) { 2456 debug("waiting for SIGUSR1 from parent"); 2457 sleep(1); 2458 } 2459 2460 rc = write(sds[1], "IX3", 3); 2461 if (rc == -1) { 2462 test_fail("write"); 2463 exit(1); 2464 } 2465 2466 rc = read(sds[0], buf, 6); 2467 if (rc == -1) { 2468 test_fail("read"); 2469 exit(1); 2470 } 2471 2472 if (strcmp(buf, "MINIX3") != 0) { 2473 test_fail("didn't read MINIX3"); 2474 exit(1); 2475 } 2476 2477 exit(0); 2478 } else { 2479 2480 rc = write(sds[1], "MIN", 3); 2481 if (rc == -1) { 2482 test_fail("write"); 2483 } 2484 2485 /* time to tell the client to start the test */ 2486 kill(pid, SIGUSR1); 2487 2488 do { 2489 rc = waitpid(pid, &status, 0); 2490 } while (rc == -1 && errno == EINTR); 2491 2492 /* we use the exit status to get its error count */ 2493 errct += WEXITSTATUS(status); 2494 } 2495 2496 return 0; 2497 } 2498 2499 void test_fd_passing_child(int sd) 2500 { 2501 int fd, rc; 2502 char x = 'x'; 2503 struct msghdr msghdr; 2504 struct cmsghdr *cmsg; 2505 struct iovec iov; 2506 char buf[BUFSIZE]; 2507 2508 memset(buf, '\0', BUFSIZE); 2509 2510 fd = open(TEST_TXT_FILE, O_CREAT|O_TRUNC|O_RDWR); 2511 if (fd == -1) { 2512 test_fail("could not open test.txt"); 2513 } 2514 2515 msghdr.msg_name = NULL; 2516 msghdr.msg_namelen = 0; 2517 2518 iov.iov_base = &x; 2519 iov.iov_len = 1; 2520 msghdr.msg_iov = &iov; 2521 msghdr.msg_iovlen = 1; 2522 2523 msghdr.msg_control = buf; 2524 msghdr.msg_controllen = CMSG_SPACE(sizeof(int)); 2525 2526 msghdr.msg_flags = 0; 2527 2528 cmsg = CMSG_FIRSTHDR(&msghdr); 2529 cmsg->cmsg_len = CMSG_SPACE(sizeof(int)); 2530 cmsg->cmsg_level = SOL_SOCKET; 2531 cmsg->cmsg_type = SCM_RIGHTS; 2532 2533 ((int *) CMSG_DATA(cmsg))[0] = fd; 2534 2535 rc = sendmsg(sd, &msghdr, 0); 2536 if (rc == -1) { 2537 test_fail("could not send message"); 2538 } 2539 2540 memset(buf, '\0', BUFSIZE); 2541 rc = read(sd, buf, BUFSIZE); 2542 if (rc == -1) { 2543 test_fail("could not read from socket"); 2544 } 2545 2546 if (strcmp(buf, "done") != 0) { 2547 test_fail("we didn't read the right message"); 2548 } 2549 2550 memset(buf, '\0', BUFSIZE); 2551 rc = lseek(fd, 0, SEEK_SET); 2552 if (rc == -1) { 2553 test_fail("could not seek to start of test.txt"); 2554 } 2555 2556 rc = read(fd, buf, BUFSIZE); 2557 if (rc == -1) { 2558 test_fail("could not read from test.txt"); 2559 } 2560 2561 if (strcmp(buf, MSG) != 0) { 2562 test_fail("other process didn't write MSG to test.txt"); 2563 } 2564 2565 rc = close(fd); 2566 if (rc == -1) { 2567 test_fail("could not close test.txt"); 2568 } 2569 2570 rc = close(sd); 2571 if (rc == -1) { 2572 test_fail("could not close socket"); 2573 } 2574 2575 rc = unlink(TEST_TXT_FILE); 2576 if (rc == -1) { 2577 test_fail("could not unlink test.txt"); 2578 } 2579 2580 exit(errct); 2581 } 2582 2583 void test_fd_passing_parent(int sd) 2584 { 2585 int rc, fd; 2586 char x; 2587 struct msghdr msghdr; 2588 struct cmsghdr *cmsg; 2589 struct iovec iov; 2590 char buf[BUFSIZE]; 2591 2592 memset(buf, '\0', BUFSIZE); 2593 2594 msghdr.msg_name = NULL; 2595 msghdr.msg_namelen = 0; 2596 2597 iov.iov_base = &x; 2598 iov.iov_len = 1; 2599 msghdr.msg_iov = &iov; 2600 msghdr.msg_iovlen = 1; 2601 2602 msghdr.msg_iov = &iov; 2603 msghdr.msg_iovlen = 1; 2604 2605 msghdr.msg_control = buf; 2606 msghdr.msg_controllen = BUFSIZE; 2607 2608 msghdr.msg_flags = 0; 2609 2610 rc = recvmsg(sd, &msghdr, 0); 2611 if (rc == -1) { 2612 test_fail("could not recv message."); 2613 } 2614 2615 cmsg = CMSG_FIRSTHDR(&msghdr); 2616 fd = ((int *) CMSG_DATA(cmsg))[0]; 2617 2618 rc = write(fd, MSG, strlen(MSG)); 2619 if (rc != strlen(MSG)) { 2620 test_fail("could not write the full message to test.txt"); 2621 } 2622 2623 rc = close(fd); 2624 if (rc == -1) { 2625 test_fail("could not close test.txt"); 2626 } 2627 2628 memset(buf, '\0', BUFSIZE); 2629 strcpy(buf, "done"); 2630 rc = write(sd, buf, BUFSIZE); 2631 if (rc == -1) { 2632 test_fail("could not write to socket"); 2633 } 2634 2635 rc = close(sd); 2636 if (rc == -1) { 2637 test_fail("could not close socket"); 2638 } 2639 } 2640 2641 void test_permissions(void) { 2642 /* Test bind and connect for permission verification 2643 * 2644 * After creating a UDS socket we change user credentials. At that 2645 * point we should not be allowed to bind or connect to the UDS socket 2646 */ 2647 2648 pid_t pid; 2649 int sd, rc, status; 2650 struct sockaddr_un addr; 2651 2652 memset(&addr, '\0', sizeof(struct sockaddr_un)); 2653 addr.sun_family = AF_UNIX; 2654 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 2655 2656 UNLINK(TEST_SUN_PATH); 2657 2658 pid = fork(); 2659 if (pid < 0) test_fail("unable to fork"); 2660 else if (pid == 0) { 2661 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 2662 if (setuid(999) != 0) test_fail("unable to chance uid"); 2663 rc = bind(sd, (struct sockaddr *) &addr, 2664 sizeof(struct sockaddr_un)); 2665 if (rc != -1) { 2666 test_fail("bind() should not have worked"); 2667 } 2668 exit(errct); 2669 } else { 2670 rc = waitpid(pid, &status, 0); 2671 errct += WEXITSTATUS(status); 2672 } 2673 2674 /* the signal handler is only used by the client, but we have to 2675 * install it now. if we don't the server may signal the client 2676 * before the handler is installed. 2677 */ 2678 debug("installing signal handler"); 2679 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) { 2680 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed"); 2681 } 2682 2683 debug("signal handler installed"); 2684 2685 server_ready = 0; 2686 2687 pid = fork(); 2688 if (pid < 0) test_fail("unable to fork"); 2689 else if (pid == 0) { 2690 while (server_ready == 0) { 2691 debug("[client] waiting for the server to signal"); 2692 sleep(1); 2693 } 2694 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 2695 if (setuid(999) != 0) test_fail("unable to chance uid"); 2696 rc = connect(sd, (struct sockaddr *) &addr, 2697 sizeof(struct sockaddr_un)); 2698 if (rc != -1) 2699 test_fail("connect should not have worked"); 2700 exit(errct); 2701 } else { 2702 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 2703 rc = bind(sd, (struct sockaddr *) &addr, 2704 sizeof(struct sockaddr_un)); 2705 if (rc == -1) { 2706 test_fail("bind() should have worked"); 2707 } 2708 2709 rc = listen(sd, 8); 2710 if (rc == -1) { 2711 test_fail("listen(sd, 8) should have worked"); 2712 } 2713 kill(pid, SIGUSR1); 2714 sleep(1); 2715 CLOSE(sd); 2716 2717 rc = waitpid(pid, &status, 0); 2718 errct += WEXITSTATUS(status); 2719 } 2720 2721 UNLINK(TEST_SUN_PATH); 2722 } 2723 2724 void test_fd_passing(void) { 2725 int status; 2726 int sv[2]; 2727 pid_t pid; 2728 int rc; 2729 2730 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sv); 2731 if (rc == -1) { 2732 test_fail("socketpair failed"); 2733 } 2734 2735 pid = fork(); 2736 if (pid == -1) { 2737 test_fail("fork() failed"); 2738 2739 rc = close(sv[0]); 2740 if (rc == -1) { 2741 test_fail("could not close sv[0]"); 2742 } 2743 2744 rc = close(sv[1]); 2745 if (rc == -1) { 2746 test_fail("could not close sv[1]"); 2747 } 2748 2749 exit(0); 2750 } else if (pid == 0) { 2751 rc = close(sv[0]); 2752 if (rc == -1) { 2753 test_fail("could not close sv[0]"); 2754 } 2755 2756 test_fd_passing_child(sv[1]); 2757 test_fail("should never get here"); 2758 exit(1); 2759 } else { 2760 rc = close(sv[1]); 2761 if (rc == -1) { 2762 test_fail("could not close sv[1]"); 2763 } 2764 2765 test_fd_passing_parent(sv[0]); 2766 2767 /* wait for client to exit */ 2768 do { 2769 errno = 0; 2770 rc = waitpid(pid, &status, 0); 2771 } while (rc == -1 && errno == EINTR); 2772 2773 /* we use the exit status to get its error count */ 2774 errct += WEXITSTATUS(status); 2775 } 2776 } 2777 2778 void test_select() 2779 { 2780 int i, nfds = -1; 2781 int socks[2]; 2782 fd_set readfds, writefds; 2783 struct timeval tv; 2784 int res = 0; 2785 char buf[1]; 2786 2787 FD_ZERO(&readfds); 2788 FD_ZERO(&writefds); 2789 2790 tv.tv_sec = 2; 2791 tv.tv_usec = 0; /* 2 sec time out */ 2792 2793 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) { 2794 test_fail("Can't open socket pair."); 2795 } 2796 FD_SET(socks[0], &readfds); 2797 nfds = socks[0] + 1; 2798 2799 /* Close the write end of the socket to generate EOF on read end */ 2800 if ((res = shutdown(socks[1], SHUT_WR)) != 0) { 2801 test_fail("shutdown failed\n"); 2802 } 2803 2804 res = select(nfds, &readfds, NULL, NULL, &tv); 2805 if (res != 1) { 2806 test_fail("select should've returned 1 ready fd\n"); 2807 } 2808 if (!(FD_ISSET(socks[0], &readfds))) { 2809 test_fail("The server didn't respond within 2 seconds"); 2810 } 2811 /* Now try to read from empty, closed pipe */ 2812 if (read(socks[0], buf, sizeof(buf)) != 0) { 2813 test_fail("reading from empty, closed pipe should return EOF"); 2814 } 2815 2816 close(socks[0]); 2817 2818 /* Try again the other way around: create a socketpair, close the 2819 * read end, and try to write. This should cause an EPIPE */ 2820 2821 tv.tv_sec = 2; 2822 tv.tv_usec = 0; /* 2 sec time out */ 2823 2824 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) { 2825 test_fail("Can't open socket pair."); 2826 } 2827 FD_SET(socks[1], &writefds); 2828 nfds = socks[1] + 1; 2829 2830 /* kill the read end of the socket to generate EPIPE on write end */ 2831 if ((res = shutdown(socks[0], SHUT_RD)) != 0) { 2832 test_fail("shutdown failed\n"); 2833 } 2834 2835 res = select(nfds, NULL, &writefds, NULL, &tv); 2836 if (res != 1) { 2837 test_fail("select should've returned 1 ready fd\n"); 2838 } 2839 if (!(FD_ISSET(socks[1], &writefds))) { 2840 test_fail("The server didn't respond within 2 seconds"); 2841 } 2842 2843 /* Now try to write to closed pipe */ 2844 errno = 0; 2845 if ((res = write(socks[1], buf, sizeof(buf))) != -1) { 2846 printf("write res = %d\n", res); 2847 test_fail("writing to empty, closed pipe should fail"); 2848 } 2849 if (errno != EPIPE) { 2850 printf("errno = %d\n", errno); 2851 test_fail("writing to closed pipe should return EPIPE\n"); 2852 } 2853 2854 close(socks[1]); 2855 } 2856 2857 void test_select_close(void) 2858 { 2859 int res, socks[2]; 2860 fd_set readfds; 2861 struct timeval tv; 2862 2863 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) { 2864 test_fail("Can't open socket pair."); 2865 } 2866 2867 switch (fork()) { 2868 case 0: 2869 sleep(1); 2870 2871 exit(0); 2872 case -1: 2873 test_fail("Can't fork."); 2874 default: 2875 break; 2876 } 2877 2878 close(socks[1]); 2879 2880 FD_ZERO(&readfds); 2881 FD_SET(socks[0], &readfds); 2882 tv.tv_sec = 2; 2883 tv.tv_usec = 0; /* 2 sec time out */ 2884 2885 res = select(socks[0] + 1, &readfds, NULL, NULL, &tv); 2886 if (res != 1) { 2887 test_fail("select should've returned 1 ready fd\n"); 2888 } 2889 if (!(FD_ISSET(socks[0], &readfds))) { 2890 test_fail("The server didn't respond within 2 seconds"); 2891 } 2892 2893 wait(NULL); 2894 2895 close(socks[0]); 2896 } 2897 2898 void test_fchmod() 2899 { 2900 int socks[2]; 2901 struct stat st1, st2; 2902 2903 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) { 2904 test_fail("Can't open socket pair."); 2905 } 2906 2907 if (fstat(socks[0], &st1) < 0 || fstat(socks[1], &st2) < 0) { 2908 test_fail("fstat failed."); 2909 } 2910 2911 if ((st1.st_mode & (S_IRUSR|S_IWUSR)) == S_IRUSR && 2912 (st2.st_mode & (S_IRUSR|S_IWUSR)) == S_IWUSR) { 2913 test_fail("fstat failed."); 2914 } 2915 2916 if (fchmod(socks[0], S_IRUSR) < 0 || 2917 fstat(socks[0], &st1) < 0 || 2918 (st1.st_mode & (S_IRUSR|S_IWUSR)) != S_IRUSR) { 2919 test_fail("fchmod/fstat mode set/check failed (1)."); 2920 } 2921 2922 if (fchmod(socks[1], S_IWUSR) < 0 || fstat(socks[1], &st2) < 0 || 2923 (st2.st_mode & (S_IRUSR|S_IWUSR)) != S_IWUSR) { 2924 test_fail("fchmod/fstat mode set/check failed (2)."); 2925 } 2926 2927 close(socks[0]); 2928 close(socks[1]); 2929 } 2930 2931 static void 2932 check_select(int sd, int rd, int wr, int block) 2933 { 2934 fd_set read_set, write_set; 2935 struct timeval tv; 2936 2937 FD_ZERO(&read_set); 2938 if (rd != -1) 2939 FD_SET(sd, &read_set); 2940 2941 FD_ZERO(&write_set); 2942 if (wr != -1) 2943 FD_SET(sd, &write_set); 2944 2945 tv.tv_sec = block ? 2 : 0; 2946 tv.tv_usec = 0; 2947 2948 if (select(sd + 1, &read_set, &write_set, NULL, &tv) < 0) 2949 test_fail("select() failed unexpectedly"); 2950 2951 if (rd != -1 && !!FD_ISSET(sd, &read_set) != rd) 2952 test_fail("select() mismatch on read operation"); 2953 2954 if (wr != -1 && !!FD_ISSET(sd, &write_set) != wr) 2955 test_fail("select() mismatch on write operation"); 2956 } 2957 2958 /* 2959 * Verify that: 2960 * - a nonblocking connecting socket for which there is no accepter, will 2961 * return EINPROGRESS and complete in the background later; 2962 * - a nonblocking listening socket will return EAGAIN on accept; 2963 * - connecting a connecting socket yields EALREADY; 2964 * - connecting a connected socket yields EISCONN; 2965 * - selecting for read and write on a connecting socket will only satisfy the 2966 * write only once it is connected; 2967 * - doing a nonblocking write on a connecting socket yields EAGAIN; 2968 * - doing a nonblocking read on a connected socket with no pending data yields 2969 * EAGAIN. 2970 */ 2971 static void 2972 test_nonblock(void) 2973 { 2974 char buf[BUFSIZE]; 2975 socklen_t len; 2976 int server_sd, client_sd; 2977 struct sockaddr_un server_addr, client_addr, addr; 2978 int status; 2979 2980 memset(buf, 0, sizeof(buf)); 2981 2982 memset(&server_addr, 0, sizeof(server_addr)); 2983 strlcpy(server_addr.sun_path, TEST_SUN_PATH, 2984 sizeof(server_addr.sun_path)); 2985 server_addr.sun_family = AF_UNIX; 2986 2987 client_addr = server_addr; 2988 2989 SOCKET(server_sd, PF_UNIX, SOCK_STREAM, 0); 2990 2991 if (bind(server_sd, (struct sockaddr *) &server_addr, 2992 sizeof(struct sockaddr_un)) == -1) 2993 test_fail("bind() should have worked"); 2994 2995 if (listen(server_sd, 8) == -1) 2996 test_fail("listen() should have worked"); 2997 2998 fcntl(server_sd, F_SETFL, fcntl(server_sd, F_GETFL) | O_NONBLOCK); 2999 3000 check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3001 3002 len = sizeof(addr); 3003 if (accept(server_sd, (struct sockaddr *) &addr, &len) != -1 || 3004 errno != EAGAIN) 3005 test_fail("accept() should have yielded EAGAIN"); 3006 3007 SOCKET(client_sd, PF_UNIX, SOCK_STREAM, 0); 3008 3009 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK); 3010 3011 if (connect(client_sd, (struct sockaddr *) &client_addr, 3012 sizeof(struct sockaddr_un)) != -1 || errno != EINPROGRESS) 3013 test_fail("connect() should have yielded EINPROGRESS"); 3014 3015 check_select(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/); 3016 3017 if (connect(client_sd, (struct sockaddr *) &client_addr, 3018 sizeof(struct sockaddr_un)) != -1 || errno != EALREADY) 3019 test_fail("connect() should have yielded EALREADY"); 3020 3021 if (recv(client_sd, buf, sizeof(buf), 0) != -1 || errno != EAGAIN) 3022 test_fail("recv() should have yielded EAGAIN"); 3023 3024 /* This may be an implementation aspect, or even plain wrong (?). */ 3025 if (send(client_sd, buf, sizeof(buf), 0) != -1 || errno != EAGAIN) 3026 test_fail("send() should have yielded EAGAIN"); 3027 3028 switch (fork()) { 3029 case 0: 3030 close(client_sd); 3031 3032 check_select(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); 3033 3034 len = sizeof(addr); 3035 client_sd = accept(server_sd, (struct sockaddr *) &addr, &len); 3036 if (client_sd == -1) 3037 test_fail("accept() should have succeeded"); 3038 3039 check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3040 3041 close(server_sd); 3042 3043 /* Let the socket become writable in the parent process. */ 3044 sleep(1); 3045 3046 if (write(client_sd, buf, 1) != 1) 3047 test_fail("write() should have succeeded"); 3048 3049 /* Wait for the client side to close. */ 3050 check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3051 check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/); 3052 check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); 3053 3054 exit(errct); 3055 case -1: 3056 test_fail("can't fork"); 3057 default: 3058 break; 3059 } 3060 3061 close(server_sd); 3062 3063 check_select(client_sd, 0 /*read*/, 1 /*write*/, 1 /*block*/); 3064 check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3065 3066 if (connect(client_sd, (struct sockaddr *) &client_addr, 3067 sizeof(struct sockaddr_un)) != -1 || errno != EISCONN) 3068 test_fail("connect() should have yielded EISCONN"); 3069 3070 check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/); 3071 check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); 3072 3073 if (read(client_sd, buf, 1) != 1) 3074 test_fail("read() should have succeeded"); 3075 3076 check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3077 3078 if (read(client_sd, buf, 1) != -1 || errno != EAGAIN) 3079 test_fail("read() should have yielded EAGAIN"); 3080 3081 /* Let the child process block on the select waiting for the close. */ 3082 sleep(1); 3083 3084 close(client_sd); 3085 3086 if (wait(&status) <= 0) 3087 test_fail("wait() should have succeeded"); 3088 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 3089 test_fail("child process failed the test"); 3090 3091 UNLINK(TEST_SUN_PATH); 3092 } 3093 3094 /* 3095 * Verify that a nonblocking connect for which there is an accepter, succeeds 3096 * immediately. A pretty lame test, only here for completeness. 3097 */ 3098 static void 3099 test_connect_nb(void) 3100 { 3101 socklen_t len; 3102 int server_sd, client_sd; 3103 struct sockaddr_un server_addr, client_addr, addr; 3104 int status; 3105 3106 memset(&server_addr, 0, sizeof(server_addr)); 3107 strlcpy(server_addr.sun_path, TEST_SUN_PATH, 3108 sizeof(server_addr.sun_path)); 3109 server_addr.sun_family = AF_UNIX; 3110 3111 client_addr = server_addr; 3112 3113 SOCKET(server_sd, PF_UNIX, SOCK_STREAM, 0); 3114 3115 if (bind(server_sd, (struct sockaddr *) &server_addr, 3116 sizeof(struct sockaddr_un)) == -1) 3117 test_fail("bind() should have worked"); 3118 3119 if (listen(server_sd, 8) == -1) 3120 test_fail("listen() should have worked"); 3121 3122 switch (fork()) { 3123 case 0: 3124 len = sizeof(addr); 3125 if (accept(server_sd, (struct sockaddr *) &addr, &len) == -1) 3126 test_fail("accept() should have succeeded"); 3127 3128 exit(errct); 3129 case -1: 3130 test_fail("can't fork"); 3131 default: 3132 break; 3133 } 3134 3135 close(server_sd); 3136 3137 sleep(1); 3138 3139 SOCKET(client_sd, PF_UNIX, SOCK_STREAM, 0); 3140 3141 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK); 3142 3143 if (connect(client_sd, (struct sockaddr *) &client_addr, 3144 sizeof(struct sockaddr_un)) != 0) 3145 test_fail("connect() should have succeeded"); 3146 3147 close(client_sd); 3148 3149 if (wait(&status) <= 0) 3150 test_fail("wait() should have succeeded"); 3151 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 3152 test_fail("child process failed the test"); 3153 3154 UNLINK(TEST_SUN_PATH); 3155 } 3156 3157 static void 3158 dummy_handler(int sig) 3159 { 3160 /* Nothing. */ 3161 } 3162 3163 /* 3164 * Verify that: 3165 * - interrupting a blocking connect will return EINTR but complete in the 3166 * background later; 3167 * - doing a blocking write on an asynchronously connecting socket succeeds 3168 * once the socket is connected. 3169 * - doing a nonblocking write on a connected socket with lots of pending data 3170 * yields EAGAIN. 3171 */ 3172 static void 3173 test_intr(void) 3174 { 3175 struct sigaction act, oact; 3176 char buf[BUFSIZE]; 3177 socklen_t len; 3178 int server_sd, client_sd; 3179 struct sockaddr_un server_addr, client_addr, addr; 3180 int r, status; 3181 3182 memset(buf, 0, sizeof(buf)); 3183 3184 memset(&server_addr, 0, sizeof(server_addr)); 3185 strlcpy(server_addr.sun_path, TEST_SUN_PATH, 3186 sizeof(server_addr.sun_path)); 3187 server_addr.sun_family = AF_UNIX; 3188 3189 client_addr = server_addr; 3190 3191 SOCKET(server_sd, PF_UNIX, SOCK_STREAM, 0); 3192 3193 if (bind(server_sd, (struct sockaddr *) &server_addr, 3194 sizeof(struct sockaddr_un)) == -1) 3195 test_fail("bind() should have worked"); 3196 3197 if (listen(server_sd, 8) == -1) 3198 test_fail("listen() should have worked"); 3199 3200 SOCKET(client_sd, PF_UNIX, SOCK_STREAM, 0); 3201 3202 memset(&act, 0, sizeof(act)); 3203 act.sa_handler = dummy_handler; 3204 if (sigaction(SIGALRM, &act, &oact) == -1) 3205 test_fail("sigaction() should have succeeded"); 3206 3207 alarm(1); 3208 3209 if (connect(client_sd, (struct sockaddr *) &client_addr, 3210 sizeof(struct sockaddr_un)) != -1 || errno != EINTR) 3211 test_fail("connect() should have yielded EINTR"); 3212 3213 check_select(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/); 3214 3215 switch (fork()) { 3216 case 0: 3217 close(client_sd); 3218 3219 check_select(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); 3220 3221 len = sizeof(addr); 3222 client_sd = accept(server_sd, (struct sockaddr *) &addr, &len); 3223 if (client_sd == -1) 3224 test_fail("accept() should have succeeded"); 3225 3226 check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3227 3228 close(server_sd); 3229 3230 check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/); 3231 check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); 3232 3233 if (recv(client_sd, buf, sizeof(buf), 0) != sizeof(buf)) 3234 test_fail("recv() should have yielded bytes"); 3235 3236 /* No partial transfers should be happening. */ 3237 check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3238 3239 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | 3240 O_NONBLOCK); 3241 3242 /* We can only test nonblocking writes by filling the pipe. */ 3243 while ((r = write(client_sd, buf, sizeof(buf))) > 0); 3244 3245 if (r != -1 || errno != EAGAIN) 3246 test_fail("write() should have yielded EAGAIN"); 3247 3248 check_select(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/); 3249 3250 if (write(client_sd, buf, 1) != -1 || errno != EAGAIN) 3251 test_fail("write() should have yielded EAGAIN"); 3252 3253 exit(errct); 3254 case -1: 3255 test_fail("can't fork"); 3256 default: 3257 break; 3258 } 3259 3260 close(server_sd); 3261 3262 if (send(client_sd, buf, sizeof(buf), 0) != sizeof(buf)) 3263 test_fail("send() should have succeded"); 3264 3265 check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3266 3267 if (wait(&status) <= 0) 3268 test_fail("wait() should have succeeded"); 3269 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 3270 test_fail("child process failed the test"); 3271 3272 check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); 3273 3274 close(client_sd); 3275 3276 sigaction(SIGALRM, &oact, NULL); 3277 3278 UNLINK(TEST_SUN_PATH); 3279 } 3280 3281 /* 3282 * Verify that closing a connecting socket before it is accepted will result in 3283 * no activity on the accepting side later. 3284 */ 3285 static void 3286 test_connect_close(void) 3287 { 3288 int server_sd, client_sd; 3289 struct sockaddr_un server_addr, client_addr; 3290 socklen_t len; 3291 3292 memset(&server_addr, 0, sizeof(server_addr)); 3293 strlcpy(server_addr.sun_path, TEST_SUN_PATH, 3294 sizeof(server_addr.sun_path)); 3295 server_addr.sun_family = AF_UNIX; 3296 3297 client_addr = server_addr; 3298 3299 SOCKET(server_sd, PF_UNIX, SOCK_STREAM, 0); 3300 3301 if (bind(server_sd, (struct sockaddr *) &server_addr, 3302 sizeof(struct sockaddr_un)) == -1) 3303 test_fail("bind() should have worked"); 3304 3305 if (listen(server_sd, 8) == -1) 3306 test_fail("listen() should have worked"); 3307 3308 fcntl(server_sd, F_SETFL, fcntl(server_sd, F_GETFL) | O_NONBLOCK); 3309 3310 check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3311 3312 SOCKET(client_sd, PF_UNIX, SOCK_STREAM, 0); 3313 3314 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK); 3315 3316 if (connect(client_sd, (struct sockaddr *) &client_addr, 3317 sizeof(struct sockaddr_un)) != -1 || errno != EINPROGRESS) 3318 test_fail("connect() should have yielded EINPROGRESS"); 3319 3320 check_select(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/); 3321 check_select(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); 3322 3323 close(client_sd); 3324 3325 check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/); 3326 3327 len = sizeof(client_addr); 3328 if (accept(server_sd, (struct sockaddr *) &client_addr, &len) != -1 || 3329 errno != EAGAIN) 3330 test_fail("accept() should have yielded EAGAIN"); 3331 3332 close(server_sd); 3333 3334 UNLINK(TEST_SUN_PATH); 3335 } 3336 3337 /* 3338 * Verify that closing a listening socket will cause a blocking connect to fail 3339 * with ECONNRESET, and that a subsequent write will yield EPIPE. 3340 */ 3341 static void 3342 test_listen_close(void) 3343 { 3344 socklen_t len; 3345 int server_sd, client_sd; 3346 struct sockaddr_un server_addr, client_addr, addr; 3347 int status; 3348 char byte; 3349 3350 memset(&server_addr, 0, sizeof(server_addr)); 3351 strlcpy(server_addr.sun_path, TEST_SUN_PATH, 3352 sizeof(server_addr.sun_path)); 3353 server_addr.sun_family = AF_UNIX; 3354 3355 client_addr = server_addr; 3356 3357 SOCKET(server_sd, PF_UNIX, SOCK_STREAM, 0); 3358 3359 if (bind(server_sd, (struct sockaddr *) &server_addr, 3360 sizeof(struct sockaddr_un)) == -1) 3361 test_fail("bind() should have worked"); 3362 3363 if (listen(server_sd, 8) == -1) 3364 test_fail("listen() should have worked"); 3365 3366 switch (fork()) { 3367 case 0: 3368 sleep(1); 3369 3370 exit(0); 3371 case -1: 3372 test_fail("can't fork"); 3373 default: 3374 break; 3375 } 3376 3377 close(server_sd); 3378 3379 SOCKET(client_sd, PF_UNIX, SOCK_STREAM, 0); 3380 3381 byte = 0; 3382 if (write(client_sd, &byte, 1) != -1 || errno != ENOTCONN) 3383 /* Yes, you fucked up the fix for the FIXME below. */ 3384 test_fail("write() should have yielded ENOTCONN"); 3385 3386 if (connect(client_sd, (struct sockaddr *) &client_addr, 3387 sizeof(struct sockaddr_un)) != -1 || errno != ECONNRESET) 3388 test_fail("connect() should have yielded ECONNRESET"); 3389 3390 /* 3391 * FIXME: currently UDS cannot distinguish between sockets that have 3392 * not yet been connected, and sockets that have been disconnected. 3393 * Thus, we get the same error for both: ENOTCONN instead of EPIPE. 3394 */ 3395 #if 0 3396 if (write(client_sd, &byte, 1) != -1 || errno != EPIPE) 3397 test_fail("write() should have yielded EPIPE"); 3398 #endif 3399 3400 close(client_sd); 3401 3402 if (wait(&status) <= 0) 3403 test_fail("wait() should have succeeded"); 3404 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 3405 test_fail("child process failed the test"); 3406 3407 UNLINK(TEST_SUN_PATH); 3408 } 3409 3410 /* 3411 * Verify that closing a listening socket will cause a nonblocking connect to 3412 * result in the socket becoming readable and writable, and yielding ECONNRESET 3413 * and EPIPE on the next two writes, respectively. 3414 */ 3415 static void 3416 test_listen_close_nb(void) 3417 { 3418 socklen_t len; 3419 int server_sd, client_sd; 3420 struct sockaddr_un server_addr, client_addr, addr; 3421 int status; 3422 char byte; 3423 3424 memset(&server_addr, 0, sizeof(server_addr)); 3425 strlcpy(server_addr.sun_path, TEST_SUN_PATH, 3426 sizeof(server_addr.sun_path)); 3427 server_addr.sun_family = AF_UNIX; 3428 3429 client_addr = server_addr; 3430 3431 SOCKET(server_sd, PF_UNIX, SOCK_STREAM, 0); 3432 3433 if (bind(server_sd, (struct sockaddr *) &server_addr, 3434 sizeof(struct sockaddr_un)) == -1) 3435 test_fail("bind() should have worked"); 3436 3437 if (listen(server_sd, 8) == -1) 3438 test_fail("listen() should have worked"); 3439 3440 switch (fork()) { 3441 case 0: 3442 sleep(1); 3443 3444 exit(0); 3445 case -1: 3446 test_fail("can't fork"); 3447 default: 3448 break; 3449 } 3450 3451 close(server_sd); 3452 3453 SOCKET(client_sd, PF_UNIX, SOCK_STREAM, 0); 3454 3455 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK); 3456 3457 if (connect(client_sd, (struct sockaddr *) &client_addr, 3458 sizeof(struct sockaddr_un)) != -1 || errno != EINPROGRESS) 3459 test_fail("connect() should have yielded EINPROGRESS"); 3460 3461 check_select(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/); 3462 check_select(client_sd, 1 /*read*/, 1 /*write*/, 1 /*block*/); 3463 3464 byte = 0; 3465 if (write(client_sd, &byte, 1) != -1 || errno != ECONNRESET) 3466 test_fail("write() should have yielded ECONNRESET"); 3467 3468 /* 3469 * FIXME: currently UDS cannot distinguish between sockets that have 3470 * not yet been connected, and sockets that have been disconnected. 3471 * Thus, we get the same error for both: ENOTCONN instead of EPIPE. 3472 */ 3473 #if 0 3474 if (write(client_sd, &byte, 1) != -1 || errno != EPIPE) 3475 test_fail("write() should have yielded EPIPE"); 3476 #endif 3477 3478 check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/); 3479 3480 close(client_sd); 3481 3482 if (wait(&status) <= 0) 3483 test_fail("wait() should have succeeded"); 3484 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 3485 test_fail("child process failed the test"); 3486 3487 UNLINK(TEST_SUN_PATH); 3488 } 3489 3490 int main(int argc, char *argv[]) 3491 { 3492 int i; 3493 3494 debug("entering main()"); 3495 3496 start(56); 3497 3498 test_socket(); 3499 test_bind(); 3500 test_listen(); 3501 test_getsockname(); 3502 test_header(); 3503 test_shutdown(); 3504 test_close(); 3505 test_permissions(); 3506 test_dup(); 3507 test_dup2(); 3508 test_socketpair(); 3509 test_shutdown(); 3510 test_read(); 3511 test_write(); 3512 test_sockopts(); 3513 test_ucred(); 3514 test_xfer(); 3515 3516 for (i = 0; i < 3; i++) { 3517 test_simple_client_server(types[i]); 3518 if (types[i] != SOCK_DGRAM) test_vectorio(types[i]); 3519 if (types[i] != SOCK_DGRAM) test_msg(types[i]); 3520 } 3521 test_abort_client_server(1); 3522 test_abort_client_server(2); 3523 test_msg_dgram(); 3524 test_connect(); 3525 test_multiproc_read(); 3526 test_multiproc_write(); 3527 test_scm_credentials(); 3528 test_fd_passing(); 3529 test_select(); 3530 test_select_close(); 3531 test_fchmod(); 3532 test_nonblock(); 3533 test_connect_nb(); 3534 test_intr(); 3535 test_connect_close(); 3536 test_listen_close(); 3537 test_listen_close_nb(); 3538 3539 quit(); 3540 3541 return -1; /* we should never get here */ 3542 } 3543