PageRenderTime 130ms CodeModel.GetById 20ms app.highlight 97ms RepoModel.GetById 1ms app.codeStats 0ms

/minix/tests/common-socket.c

http://www.minix3.org/
C | 2122 lines | 1541 code | 458 blank | 123 comment | 544 complexity | 50a270436d585eaf1c891599c09db552 MD5 | raw file
   1#include <assert.h>
   2#include <ctype.h>
   3#include <errno.h>
   4#include <fcntl.h>
   5#include <signal.h>
   6#include <stdio.h>
   7#include <stdlib.h>
   8#include <string.h>
   9#include <sys/socket.h>
  10#include <sys/stat.h>
  11#include <sys/wait.h>
  12#include <time.h>
  13#include <unistd.h>
  14
  15#include "common.h"
  16#include "common-socket.h"
  17
  18#define ISO8601_FORMAT "%Y-%m-%dT%H:%M:%S"
  19
  20/* timestamps for debug and error logs */
  21static char *get_timestamp(void)
  22{
  23	struct tm *tm;
  24	time_t t;
  25	size_t len;
  26	char *s;
  27
  28	len = sizeof(char) * 32;
  29
  30	t = time(NULL);
  31	if (t == -1) {
  32		return NULL;
  33	}
  34	tm = gmtime(&t);
  35	if (tm == NULL) {
  36		return NULL;
  37	}
  38
  39	s = (char *) malloc(len);
  40	if (!s) {
  41		perror("malloc");
  42		return NULL;
  43	}
  44	memset(s, '\0', len);
  45
  46	strftime(s, len - 1, ISO8601_FORMAT, tm);
  47	return s;
  48}
  49
  50void test_fail_fl(char *msg, char *file, int line)
  51{
  52	char *timestamp;
  53	timestamp = get_timestamp();
  54	if (errct == 0) fprintf(stderr, "\n");
  55	fprintf(stderr, "[ERROR][%s] (%s Line %d) %s [pid=%d:errno=%d:%s]\n",
  56			timestamp, file, line, msg, getpid(),
  57					errno, strerror(errno));
  58	fflush(stderr);
  59	if (timestamp != NULL) {
  60		free(timestamp);
  61		timestamp = NULL;
  62	}
  63	e(7);
  64}
  65
  66#if DEBUG == 1
  67void debug_fl(char *msg, char *file, int line)
  68{
  69	char *timestamp;
  70	timestamp = get_timestamp();
  71	fprintf(stdout,"[DEBUG][%s] (%s:%d) %s [pid=%d]\n",
  72		timestamp, __FILE__, __LINE__, msg, getpid());
  73	fflush(stdout);
  74	if (timestamp != NULL) {
  75		free(timestamp);
  76		timestamp = NULL;
  77	}
  78}
  79#endif
  80
  81void test_socket(const struct socket_test_info *info)
  82{
  83	struct stat statbuf, statbuf2;
  84	int sd, sd2;
  85	int rc;
  86	int i;
  87
  88	debug("entering test_socket()");
  89
  90	debug("Test socket() with an unsupported address family");
  91
  92	errno = 0;
  93	sd = socket(-1, info->type, 0);
  94	if (!(sd == -1 && errno == EAFNOSUPPORT)) {
  95		test_fail("socket");
  96		if (sd != -1) {
  97			CLOSE(sd);
  98		}
  99	}
 100
 101	debug("Test socket() with all available FDs open by this process");
 102
 103	for (i = 3; i < getdtablesize(); i++) {
 104		rc = open("/dev/null", O_RDONLY);
 105		if (rc == -1) {
 106			test_fail("we couldn't open /dev/null for read");
 107		}
 108	}
 109
 110	errno = 0;
 111	sd = socket(info->domain, info->type, 0);
 112	if (!(sd == -1 && errno == EMFILE)) {
 113		test_fail("socket() call with all fds open should fail");
 114		if (sd != -1) {
 115			CLOSE(sd);
 116		}
 117	}
 118
 119	for (i = 3; i < getdtablesize(); i++) {
 120		CLOSE(i);
 121	}
 122
 123	debug("Test socket() with an mismatched protocol");
 124
 125	errno = 0;
 126	sd = socket(info->domain, info->type, 4);
 127	if (!(sd == -1 && errno == EPROTONOSUPPORT)) {
 128		test_fail("socket() should fail with errno = EPROTONOSUPPORT");
 129		if (sd != -1) {
 130			CLOSE(sd);
 131		}
 132	}
 133
 134	debug("Test socket() success");
 135
 136	/*
 137	 * open 2 sockets at once and *then* close them.
 138	 * This will test that /dev/uds is cloning properly.
 139	 */
 140
 141	SOCKET(sd, info->domain, info->type, 0);
 142	SOCKET(sd2, info->domain, info->type, 0);
 143
 144	rc = fstat(sd, &statbuf);
 145	if (rc == -1) {
 146		test_fail("fstat failed on sd");
 147	}
 148
 149	rc = fstat(sd2, &statbuf2);
 150	if (rc == -1) {
 151		test_fail("fstat failed on sd2");
 152	}
 153
 154
 155	if (statbuf.st_dev == statbuf2.st_dev) {
 156		test_fail("/dev/uds isn't being cloned");
 157	}
 158
 159	CLOSE(sd2);
 160	CLOSE(sd);
 161
 162	debug("leaving test_socket()");
 163}
 164
 165void test_getsockname(const struct socket_test_info *info)
 166{
 167	int sd;
 168	int rc;
 169	struct sockaddr_storage sock_addr;
 170	socklen_t sock_addr_len;
 171
 172	SOCKET(sd, info->domain, info->type, 0);
 173	rc = bind(sd, info->serveraddr, info->serveraddrlen);
 174	if (rc == -1) {
 175		test_fail("bind() should have worked");
 176	}
 177
 178	debug("Test getsockname() success");
 179
 180	memset(&sock_addr, '\0', sizeof(sock_addr));
 181	sock_addr_len = sizeof(sock_addr);
 182
 183	rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len);
 184	if (rc == -1) {
 185		test_fail("getsockname() should have worked");
 186	}
 187
 188	info->callback_check_sockaddr((struct sockaddr *) &sock_addr,
 189		sock_addr_len, "getsockname", 1);
 190
 191	CLOSE(sd);
 192}
 193
 194void test_bind(const struct socket_test_info *info)
 195{
 196	struct sockaddr_storage sock_addr;
 197	socklen_t sock_addr_len;
 198	int sd;
 199	int sd2;
 200	int rc;
 201
 202	debug("entering test_bind()");
 203	info->callback_cleanup();
 204
 205	debug("Test bind() success");
 206
 207	SOCKET(sd, info->domain, info->type, 0);
 208	rc = bind(sd, info->serveraddr, info->serveraddrlen);
 209	if (rc == -1) {
 210		test_fail("bind() should have worked");
 211	}
 212
 213	debug("Test getsockname() success");
 214
 215	memset(&sock_addr, '\0', sizeof(sock_addr));
 216	sock_addr_len = sizeof(sock_addr);
 217
 218	rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len);
 219	if (rc == -1) {
 220		test_fail("getsockname() should have worked");
 221	}
 222
 223	info->callback_check_sockaddr((struct sockaddr *) &sock_addr,
 224		sock_addr_len, "getsockname", 1);
 225
 226	debug("Test bind() with a address that has already been bind()'d");
 227
 228	SOCKET(sd2, info->domain, info->type, 0);
 229	errno = 0;
 230	rc = bind(sd2, info->serveraddr, info->serveraddrlen);
 231	if (!((rc == -1) && (errno == EADDRINUSE)) &&
 232		!info->bug_bind_in_use) {
 233		test_fail("bind() should have failed with EADDRINUSE");
 234	}
 235	CLOSE(sd2);
 236	CLOSE(sd);
 237	info->callback_cleanup();
 238
 239	if (!info->bug_bind_null) {
 240		debug("Test bind() with a NULL address");
 241
 242		SOCKET(sd, info->domain, info->type, 0);
 243		errno = 0;
 244		rc = bind(sd, (struct sockaddr *) NULL,
 245			sizeof(struct sockaddr_storage));
 246		if (!((rc == -1) && (errno == EFAULT))) {
 247			test_fail("bind() should have failed with EFAULT");
 248		}
 249		CLOSE(sd);
 250	}
 251
 252	debug("leaving test_bind()");
 253}
 254
 255void test_listen(const struct socket_test_info *info)
 256{
 257	int rc;
 258
 259	debug("entering test_listen()");
 260
 261	debug("Test listen() with a bad file descriptor");
 262
 263	errno = 0;
 264	rc = listen(-1, 0);
 265	if (!(rc == -1 && errno == EBADF)) {
 266		test_fail("listen(-1, 0) should have failed");
 267	}
 268
 269	debug("Test listen() with a non-socket file descriptor");
 270
 271	errno = 0;
 272	rc = listen(0, 0);
 273	/* Test on errno disabled here: there's currently no telling what this
 274	 * will return. POSIX says it should be ENOTSOCK, MINIX3 libc returns
 275	 * ENOSYS, and we used to test for ENOTTY here..
 276	 */
 277	if (!(rc == -1)) {
 278		test_fail("listen(0, 0) should have failed");
 279	}
 280
 281	debug("leaving test_listen()");
 282}
 283
 284void test_shutdown(const struct socket_test_info *info)
 285{
 286	int how[3] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
 287	int sd;
 288	int rc;
 289	int i;
 290
 291	debug("entering test_shutdown()");
 292
 293	/* test for each direction (read, write, read-write) */
 294	for (i = 0; i < 3; i++) {
 295
 296		if (info->bug_shutdown_read && how[i] == SHUT_RD) continue;
 297
 298		debug("test shutdown() with an invalid descriptor");
 299
 300		errno = 0;
 301		rc = shutdown(-1, how[i]);
 302		if (!(rc == -1 && errno == EBADF) && !info->bug_shutdown) {
 303			test_fail("shutdown(-1, how[i]) should have failed");
 304		}
 305
 306		debug("test shutdown() with a non-socket descriptor");
 307
 308		errno = 0;
 309		rc = shutdown(0, how[i]);
 310		if (!(rc == -1 && errno == ENOTSOCK) && !info->bug_shutdown) {
 311			test_fail("shutdown() should have failed with "
 312			    "ENOTSOCK");
 313		}
 314
 315		debug("test shutdown() with a socket that is not connected");
 316
 317		SOCKET(sd, info->domain, info->type, 0);
 318		errno = 0;
 319		rc = shutdown(sd, how[i]);
 320		if (!(rc == -1 && errno == ENOTCONN) &&
 321			!info->bug_shutdown_not_conn &&
 322			!info->bug_shutdown) {
 323			test_fail("shutdown() should have failed");
 324		}
 325		CLOSE(sd);
 326	}
 327
 328	SOCKET(sd, info->domain, info->type, 0);
 329	errno = 0;
 330	rc = shutdown(sd, -1);
 331	if (!(rc == -1 && errno == ENOTCONN) &&
 332		!info->bug_shutdown_not_conn &&
 333		!info->bug_shutdown) {
 334		test_fail("shutdown(sd, -1) should have failed with ENOTCONN");
 335	}
 336	CLOSE(sd);
 337
 338	debug("leaving test_shutdown()");
 339}
 340
 341void test_close(const struct socket_test_info *info)
 342{
 343	int sd, sd2;
 344	int rc, i;
 345
 346	debug("entering test_close()");
 347
 348	info->callback_cleanup();
 349
 350	debug("Test close() success");
 351
 352	SOCKET(sd, info->domain, info->type, 0);
 353	rc = bind(sd, info->serveraddr, info->serveraddrlen);
 354	if (rc != 0) {
 355		test_fail("bind() should have worked");
 356	}
 357
 358	CLOSE(sd);
 359
 360	debug("Close an already closed file descriptor");
 361
 362	errno = 0;
 363	rc = close(sd);
 364	if (!(rc == -1 && errno == EBADF)) {
 365		test_fail("close(sd) should have failed with EBADF");
 366	}
 367
 368	info->callback_cleanup();
 369
 370	debug("dup()'ing a file descriptor and closing both should work");
 371
 372	SOCKET(sd, info->domain, info->type, 0);
 373	rc = bind(sd, info->serveraddr, info->serveraddrlen);
 374	if (rc != 0) {
 375		test_fail("bind() should have worked");
 376	}
 377
 378	errno = 0;
 379	sd2 = dup(sd);
 380	if (sd2 == -1) {
 381		test_fail("dup(sd) should have worked");
 382	} else {
 383		CLOSE(sd2);
 384		CLOSE(sd);
 385	}
 386
 387	info->callback_cleanup();
 388
 389	/* Create and close a socket a bunch of times.
 390	 * If the implementation doesn't properly free the
 391	 * socket during close(), eventually socket() will
 392	 * fail when the internal descriptor table is full.
 393	 */
 394	for (i = 0; i < 1024; i++) {
 395		SOCKET(sd, info->domain, info->type, 0);
 396		CLOSE(sd);
 397	}
 398
 399	debug("leaving test_close()");
 400}
 401
 402void test_sockopts(const struct socket_test_info *info)
 403{
 404	int i;
 405	int rc;
 406	int sd;
 407	int option_value;
 408	socklen_t option_len;
 409
 410	debug("entering test_sockopts()");
 411
 412	for (i = 0; i < info->typecount; i++) {
 413
 414		SOCKET(sd, info->domain, info->types[i], 0);
 415
 416		debug("Test setsockopt() works");
 417
 418		option_value = 0;
 419		option_len = sizeof(option_value);
 420		errno = 0;
 421		rc = getsockopt(sd, SOL_SOCKET, SO_TYPE, &option_value,
 422							&option_len);
 423		if (rc != 0) {
 424			test_fail("setsockopt() should have worked");
 425		}
 426
 427		if (option_value != info->types[i]) {
 428			test_fail("SO_TYPE didn't seem to work.");
 429		}
 430
 431		CLOSE(sd);
 432	}
 433
 434
 435
 436	SOCKET(sd, info->domain, info->type, 0);
 437
 438	debug("Test setsockopt() works");
 439
 440	option_value = 0;
 441	option_len = sizeof(option_value);
 442	errno = 0;
 443	rc = getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &option_value, &option_len);
 444	if (rc != 0 && !info->bug_sockopt_sndbuf) {
 445		test_fail("getsockopt() should have worked");
 446	}
 447
 448	if (info->expected_sndbuf >= 0 &&
 449		option_value != info->expected_sndbuf &&
 450		!info->bug_sockopt_sndbuf) {
 451		test_fail("SO_SNDBUF didn't seem to work.");
 452	}
 453
 454	CLOSE(sd);
 455
 456
 457	SOCKET(sd, info->domain, info->type, 0);
 458
 459	debug("Test setsockopt() works");
 460
 461	option_value = 0;
 462	option_len = sizeof(option_value);
 463	errno = 0;
 464	rc = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &option_value, &option_len);
 465	if (rc != 0 && !info->bug_sockopt_rcvbuf) {
 466		test_fail("getsockopt() should have worked");
 467	}
 468
 469	if (info->expected_rcvbuf >= 0 &&
 470		option_value != info->expected_rcvbuf &&
 471		!info->bug_sockopt_rcvbuf) {
 472		test_fail("SO_RCVBUF didn't seem to work.");
 473	}
 474
 475	CLOSE(sd);
 476
 477
 478	debug("leaving test_sockopts()");
 479}
 480
 481void test_read(const struct socket_test_info *info)
 482{
 483	int rc;
 484	int fd;
 485	char buf[BUFSIZE];
 486
 487	debug("entering test_read()");
 488
 489	errno = 0;
 490	rc = read(-1, buf, sizeof(buf));
 491	if (!(rc == -1 && errno == EBADF)) {
 492		test_fail("read() should have failed with EBADF");
 493	}
 494
 495	fd = open("/tmp", O_RDONLY);
 496	if (fd == -1) {
 497		test_fail("open(\"/tmp\", O_RDONLY) should have worked");
 498	}
 499
 500	CLOSE(fd);
 501
 502	debug("leaving test_read()");
 503}
 504
 505void test_write(const struct socket_test_info *info)
 506{
 507	int rc;
 508	char buf[BUFSIZE];
 509
 510	debug("entering test_write()");
 511
 512	errno = 0;
 513	rc = write(-1, buf, sizeof(buf));
 514	if (!(rc == -1 && errno == EBADF)) {
 515		test_fail("write() should have failed with EBADF");
 516	}
 517
 518	debug("leaving test_write()");
 519}
 520
 521void test_dup(const struct socket_test_info *info)
 522{
 523	struct stat info1;
 524	struct stat info2;
 525	int sd, sd2;
 526	int rc;
 527	int i;
 528
 529	debug("entering test_dup()");
 530
 531	info->callback_cleanup();
 532
 533	debug("Test dup()");
 534
 535	SOCKET(sd, info->domain, info->type, 0);
 536	rc = bind(sd, info->serveraddr, info->serveraddrlen);
 537	if (rc != 0) {
 538		test_fail("bind() should have worked");
 539	}
 540
 541	errno = 0;
 542	sd2 = dup(sd);
 543	if (sd2 == -1) {
 544		test_fail("dup(sd) should have worked");
 545	}
 546
 547	rc = fstat(sd, &info1);
 548	if (rc == -1) {
 549		test_fail("fstat(fd, &info1) failed");
 550	}
 551
 552	rc = fstat(sd2, &info2);
 553	if (rc == -1) {
 554		test_fail("fstat(sd, &info2) failed");
 555	}
 556
 557	if (info1.st_ino != info2.st_ino) {
 558		test_fail("dup() failed info1.st_ino != info2.st_ino");
 559	}
 560
 561	CLOSE(sd);
 562	CLOSE(sd2);
 563
 564	debug("Test dup() with a closed socket");
 565
 566	errno = 0;
 567	rc = dup(sd);
 568	if (!(rc == -1 && errno == EBADF)) {
 569		test_fail("dup(sd) on a closed socket shouldn't have worked");
 570	}
 571
 572	debug("Test dup() with socket descriptor of -1");
 573
 574	errno = 0;
 575	rc = dup(-1);
 576	if (!(rc == -1 && errno == EBADF)) {
 577		test_fail("dup(-1) shouldn't have worked");
 578	}
 579
 580	debug("Test dup() when all of the file descriptors are taken");
 581
 582	SOCKET(sd, info->domain, info->type, 0);
 583
 584	for (i = 4; i < getdtablesize(); i++) {
 585		rc = open("/dev/null", O_RDONLY);
 586		if (rc == -1) {
 587			test_fail("we couldn't open /dev/null for read");
 588		}
 589	}
 590
 591	errno = 0;
 592	sd2 = dup(sd);
 593	if (!(sd2 == -1 && errno == EMFILE)) {
 594		test_fail("dup(sd) should have failed with errno = EMFILE");
 595	}
 596
 597	for (i = 3; i < getdtablesize(); i++) {
 598		CLOSE(i);
 599	}
 600
 601	info->callback_cleanup();
 602
 603	debug("leaving test_dup()");
 604}
 605
 606void test_dup2(const struct socket_test_info *info)
 607{
 608	struct stat info1;
 609	struct stat info2;
 610	int sd;
 611	int fd;
 612	int rc;
 613
 614	debug("entering test_dup2()");
 615	info->callback_cleanup();
 616
 617	SOCKET(sd, info->domain, info->type, 0);
 618
 619	rc = bind(sd, info->serveraddr, info->serveraddrlen);
 620	if (rc != 0) {
 621		test_fail("bind() should have worked");
 622	}
 623
 624	fd = open("/dev/null", O_RDONLY);
 625	if (fd == -1) {
 626		test_fail("open(\"/dev/null\", O_RDONLY) failed");
 627	}
 628
 629	fd = dup2(sd, fd);
 630	if (fd == -1) {
 631		test_fail("dup2(sd, fd) failed.");
 632	}
 633
 634	memset(&info1, '\0', sizeof(struct stat));
 635	memset(&info2, '\0', sizeof(struct stat));
 636
 637	rc = fstat(fd, &info1);
 638	if (rc == -1) {
 639		test_fail("fstat(fd, &info1) failed");
 640	}
 641
 642	rc = fstat(sd, &info2);
 643	if (rc == -1) {
 644		test_fail("fstat(sd, &info2) failed");
 645	}
 646
 647	if (!(info1.st_ino == info2.st_ino &&
 648		major(info1.st_dev) == major(info2.st_dev) &&
 649		minor(info1.st_dev) == minor(info2.st_dev))) {
 650
 651		test_fail("dup2() failed");
 652	}
 653
 654	CLOSE(fd);
 655	CLOSE(sd);
 656
 657	info->callback_cleanup();
 658	debug("leaving test_dup2()");
 659
 660}
 661
 662/*
 663 * A toupper() server. This toy server converts a string to upper case.
 664 */
 665static void test_xfer_server(const struct socket_test_info *info, pid_t pid)
 666{
 667	int i;
 668	struct timeval tv;
 669	fd_set readfds;
 670	int status;
 671	int rc;
 672	int sd;
 673	unsigned char buf[BUFSIZE];
 674	socklen_t client_addr_size;
 675	int client_sd;
 676	struct sockaddr_storage client_addr;
 677
 678	status = 0;
 679	rc = 0;
 680	sd = 0;
 681	client_sd = 0;
 682	client_addr_size = sizeof(struct sockaddr_storage);
 683
 684	memset(&buf, '\0', sizeof(buf));
 685	memset(&client_addr, '\0', sizeof(client_addr));
 686
 687	SOCKET(sd, info->domain, info->type, 0);
 688
 689	rc = bind(sd, info->serveraddr, info->serveraddrlen);
 690	if (rc == -1) {
 691		test_fail("bind() should have worked");
 692	}
 693
 694	rc = listen(sd, 8);
 695	if (rc == -1) {
 696		test_fail("listen(sd, 8) should have worked");
 697	}
 698
 699	/* we're ready for connections, time to tell the client to start
 700	 * the test
 701	 */
 702	kill(pid, SIGUSR1);
 703
 704	tv.tv_sec = 10;
 705	tv.tv_usec = 0;
 706
 707	FD_ZERO(&readfds);
 708	FD_SET(sd, &readfds);
 709
 710	/* use select() in case the client is really broken and never
 711	 * attempts to connect (we don't want to block on accept()
 712	 * forever).
 713	 */
 714	rc = select(sd + 1, &readfds, NULL, NULL, &tv);
 715	if (rc == -1) {
 716		test_fail("[server] select() should not have failed");
 717	}
 718
 719	if (rc != 1) {
 720		test_fail("[server] select() should have returned 1");
 721		printf("[server] select returned %d\n", rc);
 722	}
 723
 724	if (!(FD_ISSET(sd, &readfds))) {
 725		test_fail("[server] client didn't connect within 10 seconds");
 726		kill(pid, SIGKILL);
 727		return;
 728	}
 729
 730	client_sd = accept(sd, (struct sockaddr *) &client_addr,
 731						&client_addr_size);
 732
 733	if (client_sd == -1) {
 734		test_fail("accept() should have worked");
 735		kill(pid, SIGKILL);
 736		return;
 737	} else {
 738		debug("[server] client accept()'d");
 739	}
 740
 741	debug("[server] Reading message");
 742	rc = read(client_sd, buf, sizeof(buf));
 743	if (rc == -1) {
 744		test_fail("read() failed unexpectedly");
 745		kill(pid, SIGKILL);
 746		return;
 747	}
 748	debug("[server] we got the following message:");
 749	debug(buf);
 750
 751	for (i = 0; i < rc && i < 127; i++) {
 752		buf[i] = toupper(buf[i]);
 753	}
 754
 755	debug("[server] Writing message...");
 756	rc = write(client_sd, buf, sizeof(buf));
 757	if (rc == -1) {
 758		test_fail("write(client_sd, buf, sizeof(buf)) failed");
 759		kill(pid, SIGKILL);
 760		return;
 761	}
 762
 763	if (rc < strlen((char *)buf)) {
 764		test_fail("[server] write didn't write all the bytes");
 765	}
 766
 767	memset(&buf, '\0', sizeof(buf));
 768
 769	debug("[server] Recv message");
 770	rc = recv(client_sd, buf, sizeof(buf), 0);
 771	if (rc == -1) {
 772		test_fail("recv() failed unexpectedly");
 773		kill(pid, SIGKILL);
 774		return;
 775	}
 776	debug("[server] we got the following message:");
 777	debug(buf);
 778
 779	for (i = 0; i < rc && i < 127; i++) {
 780		buf[i] = toupper(buf[i]);
 781	}
 782
 783	debug("[server] Sending message...");
 784	rc = send(client_sd, buf, sizeof(buf), 0);
 785	if (rc == -1) {
 786		test_fail("send(client_sd, buf, sizeof(buf), 0) failed");
 787		kill(pid, SIGKILL);
 788		return;
 789	}
 790
 791	if (rc < strlen((char *)buf)) {
 792		test_fail("[server] write didn't write all the bytes");
 793	}
 794
 795	memset(&buf, '\0', sizeof(buf));
 796
 797	debug("[server] Recvfrom message");
 798	rc = recvfrom(client_sd, buf, sizeof(buf), 0, NULL, 0);
 799	if (rc == -1) {
 800		test_fail("recvfrom() failed unexpectedly");
 801		kill(pid, SIGKILL);
 802		return;
 803	}
 804	debug("[server] we got the following message:");
 805	debug(buf);
 806
 807	for (i = 0; i < rc && i < 127; i++) {
 808		buf[i] = toupper(buf[i]);
 809	}
 810
 811	debug("[server] Sendto message...");
 812	rc = sendto(client_sd, buf, sizeof(buf), 0, NULL, 0);
 813	if (rc == -1) {
 814		test_fail("sendto() failed");
 815		kill(pid, SIGKILL);
 816		return;
 817	}
 818
 819	if (rc < strlen((char *)buf)) {
 820		test_fail("[server] write didn't write all the bytes");
 821	}
 822
 823	shutdown(client_sd, SHUT_RDWR);
 824	CLOSE(client_sd);
 825
 826	shutdown(sd, SHUT_RDWR);
 827	CLOSE(sd);
 828
 829	/* wait for client to exit */
 830	do {
 831		errno = 0;
 832		rc = waitpid(pid, &status, 0);
 833	} while (rc == -1 && errno == EINTR);
 834
 835	/* we use the exit status to get its error count */
 836	errct += WEXITSTATUS(status);
 837}
 838
 839int server_ready = 0;
 840
 841/* signal handler for the client */
 842void test_xfer_sighdlr(int sig)
 843{
 844	debug("entering signal handler");
 845	switch (sig) {
 846		/* the server will send SIGUSR1 when it is time for us
 847		 * to start the tests
 848		 */
 849	case SIGUSR1:
 850		server_ready = 1;
 851		debug("got SIGUSR1, the server is ready for the client");
 852		break;
 853	default:
 854		debug("didn't get SIGUSR1");
 855	}
 856	debug("leaving signal handler");
 857}
 858
 859/*
 860 * A toupper() client.
 861 */
 862static void test_xfer_client(const struct socket_test_info *info)
 863{
 864	struct timeval tv;
 865	fd_set readfds;
 866	struct sockaddr_storage peer_addr;
 867	socklen_t peer_addr_len;
 868	int sd;
 869	int rc;
 870	char buf[BUFSIZE];
 871
 872	debug("[client] entering test_xfer_client()");
 873	errct = 0;	/* reset error count */
 874	memset(&buf, '\0', sizeof(buf));
 875
 876	while (server_ready == 0) {
 877		debug("[client] waiting for the server to signal");
 878		sleep(1);
 879	}
 880
 881	peer_addr_len = sizeof(peer_addr);
 882
 883
 884	if (info->callback_xfer_prepclient) info->callback_xfer_prepclient();
 885
 886	debug("[client] creating client socket");
 887	SOCKET(sd, info->domain, info->type, 0);
 888
 889	debug("[client] connecting to server through the symlink");
 890	rc = connect(sd, info->clientaddrsym, info->clientaddrsymlen);
 891	if (rc == -1) {
 892		test_fail("[client] connect() should have worked");
 893	} else {
 894		debug("[client] connected");
 895	}
 896
 897	debug("[client] testing getpeername()");
 898	memset(&peer_addr, '\0', sizeof(peer_addr));
 899	rc = getpeername(sd, (struct sockaddr *) &peer_addr, &peer_addr_len);
 900	if (rc == -1) {
 901		test_fail("[client] getpeername() should have worked");
 902	}
 903
 904	/* we need to use the full path "/usr/src/test/DIR_56/test.sock"
 905	 * because that is what is returned by getpeername().
 906	 */
 907
 908	info->callback_check_sockaddr((struct sockaddr *) &peer_addr,
 909		peer_addr_len, "getpeername", 1);
 910
 911	strncpy(buf, "Hello, World!", sizeof(buf) - 1);
 912	debug("[client] send to server");
 913	rc = write(sd, buf, sizeof(buf));
 914	if (rc == -1) {
 915		test_fail("[client] write() failed unexpectedly");
 916	}
 917
 918	memset(buf, '\0', sizeof(buf));
 919	debug("[client] read from server");
 920	rc = read(sd, buf, sizeof(buf));
 921	if (rc == -1) {
 922		test_fail("[client] read() failed unexpectedly");
 923	} else {
 924		debug("[client] we got the following message:");
 925		debug(buf);
 926	}
 927
 928	if (strncmp(buf, "HELLO, WORLD!", sizeof(buf)) != 0) {
 929		test_fail("[client] We didn't get the correct response");
 930	}
 931
 932	memset(&buf, '\0', sizeof(buf));
 933	strncpy(buf, "Bonjour!", sizeof(buf) - 1);
 934
 935	debug("[client] send to server");
 936	rc = send(sd, buf, sizeof(buf), 0);
 937	if (rc == -1) {
 938		test_fail("[client] send() failed unexpectedly");
 939	}
 940
 941	if (info->callback_xfer_peercred) info->callback_xfer_peercred(sd);
 942
 943	debug("Testing select()");
 944
 945	tv.tv_sec = 2;
 946	tv.tv_usec = 500000;
 947
 948	FD_ZERO(&readfds);
 949	FD_SET(sd, &readfds);
 950
 951	rc = select(sd + 1, &readfds, NULL, NULL, &tv);
 952	if (rc == -1) {
 953		test_fail("[client] select() should not have failed");
 954	}
 955
 956	if (rc != 1) {
 957		test_fail("[client] select() should have returned 1");
 958	}
 959
 960	if (!(FD_ISSET(sd, &readfds))) {
 961		test_fail("The server didn't respond within 2.5 seconds");
 962	}
 963
 964	memset(buf, '\0', sizeof(buf));
 965	debug("[client] recv from server");
 966	rc = recv(sd, buf, sizeof(buf), 0);
 967	if (rc == -1) {
 968		test_fail("[client] recv() failed unexpectedly");
 969	} else {
 970		debug("[client] we got the following message:");
 971		debug(buf);
 972	}
 973
 974	if (strncmp(buf, "BONJOUR!", sizeof(buf)) != 0) {
 975		test_fail("[client] We didn't get the right response.");
 976	}
 977
 978	memset(&buf, '\0', sizeof(buf));
 979	strncpy(buf, "Hola!", sizeof(buf) - 1);
 980
 981	debug("[client] sendto to server");
 982	rc = sendto(sd, buf, sizeof(buf), 0, NULL, 0);
 983	if (rc == -1) {
 984		test_fail("[client] sendto() failed");
 985	}
 986
 987	debug("Testing select()");
 988
 989	tv.tv_sec = 2;
 990	tv.tv_usec = 500000;
 991
 992	FD_ZERO(&readfds);
 993	FD_SET(sd, &readfds);
 994
 995	rc = select(sd + 1, &readfds, NULL, NULL, &tv);
 996	if (rc == -1) {
 997		test_fail("[client] select() should not have failed");
 998	}
 999
1000	if (rc != 1) {
1001		test_fail("[client] select() should have returned 1");
1002	}
1003
1004	if (!(FD_ISSET(sd, &readfds))) {
1005		test_fail("[client] The server didn't respond in 2.5 seconds");
1006	}
1007
1008	memset(buf, '\0', sizeof(buf));
1009	debug("[client] recvfrom from server");
1010	rc = recvfrom(sd, buf, sizeof(buf), 0, NULL, 0);
1011	if (rc == -1) {
1012		test_fail("[cleint] recvfrom() failed unexpectedly");
1013	} else {
1014		debug("[client] we got the following message:");
1015		debug(buf);
1016	}
1017
1018	if (strncmp(buf, "HOLA!", sizeof(buf)) != 0) {
1019		test_fail("[client] We didn't get the right response.");
1020	}
1021
1022	debug("[client] closing socket");
1023	CLOSE(sd);
1024
1025	debug("[client] leaving test_xfer_client()");
1026	exit(errct);
1027}
1028
1029void test_xfer(const struct socket_test_info *info)
1030{
1031	pid_t pid;
1032
1033	debug("entering test_xfer()");
1034	info->callback_cleanup();
1035
1036	/* the signal handler is only used by the client, but we have to
1037	 * install it now. if we don't the server may signal the client
1038	 * before the handler is installed.
1039	 */
1040	debug("installing signal handler");
1041	if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1042		test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1043	}
1044
1045	debug("signal handler installed");
1046
1047	server_ready = 0;
1048
1049	pid = fork();
1050	if (pid == -1) {
1051		test_fail("fork() failed");
1052		return;
1053	} else if (pid == 0) {
1054		debug("child");
1055		errct = 0;
1056		test_xfer_client(info);
1057		test_fail("we should never get here");
1058		exit(1);
1059	} else {
1060		debug("parent");
1061		test_xfer_server(info, pid);
1062		debug("parent done");
1063	}
1064
1065	info->callback_cleanup();
1066	debug("leaving test_xfer()");
1067}
1068
1069static void test_simple_client(const struct socket_test_info *info, int type)
1070{
1071	char buf[BUFSIZE];
1072	int sd, rc;
1073
1074	sd = socket(info->domain, type, 0);
1075	if (sd == -1) {
1076		test_fail("socket");
1077		exit(errct);
1078	}
1079
1080	while (server_ready == 0) {
1081		debug("[client] waiting for the server");
1082		sleep(1);
1083	}
1084
1085	bzero(buf, BUFSIZE);
1086	snprintf(buf, BUFSIZE-1, "Hello, My Name is Client.");
1087
1088	if (type == SOCK_DGRAM) {
1089
1090		rc = sendto(sd, buf, strlen(buf) + 1, 0,
1091			info->clientaddr, info->clientaddrlen);
1092		if (rc == -1) {
1093			test_fail("sendto");
1094			exit(errct);
1095		}
1096
1097	} else {
1098
1099		rc = connect(sd, info->clientaddr, info->clientaddrlen);
1100		if (rc == -1) {
1101			test_fail("connect");
1102			exit(errct);
1103		}
1104
1105		rc = write(sd, buf, strlen(buf) + 1);
1106
1107		if (rc == -1) {
1108			test_fail("write");
1109		}
1110
1111		memset(buf, '\0', BUFSIZE);
1112		rc = read(sd, buf, BUFSIZE);
1113		if (rc == -1) {
1114			test_fail("read");
1115		}
1116
1117		if (strcmp("Hello, My Name is Server.", buf) != 0) {
1118			test_fail("didn't read the correct string");
1119		}
1120	}
1121
1122	rc = close(sd);
1123	if (rc == -1) {
1124		test_fail("close");
1125	}
1126
1127	exit(errct);
1128}
1129
1130static void test_simple_server(const struct socket_test_info *info, int type,
1131	pid_t pid)
1132{
1133	char buf[BUFSIZE];
1134	int sd, rc, client_sd, status;
1135	struct sockaddr_storage addr;
1136	socklen_t addr_len;
1137
1138	addr_len = info->clientaddrlen;
1139
1140	sd = socket(info->domain, type, 0);
1141	if (sd == -1) {
1142		test_fail("socket");
1143	}
1144
1145	assert(info->clientaddrlen <= sizeof(addr));
1146	memcpy(&addr, info->clientaddr, info->clientaddrlen);
1147
1148	rc = bind(sd, info->serveraddr, info->serveraddrlen);
1149	if (rc == -1) {
1150		test_fail("bind");
1151	}
1152
1153	if (type == SOCK_DGRAM) {
1154
1155		/* ready for client */
1156		kill(pid, SIGUSR1);
1157
1158		rc = recvfrom(sd, buf, BUFSIZE, 0,
1159				(struct sockaddr *) &addr, &addr_len);
1160		if (rc == -1) {
1161			test_fail("recvfrom");
1162		}
1163
1164	} else {
1165
1166		rc = listen(sd, 5);
1167		if (rc == -1) {
1168			test_fail("listen");
1169		}
1170
1171		/* we're ready for connections, time to tell the client
1172		 * to start the test
1173		 */
1174		kill(pid, SIGUSR1);
1175
1176		client_sd = accept(sd, (struct sockaddr *) &addr, &addr_len);
1177		if (client_sd == -1) {
1178			test_fail("accept");
1179		}
1180
1181		memset(buf, '\0', BUFSIZE);
1182		rc = read(client_sd, buf, BUFSIZE);
1183		if (rc == -1) {
1184			test_fail("read");
1185		}
1186
1187		if (strcmp("Hello, My Name is Client.", buf) != 0) {
1188			test_fail("didn't read the correct string");
1189		}
1190
1191		/* added for extra fun to make the client block on read() */
1192		sleep(1);
1193
1194		bzero(buf, BUFSIZE);
1195		snprintf(buf, BUFSIZE-1, "Hello, My Name is Server.");
1196
1197		rc = write(client_sd, buf, strlen(buf) + 1);
1198		if (rc == -1) {
1199			test_fail("write");
1200		}
1201		rc = close(client_sd);
1202		if (rc == -1) {
1203			test_fail("close");
1204		}
1205	}
1206
1207	rc = close(sd);
1208	if (rc == -1) {
1209		test_fail("close");
1210	}
1211
1212	/* wait for client to exit */
1213	do {
1214		errno = 0;
1215		rc = waitpid(pid, &status, 0);
1216	} while (rc == -1 && errno == EINTR);
1217
1218	/* we use the exit status to get its error count */
1219	errct += WEXITSTATUS(status);
1220}
1221
1222static void test_abort_client(const struct socket_test_info *info,
1223	int abort_type);
1224static void test_abort_server(const struct socket_test_info *info,
1225	pid_t pid, int abort_type);
1226
1227void test_abort_client_server(const struct socket_test_info *info,
1228	int abort_type)
1229{
1230	pid_t pid;
1231
1232	debug("test_simple_client_server()");
1233
1234	info->callback_cleanup();
1235
1236	/* the signal handler is only used by the client, but we have to
1237	 * install it now. if we don't the server may signal the client
1238	 * before the handler is installed.
1239	 */
1240	debug("installing signal handler");
1241	if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1242		test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1243	}
1244
1245	debug("signal handler installed");
1246
1247	server_ready = 0;
1248
1249	pid = fork();
1250	if (pid == -1) {
1251		test_fail("fork() failed");
1252		return;
1253	} else if (pid == 0) {
1254		debug("child");
1255		errct = 0;
1256		test_abort_client(info, abort_type);
1257		test_fail("we should never get here");
1258		exit(1);
1259	} else {
1260		debug("parent");
1261		test_abort_server(info, pid, abort_type);
1262		debug("parent done");
1263	}
1264
1265	info->callback_cleanup();
1266}
1267
1268static void test_abort_client(const struct socket_test_info *info,
1269	int abort_type)
1270{
1271	char buf[BUFSIZE];
1272	int sd, rc;
1273
1274	sd = socket(info->domain, info->type, 0);
1275	if (sd == -1) {
1276		test_fail("socket");
1277		exit(errct);
1278	}
1279
1280	while (server_ready == 0) {
1281		debug("[client] waiting for the server");
1282		sleep(1);
1283	}
1284
1285	bzero(buf, BUFSIZE);
1286	snprintf(buf, BUFSIZE-1, "Hello, My Name is Client.");
1287
1288	rc = connect(sd, info->clientaddr, info->clientaddrlen);
1289	if (rc == -1) {
1290		test_fail("connect");
1291		exit(errct);
1292	}
1293
1294	if (abort_type == 2) {
1295		/* Give server a chance to close connection */
1296		sleep(2);
1297		rc = write(sd, buf, strlen(buf) + 1);
1298		if (rc != -1) {
1299			if (!info->ignore_write_conn_reset) {
1300				test_fail("write should have failed\n");
1301			}
1302		} else if (errno != ECONNRESET) {
1303			test_fail("errno should've been ECONNRESET\n");
1304		}
1305	}
1306
1307	rc = close(sd);
1308	if (rc == -1) {
1309		test_fail("close");
1310	}
1311
1312	exit(errct);
1313}
1314
1315static void test_abort_server(const struct socket_test_info *info,
1316	pid_t pid, int abort_type)
1317{
1318	char buf[BUFSIZE];
1319	int sd, rc, client_sd, status;
1320	struct sockaddr_storage addr;
1321	socklen_t addr_len;
1322
1323	addr_len = info->clientaddrlen;
1324
1325	sd = socket(info->domain, info->type, 0);
1326	if (sd == -1) {
1327		test_fail("socket");
1328	}
1329
1330	assert(sizeof(addr) >= info->clientaddrlen);
1331	memcpy(&addr, info->clientaddr, info->clientaddrlen);
1332
1333	rc = bind(sd, info->serveraddr, info->serveraddrlen);
1334	if (rc == -1) {
1335		test_fail("bind");
1336	}
1337
1338	rc = listen(sd, 5);
1339	if (rc == -1) {
1340		test_fail("listen");
1341	}
1342
1343	/* we're ready for connections, time to tell the client
1344	 * to start the test
1345	 */
1346	kill(pid, SIGUSR1);
1347
1348	client_sd = accept(sd, (struct sockaddr *) &addr, &addr_len);
1349	if (client_sd == -1) {
1350		test_fail("accept");
1351	}
1352
1353	if (abort_type == 1) {
1354		memset(buf, '\0', BUFSIZE);
1355		rc = read(client_sd, buf, BUFSIZE);
1356		if (rc != -1 && (rc != 0 || !info->ignore_read_conn_reset)) {
1357			test_fail("read should've failed or returned zero\n");
1358		}
1359		if (rc != 0 && errno != ECONNRESET) {
1360			test_fail("errno should've been ECONNRESET\n");
1361		}
1362	} /* else if (abort_type == 2) { */
1363		rc = close(client_sd);
1364		if (rc == -1) {
1365			test_fail("close");
1366		}
1367	/* } */
1368
1369	rc = close(sd);
1370	if (rc == -1) {
1371		test_fail("close");
1372	}
1373
1374	/* wait for client to exit */
1375	do {
1376		errno = 0;
1377		rc = waitpid(pid, &status, 0);
1378	} while (rc == -1 && errno == EINTR);
1379
1380	/* we use the exit status to get its error count */
1381	errct += WEXITSTATUS(status);
1382}
1383
1384void test_simple_client_server(const struct socket_test_info *info, int type)
1385{
1386	pid_t pid;
1387
1388	debug("entering test_simple_client_server()");
1389
1390	info->callback_cleanup();
1391
1392	/* the signal handler is only used by the client, but we have to
1393	 * install it now. if we don't the server may signal the client
1394	 * before the handler is installed.
1395	 */
1396	debug("installing signal handler");
1397	if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1398		test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1399	}
1400
1401	debug("signal handler installed");
1402
1403	server_ready = 0;
1404
1405	pid = fork();
1406	if (pid == -1) {
1407		test_fail("fork() failed");
1408		return;
1409	} else if (pid == 0) {
1410		debug("child");
1411		errct = 0;
1412		test_simple_client(info, type);
1413		test_fail("we should never get here");
1414		exit(1);
1415	} else {
1416		debug("parent");
1417		test_simple_server(info, type, pid);
1418		debug("parent done");
1419	}
1420
1421	info->callback_cleanup();
1422	debug("leaving test_simple_client_server()");
1423}
1424
1425void test_msg_dgram(const struct socket_test_info *info)
1426{
1427	int rc;
1428	int src;
1429	int dst;
1430	struct sockaddr_storage addr;
1431	struct iovec iov[3];
1432	struct msghdr msg1;
1433	struct msghdr msg2;
1434	char buf1[BUFSIZE];
1435	char buf2[BUFSIZE];
1436	char buf3[BUFSIZE];
1437
1438	debug("entering test_msg_dgram");
1439
1440	info->callback_cleanup();
1441
1442	src = socket(info->domain, SOCK_DGRAM, 0);
1443	if (src == -1) {
1444		test_fail("socket");
1445	}
1446
1447	dst = socket(info->domain, SOCK_DGRAM, 0);
1448	if (dst == -1) {
1449		test_fail("socket");
1450	}
1451
1452	rc = bind(src, info->serveraddr2, info->serveraddr2len);
1453	if (rc == -1) {
1454		test_fail("bind");
1455	}
1456
1457	assert(info->clientaddrlen <= sizeof(addr));
1458	memcpy(&addr, info->clientaddr, info->clientaddrlen);
1459
1460	rc = bind(dst, info->serveraddr, info->serveraddrlen);
1461	if (rc == -1) {
1462		test_fail("bind");
1463	}
1464
1465	memset(&buf1, '\0', BUFSIZE);
1466	memset(&buf2, '\0', BUFSIZE);
1467	memset(&buf3, '\0', BUFSIZE);
1468
1469	strncpy(buf1, "Minix ", BUFSIZE-1);
1470	strncpy(buf2, "is ", BUFSIZE-1);
1471	strncpy(buf3, "great!", BUFSIZE-1);
1472
1473	iov[0].iov_base = buf1;
1474	iov[0].iov_len  = 6;
1475	iov[1].iov_base = buf2;
1476	iov[1].iov_len  = 3;
1477	iov[2].iov_base = buf3;
1478	iov[2].iov_len  = 32;
1479
1480	memset(&msg1, '\0', sizeof(struct msghdr));
1481	msg1.msg_name = &addr;
1482	msg1.msg_namelen = info->clientaddrlen;
1483	msg1.msg_iov = iov;
1484	msg1.msg_iovlen = 3;
1485	msg1.msg_control = NULL;
1486	msg1.msg_controllen = 0;
1487	msg1.msg_flags = 0;
1488
1489	rc = sendmsg(src, &msg1, 0);
1490	if (rc == -1) {
1491		test_fail("sendmsg");
1492	}
1493
1494	memset(&buf1, '\0', BUFSIZE);
1495	memset(&buf2, '\0', BUFSIZE);
1496
1497	iov[0].iov_base = buf1;
1498	iov[0].iov_len  = 9;
1499	iov[1].iov_base = buf2;
1500	iov[1].iov_len  = 32;
1501
1502	memset(&addr, '\0', sizeof(addr));
1503	memset(&msg2, '\0', sizeof(struct msghdr));
1504	msg2.msg_name = &addr;
1505	msg2.msg_namelen = sizeof(addr);
1506	msg2.msg_iov = iov;
1507	msg2.msg_iovlen = 2;
1508	msg2.msg_control = NULL;
1509	msg2.msg_controllen = 0;
1510	msg2.msg_flags = 0;
1511
1512	rc = recvmsg(dst, &msg2, 0);
1513	if (rc == -1) {
1514		test_fail("recvmsg");
1515	}
1516
1517	if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
1518		test_fail("recvmsg");
1519	}
1520
1521	/* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
1522	 * because that is what is returned by recvmsg().
1523	 */
1524	info->callback_check_sockaddr((struct sockaddr *) &addr,
1525		msg2.msg_namelen, "recvmsg", 2);
1526
1527	rc = close(dst);
1528	if (rc == -1) {
1529		test_fail("close");
1530	}
1531
1532	rc = close(src);
1533	if (rc == -1) {
1534		test_fail("close");
1535	}
1536
1537	info->callback_cleanup();
1538	debug("leaving test_msg_dgram");
1539}
1540
1541#define check_select(sd, rd, wr, block) \
1542	check_select_internal(sd, rd, wr, block, 1, __LINE__)
1543#define check_select_cond(sd, rd, wr, block, allchecks) \
1544	check_select_internal(sd, rd, wr, block, allchecks, __LINE__)
1545
1546static void
1547check_select_internal(int sd, int rd, int wr, int block, int allchecks, int line)
1548{
1549	fd_set read_set, write_set;
1550	struct timeval tv;
1551
1552	FD_ZERO(&read_set);
1553	if (rd != -1)
1554		FD_SET(sd, &read_set);
1555
1556	FD_ZERO(&write_set);
1557	if (wr != -1)
1558		FD_SET(sd, &write_set);
1559
1560	tv.tv_sec = block ? 2 : 0;
1561	tv.tv_usec = 0;
1562
1563	errno = 0;
1564	if (select(sd + 1, &read_set, &write_set, NULL, &tv) < 0)
1565		test_fail_fl("select() failed unexpectedly", __FILE__, line);
1566
1567	if (rd != -1 && !!FD_ISSET(sd, &read_set) != rd && allchecks)
1568		test_fail_fl("select() mismatch on read operation",
1569			__FILE__, line);
1570
1571	if (wr != -1 && !!FD_ISSET(sd, &write_set) != wr && allchecks)
1572		test_fail_fl("select() mismatch on write operation",
1573			__FILE__, line);
1574}
1575
1576/*
1577 * Verify that:
1578 * - a nonblocking connecting socket for which there is no accepter, will
1579 *   return EINPROGRESS and complete in the background later;
1580 * - a nonblocking listening socket will return EAGAIN on accept;
1581 * - connecting a connecting socket yields EALREADY;
1582 * - connecting a connected socket yields EISCONN;
1583 * - selecting for read and write on a connecting socket will only satisfy the
1584 *   write only once it is connected;
1585 * - doing a nonblocking write on a connecting socket yields EAGAIN;
1586 * - doing a nonblocking read on a connected socket with no pending data yields
1587 *   EAGAIN.
1588 */
1589void
1590test_nonblock(const struct socket_test_info *info)
1591{
1592	char buf[BUFSIZE];
1593	socklen_t len;
1594	int server_sd, client_sd;
1595	struct sockaddr_storage addr;
1596	int status;
1597
1598	debug("entering test_nonblock()");
1599	memset(buf, 0, sizeof(buf));
1600
1601	SOCKET(server_sd, info->domain, info->type, 0);
1602
1603	if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
1604		test_fail("bind() should have worked");
1605
1606	if (listen(server_sd, 8) == -1)
1607		test_fail("listen() should have worked");
1608
1609	fcntl(server_sd, F_SETFL, fcntl(server_sd, F_GETFL) | O_NONBLOCK);
1610
1611	check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1612
1613	len = sizeof(addr);
1614	if (accept(server_sd, (struct sockaddr *) &addr, &len) != -1 ||
1615	    errno != EAGAIN)
1616		test_fail("accept() should have yielded EAGAIN");
1617
1618	SOCKET(client_sd, info->domain, info->type, 0);
1619
1620	fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK);
1621
1622	if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) {
1623		test_fail("connect() should have failed");
1624	} else if (errno != EINPROGRESS) {
1625		test_fail("connect() should have yielded EINPROGRESS");
1626	}
1627
1628	check_select_cond(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/,
1629		!info->ignore_select_delay);
1630
1631	if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) {
1632		test_fail("connect() should have failed");
1633	} else if (errno != EALREADY && errno != EISCONN) {
1634		test_fail("connect() should have yielded EALREADY");
1635	}
1636
1637	if (recv(client_sd, buf, sizeof(buf), 0) != -1 || errno != EAGAIN)
1638		test_fail("recv() should have yielded EAGAIN");
1639
1640	/* This may be an implementation aspect, or even plain wrong (?). */
1641	if (!info->ignore_send_waiting) {
1642		if (send(client_sd, buf, sizeof(buf), 0) != -1) {
1643			test_fail("send() should have failed");
1644		} else if (errno != EAGAIN) {
1645			test_fail("send() should have yielded EAGAIN");
1646		}
1647	}
1648
1649	switch (fork()) {
1650	case 0:
1651		errct = 0;
1652		close(client_sd);
1653
1654		check_select(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1655
1656		len = sizeof(addr);
1657		client_sd = accept(server_sd, (struct sockaddr *) &addr, &len);
1658		if (client_sd == -1)
1659			test_fail("accept() should have succeeded");
1660
1661		check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1662
1663		close(server_sd);
1664
1665		/* Let the socket become writable in the parent process. */
1666		sleep(1);
1667
1668		if (write(client_sd, buf, 1) != 1)
1669			test_fail("write() should have succeeded");
1670
1671		/* Wait for the client side to close. */
1672		check_select_cond(client_sd, 0 /*read*/, 1 /*write*/,
1673			0 /*block*/, !info->ignore_select_delay /*allchecks*/);
1674		check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/);
1675		check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1676
1677		exit(errct);
1678	case -1:
1679		test_fail("can't fork");
1680	default:
1681		break;
1682	}
1683
1684	close(server_sd);
1685
1686	check_select(client_sd, 0 /*read*/, 1 /*write*/, 1 /*block*/);
1687	check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1688
1689	if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1 ||
1690		errno != EISCONN)
1691		test_fail("connect() should have yielded EISCONN");
1692
1693	check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/);
1694	check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1695
1696	if (read(client_sd, buf, 1) != 1)
1697		test_fail("read() should have succeeded");
1698
1699	check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1700
1701	if (read(client_sd, buf, 1) != -1 || errno != EAGAIN)
1702		test_fail("read() should have yielded EAGAIN");
1703
1704	/* Let the child process block on the select waiting for the close. */
1705	sleep(1);
1706
1707	close(client_sd);
1708
1709	errno = 0;
1710	if (wait(&status) <= 0)
1711		test_fail("wait() should have succeeded");
1712	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
1713		test_fail("child process failed the test");
1714
1715	info->callback_cleanup();
1716	debug("leaving test_nonblock()");
1717}
1718
1719/*
1720 * Verify that a nonblocking connect for which there is an accepter, succeeds
1721 * immediately.  A pretty lame test, only here for completeness.
1722 */
1723void
1724test_connect_nb(const struct socket_test_info *info)
1725{
1726	socklen_t len;
1727	int server_sd, client_sd;
1728	struct sockaddr_storage addr;
1729	int status;
1730
1731	debug("entering test_connect_nb()");
1732	SOCKET(server_sd, info->domain, info->type, 0);
1733
1734	if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
1735		test_fail("bind() should have worked");
1736
1737	if (listen(server_sd, 8) == -1)
1738		test_fail("listen() should have worked");
1739
1740	switch (fork()) {
1741	case 0:
1742		errct = 0;
1743		len = sizeof(addr);
1744		if (accept(server_sd, (struct sockaddr *) &addr, &len) == -1)
1745			test_fail("accept() should have succeeded");
1746
1747		exit(errct);
1748	case -1:
1749		test_fail("can't fork");
1750	default:
1751		break;
1752	}
1753
1754	close(server_sd);
1755
1756	sleep(1);
1757
1758	SOCKET(client_sd, info->domain, info->type, 0);
1759
1760	fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK);
1761
1762	if (connect(client_sd, info->clientaddr, info->clientaddrlen) != 0) {
1763		if (!info->ignore_connect_delay) {
1764			test_fail("connect() should have succeeded");
1765		} else if (errno != EINPROGRESS) {
1766			test_fail("connect() should have succeeded or "
1767				"failed with EINPROGRESS");
1768		}
1769	}
1770
1771	close(client_sd);
1772
1773	if (wait(&status) <= 0)
1774		test_fail("wait() should have succeeded");
1775	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
1776		test_fail("child process failed the test");
1777
1778	info->callback_cleanup();
1779	debug("leaving test_connect_nb()");
1780}
1781
1782static void
1783dummy_handler(int sig)
1784{
1785	/* Nothing. */
1786}
1787
1788/*
1789 * Verify that:
1790 * - interrupting a blocking connect will return EINTR but complete in the
1791 *   background later;
1792 * - doing a blocking write on an asynchronously connecting socket succeeds
1793 *   once the socket is connected.
1794 * - doing a nonblocking write on a connected socket with lots of pending data
1795 *   yields EAGAIN.
1796 */
1797void
1798test_intr(const struct socket_test_info *info)
1799{
1800	struct sigaction act, oact;
1801	char buf[BUFSIZE];
1802	int isconn;
1803	socklen_t len;
1804	int server_sd, client_sd;
1805	struct sockaddr_storage addr;
1806	int r, status;
1807
1808	debug("entering test_intr()");
1809	memset(buf, 0, sizeof(buf));
1810
1811	SOCKET(server_sd, info->domain, info->type, 0);
1812
1813	if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
1814		test_fail("bind() should have worked");
1815
1816	if (listen(server_sd, 8) == -1)
1817		test_fail("listen() should have worked");
1818
1819	SOCKET(client_sd, info->domain, info->type, 0);
1820
1821	memset(&act, 0, sizeof(act));
1822	act.sa_handler = dummy_handler;
1823	if (sigaction(SIGALRM, &act, &oact) == -1)
1824		test_fail("sigaction() should have succeeded");
1825
1826	if (info->domain != PF_INET) alarm(1);
1827
1828	isconn = 0;
1829	if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) {
1830		if (!info->ignore_connect_unaccepted) {
1831			test_fail("connect() should have failed");
1832		}
1833		isconn = 1;
1834	} else if (errno != EINTR) {
1835		test_fail("connect() should have yielded EINTR");
1836	}
1837
1838	alarm(0);
1839
1840	check_select(client_sd, 0 /*read*/, isconn /*write*/, 0 /*block*/);
1841
1842	switch (fork()) {
1843	case 0:
1844		errct = 0;
1845		close(client_sd);
1846
1847		check_select(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1848
1849		len = sizeof(addr);
1850		client_sd = accept(server_sd, (struct sockaddr *) &addr, &len);
1851		if (client_sd == -1)
1852			test_fail("accept() should have succeeded");
1853
1854		check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1855
1856		close(server_sd);
1857
1858		check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/);
1859		check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1860
1861		if (recv(client_sd, buf, sizeof(buf), 0) != sizeof(buf))
1862			test_fail("recv() should have yielded bytes");
1863
1864		/* No partial transfers should be happening. */
1865		check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1866
1867		sleep(1);
1868
1869		fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) |
1870		    O_NONBLOCK);
1871
1872		/* We can only test nonblocking writes by filling the pipe. */
1873		while ((r = write(client_sd, buf, sizeof(buf))) > 0);
1874
1875		if (r != -1) {
1876			test_fail("write() should have failed");
1877		} else if (errno != EAGAIN) {
1878			test_fail("write() should have yielded EAGAIN");
1879		}
1880
1881		check_select(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/);
1882
1883		if (write(client_sd, buf, 1) != -1) {
1884			test_fail("write() should have failed");
1885		} else if (errno != EAGAIN) {
1886			test_fail("write() should have yielded EAGAIN");
1887		}
1888
1889		exit(errct);
1890	case -1:
1891		test_fail("can't fork");
1892	default:
1893		break;
1894	}
1895
1896	close(server_sd);
1897
1898	if (send(client_sd, buf, sizeof(buf), 0) != sizeof(buf))
1899		test_fail("send() should have succeded");
1900
1901	check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1902
1903	if (wait(&status) <= 0)
1904		test_fail("wait() should have succeeded");
1905	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
1906		test_fail("child process failed the test");
1907
1908	check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1909
1910	close(client_sd);
1911
1912	sigaction(SIGALRM, &oact, NULL);
1913
1914	info->callback_cleanup();
1915	debug("leaving test_intr()");
1916}
1917
1918/*
1919 * Verify that closing a connecting socket before it is accepted will result in
1920 * no activity on the accepting side later.
1921 */
1922void
1923test_connect_close(const struct socket_test_info *info)
1924{
1925	int server_sd, client_sd;
1926	struct sockaddr_storage addr;
1927	socklen_t len;
1928
1929	debug("entering test_connect_close()");
1930	SOCKET(server_sd, info->domain, info->type, 0);
1931
1932	if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
1933		test_fail("bind() should have worked");
1934
1935	if (listen(server_sd, 8) == -1)
1936		test_fail("listen() should have worked");
1937
1938	fcntl(server_sd, F_SETFL, fcntl(server_sd, F_GETFL) | O_NONBLOCK);
1939
1940	check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1941
1942	SOCKET(client_sd, info->domain, info->type, 0);
1943
1944	fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK);
1945
1946	if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1	||
1947		errno != EINPROGRESS)
1948		test_fail("connect() should have yielded EINPROGRESS");
1949
1950	check_select_cond(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/,
1951		!info->ignore_select_delay);
1952	check_select_cond(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/,
1953		!info->ignore_select_delay);
1954
1955	close(client_sd);
1956
1957	check_select_cond(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/,
1958		!info->ignore_select_delay);
1959
1960	len = sizeof(addr);
1961	errno = 0;
1962	if (accept(server_sd, (struct sockaddr *) &addr, &len) != -1) {
1963		if (!info->ignore_accept_delay) {
1964			test_fail("accept() should have failed");
1965		}
1966	} else if (errno != EAGAIN) {
1967		test_fail("accept() should have yielded EAGAIN");
1968	}
1969	close(server_sd);
1970
1971	info->callback_cleanup();
1972	debug("leaving test_connect_close()");
1973}
1974
1975/*
1976 * Verify that closing a listening socket will cause a blocking connect to fail
1977 * with ECONNRESET, and that a subsequent write will yield EPIPE.
1978 */
1979void
1980test_listen_close(const struct socket_test_info *info)
1981{
1982	int server_sd, client_sd;
1983	int status;
1984	char byte;
1985
1986	debug("entering test_listen_close()");
1987	SOCKET(server_sd, info->domain, info->type, 0);
1988
1989	if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
1990		test_fail("bind() should have worked");
1991
1992	if (listen(server_sd, 8) == -1)
1993		test_fail("listen() should have worked");
1994
1995	switch (fork()) {
1996	case 0:
1997		sleep(1);
1998
1999		exit(0);
2000	case -1:
2001		test_fail("can't fork");
2002	default:
2003		break;
2004	}
2005
2006	close(server_sd);
2007
2008	SOCKET(client_sd, info->domain, info->type, 0);
2009
2010	byte = 0;
2011	if (write(client_sd, &byte, 1) != -1 || errno != ENOTCONN)
2012		/* Yes, you fucked up the fix for the FIXME below. */
2013		test_fail("write() should have yielded ENOTCONN");
2014
2015	if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) {
2016		if (!info->bug_connect_after_close) {
2017			test_fail("connect() should have failed");
2018		}
2019	} else if (errno != ECONNRESET) {
2020		test_fail("connect() should have yielded ECONNRESET");
2021	}
2022
2023	/*
2024	 * FIXME: currently UDS cannot distinguish between sockets that have
2025	 * not yet been connected, and sockets that have been disconnected.
2026	 * Thus, we get the same error for both: ENOTCONN instead of EPIPE.
2027	 */
2028#if 0
2029	if (write(client_sd, &byte, 1) != -1 || errno != EPIPE)
2030		test_fail("write() should have yielded EPIPE");
2031#endif
2032
2033	close(client_sd);
2034
2035	if (wait(&status) <= 0)
2036		test_fail("wait() should have succeeded");
2037	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
2038		test_fail("child process failed the test");
2039
2040	info->callback_cleanup();
2041	debug("leaving test_listen_close()");
2042}
2043
2044/*
2045 * Verify that closing a listening socket will cause a nonblocking connect to
2046 * result in the socket becoming readable and writable, and yielding ECONNRESET
2047 * and EPIPE on the next two writes, respectively.
2048 */
2049void
2050test_listen_close_nb(const struct socket_test_info *info)
2051{
2052	int server_sd, client_sd;
2053	int status;
2054	char byte;
2055
2056	debug("entering test_listen_close_nb()");
2057	SOCKET(server_sd, info->domain, info->type, 0);
2058
2059	if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
2060		test_fail("bind() should have worked");
2061
2062	if (listen(server_sd, 8) == -1)
2063		test_fail("listen() should have worked");
2064
2065	switch (fork()) {
2066	case 0:
2067		sleep(1);
2068
2069		exit(0);
2070	case -1:
2071		test_fail("can't fork");
2072	default:
2073		break;
2074	}
2075
2076	close(server_sd);
2077
2078	SOCKET(client_sd, info->domain, info->type, 0);
2079
2080	fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK);
2081
2082	if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1 ||
2083		errno != EINPROGRESS)
2084		test_fail("connect() should have yielded EINPROGRESS");
2085
2086	check_select_cond(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/,
2087		!info->ignore_select_delay);
2088	check_select_cond(client_sd, 1 /*read*/, 1 /*write*/, 1 /*block*/,
2089		!info->ignore_select_delay);
2090
2091	byte = 0;
2092	if (write(client_sd, &byte, 1) != -1) {
2093		if (!info->ignore_write_conn_reset) {
2094			test_fail("write() should have failed");
2095		}
2096	} else if (errno != ECONNRESET) {
2097		test_fail("write() should have yielded ECONNRESET");
2098	}
2099
2100	/*
2101	 * FIXME: currently UDS cannot distinguish between sockets that have
2102	 * not yet been connected, and sockets that have been disconnected.
2103	 * Thus, we get the same error for both: ENOTCONN instead of EPIPE.
2104	 */
2105#if 0
2106	if (write(client_sd, &byte, 1) != -1 || errno != EPIPE)
2107		test_fail("write() should have yielded EPIPE");
2108#endif
2109
2110	check_select_cond(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/,
2111		!info->ignore_select_delay);
2112
2113	close(client_sd);
2114
2115	if (wait(&status) <= 0)
2116		test_fail("wait() should have succeeded");
2117	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
2118		test_fail("child process failed the test");
2119
2120	info->callback_cleanup();
2121	debug("leaving test_listen_close_nb()");
2122}