Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / tests / common-socket.c
blob5249ae8cc0ee8c4007ac24c25ca1d4dbe69f6400
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>
15 #include "common.h"
16 #include "common-socket.h"
18 #define ISO8601_FORMAT "%Y-%m-%dT%H:%M:%S"
20 /* timestamps for debug and error logs */
21 static char *get_timestamp(void)
23 struct tm *tm;
24 time_t t;
25 size_t len;
26 char *s;
28 len = sizeof(char) * 32;
30 t = time(NULL);
31 if (t == -1) {
32 return NULL;
34 tm = gmtime(&t);
35 if (tm == NULL) {
36 return NULL;
39 s = (char *) malloc(len);
40 if (!s) {
41 perror("malloc");
42 return NULL;
44 memset(s, '\0', len);
46 strftime(s, len - 1, ISO8601_FORMAT, tm);
47 return s;
50 void test_fail_fl(char *msg, char *file, int line)
52 char *timestamp;
53 int e;
54 e = errno;
55 timestamp = get_timestamp();
56 if (errct == 0) fprintf(stderr, "\n");
57 errno = e;
58 fprintf(stderr, "[ERROR][%s] (%s Line %d) %s [pid=%d:errno=%d:%s]\n",
59 timestamp, file, line, msg, getpid(), errno, strerror(errno));
60 fflush(stderr);
61 if (timestamp != NULL) {
62 free(timestamp);
63 timestamp = NULL;
65 errno = e;
66 e(7);
69 #if DEBUG == 1
70 void debug_fl(char *msg, char *file, int line)
72 char *timestamp;
73 timestamp = get_timestamp();
74 fprintf(stdout,"[DEBUG][%s] (%s:%d) %s [pid=%d]\n",
75 timestamp, __FILE__, __LINE__, msg, getpid());
76 fflush(stdout);
77 if (timestamp != NULL) {
78 free(timestamp);
79 timestamp = NULL;
82 #endif
84 void test_socket(const struct socket_test_info *info)
86 struct stat statbuf, statbuf2;
87 int sd, sd2;
88 int rc;
89 int i;
91 debug("entering test_socket()");
93 debug("Test socket() with an unsupported address family");
95 errno = 0;
96 sd = socket(-1, info->type, 0);
97 if (!(sd == -1 && errno == EAFNOSUPPORT)) {
98 test_fail("socket");
99 if (sd != -1) {
100 CLOSE(sd);
104 debug("Test socket() with all available FDs open by this process");
106 for (i = 3; i < getdtablesize(); i++) {
107 rc = open("/dev/null", O_RDONLY);
108 if (rc == -1) {
109 test_fail("we couldn't open /dev/null for read");
113 errno = 0;
114 sd = socket(info->domain, info->type, 0);
115 if (!(sd == -1 && errno == EMFILE)) {
116 test_fail("socket() call with all fds open should fail");
117 if (sd != -1) {
118 CLOSE(sd);
122 for (i = 3; i < getdtablesize(); i++) {
123 CLOSE(i);
126 debug("Test socket() with an mismatched protocol");
128 errno = 0;
129 sd = socket(info->domain, info->type, 4);
130 if (!(sd == -1 && errno == EPROTONOSUPPORT)) {
131 test_fail("socket() should fail with errno = EPROTONOSUPPORT");
132 if (sd != -1) {
133 CLOSE(sd);
137 debug("Test socket() success");
140 * open 2 sockets at once and *then* close them.
141 * This will test that /dev/uds is cloning properly.
144 SOCKET(sd, info->domain, info->type, 0);
145 SOCKET(sd2, info->domain, info->type, 0);
147 rc = fstat(sd, &statbuf);
148 if (rc == -1) {
149 test_fail("fstat failed on sd");
152 rc = fstat(sd2, &statbuf2);
153 if (rc == -1) {
154 test_fail("fstat failed on sd2");
158 if (statbuf.st_dev == statbuf2.st_dev) {
159 test_fail("/dev/uds isn't being cloned");
162 CLOSE(sd2);
163 CLOSE(sd);
165 debug("leaving test_socket()");
168 void test_getsockname(const struct socket_test_info *info)
170 int sd;
171 int rc;
172 int on;
173 struct sockaddr_storage sock_addr;
174 socklen_t sock_addr_len;
176 SOCKET(sd, info->domain, info->type, 0);
178 on = 1;
179 (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
181 rc = bind(sd, info->serveraddr, info->serveraddrlen);
182 if (rc == -1) {
183 test_fail("bind() should have worked");
186 debug("Test getsockname() success");
188 memset(&sock_addr, '\0', sizeof(sock_addr));
189 sock_addr_len = sizeof(sock_addr);
191 rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len);
192 if (rc == -1) {
193 test_fail("getsockname() should have worked");
196 info->callback_check_sockaddr((struct sockaddr *) &sock_addr,
197 sock_addr_len, "getsockname", 1);
199 CLOSE(sd);
202 void test_bind(const struct socket_test_info *info)
204 struct sockaddr_storage sock_addr;
205 socklen_t sock_addr_len;
206 int sd;
207 int sd2;
208 int rc;
209 int on;
211 debug("entering test_bind()");
212 info->callback_cleanup();
214 debug("Test bind() success");
216 SOCKET(sd, info->domain, info->type, 0);
218 on = 1;
219 (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
221 rc = bind(sd, info->serveraddr, info->serveraddrlen);
222 if (rc == -1) {
223 test_fail("bind() should have worked");
226 debug("Test getsockname() success");
228 memset(&sock_addr, '\0', sizeof(sock_addr));
229 sock_addr_len = sizeof(sock_addr);
231 rc = getsockname(sd, (struct sockaddr *) &sock_addr, &sock_addr_len);
232 if (rc == -1) {
233 test_fail("getsockname() should have worked");
236 info->callback_check_sockaddr((struct sockaddr *) &sock_addr,
237 sock_addr_len, "getsockname", 1);
239 debug("Test bind() with a address that has already been bind()'d");
241 SOCKET(sd2, info->domain, info->type, 0);
242 errno = 0;
243 rc = bind(sd2, info->serveraddr, info->serveraddrlen);
244 if (!((rc == -1) && (errno == EADDRINUSE))) {
245 test_fail("bind() should have failed with EADDRINUSE");
247 CLOSE(sd2);
248 CLOSE(sd);
249 info->callback_cleanup();
251 debug("Test bind() with a NULL address");
253 SOCKET(sd, info->domain, info->type, 0);
254 errno = 0;
255 rc = bind(sd, (struct sockaddr *) NULL,
256 sizeof(struct sockaddr_storage));
257 if (!((rc == -1) && (errno == EFAULT))) {
258 test_fail("bind() should have failed with EFAULT");
260 CLOSE(sd);
262 debug("leaving test_bind()");
265 void test_listen(const struct socket_test_info *info)
267 int rc;
269 debug("entering test_listen()");
271 debug("Test listen() with a bad file descriptor");
273 errno = 0;
274 rc = listen(-1, 0);
275 if (!(rc == -1 && errno == EBADF)) {
276 test_fail("listen(-1, 0) should have failed");
279 debug("Test listen() with a non-socket file descriptor");
281 errno = 0;
282 rc = listen(0, 0);
283 /* Test on errno disabled here: there's currently no telling what this
284 * will return. POSIX says it should be ENOTSOCK, MINIX3 libc returns
285 * ENOSYS, and we used to test for ENOTTY here..
287 if (!(rc == -1)) {
288 test_fail("listen(0, 0) should have failed");
291 debug("leaving test_listen()");
294 void test_shutdown(const struct socket_test_info *info)
296 int how[3] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
297 int sd;
298 int rc;
299 int i;
301 debug("entering test_shutdown()");
303 /* test for each direction (read, write, read-write) */
304 for (i = 0; i < 3; i++) {
306 debug("test shutdown() with an invalid descriptor");
308 errno = 0;
309 rc = shutdown(-1, how[i]);
310 if (!(rc == -1 && errno == EBADF)) {
311 test_fail("shutdown(-1, how[i]) should have failed");
314 debug("test shutdown() with a non-socket descriptor");
316 errno = 0;
317 rc = shutdown(0, how[i]);
318 if (!(rc == -1 && errno == ENOTSOCK)) {
319 test_fail("shutdown() should have failed with "
320 "ENOTSOCK");
323 debug("test shutdown() with a socket that is not connected");
325 SOCKET(sd, info->domain, info->type, 0);
326 errno = 0;
327 rc = shutdown(sd, how[i]);
328 if (rc != 0 && !(rc == -1 && errno == ENOTCONN)) {
329 test_fail("shutdown() should have failed");
331 CLOSE(sd);
334 SOCKET(sd, info->domain, info->type, 0);
335 errno = 0;
336 rc = shutdown(sd, -1);
337 if (!(rc == -1 && errno == EINVAL)) {
338 test_fail("shutdown(sd, -1) should have failed with EINVAL");
340 CLOSE(sd);
342 debug("leaving test_shutdown()");
345 void test_close(const struct socket_test_info *info)
347 int sd, sd2;
348 int rc, i, on;
350 debug("entering test_close()");
352 info->callback_cleanup();
354 debug("Test close() success");
356 SOCKET(sd, info->domain, info->type, 0);
358 on = 1;
359 (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
361 rc = bind(sd, info->serveraddr, info->serveraddrlen);
362 if (rc != 0) {
363 test_fail("bind() should have worked");
366 CLOSE(sd);
368 debug("Close an already closed file descriptor");
370 errno = 0;
371 rc = close(sd);
372 if (!(rc == -1 && errno == EBADF)) {
373 test_fail("close(sd) should have failed with EBADF");
376 info->callback_cleanup();
378 debug("dup()'ing a file descriptor and closing both should work");
380 SOCKET(sd, info->domain, info->type, 0);
382 on = 1;
383 (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
385 rc = bind(sd, info->serveraddr, info->serveraddrlen);
386 if (rc != 0) {
387 test_fail("bind() should have worked");
390 errno = 0;
391 sd2 = dup(sd);
392 if (sd2 == -1) {
393 test_fail("dup(sd) should have worked");
394 } else {
395 CLOSE(sd2);
396 CLOSE(sd);
399 info->callback_cleanup();
401 /* Create and close a socket a bunch of times.
402 * If the implementation doesn't properly free the
403 * socket during close(), eventually socket() will
404 * fail when the internal descriptor table is full.
406 for (i = 0; i < 1024; i++) {
407 SOCKET(sd, info->domain, info->type, 0);
408 CLOSE(sd);
411 debug("leaving test_close()");
414 void test_sockopts(const struct socket_test_info *info)
416 int i;
417 int rc;
418 int sd;
419 int option_value;
420 socklen_t option_len;
422 debug("entering test_sockopts()");
424 for (i = 0; i < info->typecount; i++) {
426 SOCKET(sd, info->domain, info->types[i], 0);
428 debug("Test setsockopt() works");
430 option_value = 0;
431 option_len = sizeof(option_value);
432 errno = 0;
433 rc = getsockopt(sd, SOL_SOCKET, SO_TYPE, &option_value,
434 &option_len);
435 if (rc != 0) {
436 test_fail("setsockopt() should have worked");
439 if (option_value != info->types[i]) {
440 test_fail("SO_TYPE didn't seem to work.");
443 CLOSE(sd);
446 SOCKET(sd, info->domain, info->type, 0);
448 debug("Test setsockopt() works");
450 option_value = 0;
451 option_len = sizeof(option_value);
452 errno = 0;
453 rc = getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &option_value, &option_len);
455 if (info->expected_sndbuf >= 0 &&
456 option_value != info->expected_sndbuf) {
457 test_fail("SO_SNDBUF didn't seem to work.");
460 CLOSE(sd);
463 SOCKET(sd, info->domain, info->type, 0);
465 debug("Test setsockopt() works");
467 option_value = 0;
468 option_len = sizeof(option_value);
469 errno = 0;
470 rc = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &option_value, &option_len);
471 if (rc != 0) {
472 test_fail("getsockopt() should have worked");
475 if (info->expected_rcvbuf >= 0 &&
476 option_value != info->expected_rcvbuf) {
477 test_fail("SO_RCVBUF didn't seem to work.");
480 CLOSE(sd);
483 debug("leaving test_sockopts()");
486 void test_read(const struct socket_test_info *info)
488 int rc;
489 int fd;
490 char buf[BUFSIZE];
492 debug("entering test_read()");
494 errno = 0;
495 rc = read(-1, buf, sizeof(buf));
496 if (!(rc == -1 && errno == EBADF)) {
497 test_fail("read() should have failed with EBADF");
500 fd = open("/tmp", O_RDONLY);
501 if (fd == -1) {
502 test_fail("open(\"/tmp\", O_RDONLY) should have worked");
505 CLOSE(fd);
507 debug("leaving test_read()");
510 void test_write(const struct socket_test_info *info)
512 int rc;
513 char buf[BUFSIZE];
515 debug("entering test_write()");
517 errno = 0;
518 rc = write(-1, buf, sizeof(buf));
519 if (!(rc == -1 && errno == EBADF)) {
520 test_fail("write() should have failed with EBADF");
523 debug("leaving test_write()");
526 void test_dup(const struct socket_test_info *info)
528 struct stat info1;
529 struct stat info2;
530 int sd, sd2;
531 int rc;
532 int i, on;
534 debug("entering test_dup()");
536 info->callback_cleanup();
538 debug("Test dup()");
540 SOCKET(sd, info->domain, info->type, 0);
542 on = 1;
543 (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
545 rc = bind(sd, info->serveraddr, info->serveraddrlen);
546 if (rc != 0) {
547 test_fail("bind() should have worked");
550 errno = 0;
551 sd2 = dup(sd);
552 if (sd2 == -1) {
553 test_fail("dup(sd) should have worked");
556 rc = fstat(sd, &info1);
557 if (rc == -1) {
558 test_fail("fstat(fd, &info1) failed");
561 rc = fstat(sd2, &info2);
562 if (rc == -1) {
563 test_fail("fstat(sd, &info2) failed");
566 if (info1.st_ino != info2.st_ino) {
567 test_fail("dup() failed info1.st_ino != info2.st_ino");
570 CLOSE(sd);
571 CLOSE(sd2);
573 debug("Test dup() with a closed socket");
575 errno = 0;
576 rc = dup(sd);
577 if (!(rc == -1 && errno == EBADF)) {
578 test_fail("dup(sd) on a closed socket shouldn't have worked");
581 debug("Test dup() with socket descriptor of -1");
583 errno = 0;
584 rc = dup(-1);
585 if (!(rc == -1 && errno == EBADF)) {
586 test_fail("dup(-1) shouldn't have worked");
589 debug("Test dup() when all of the file descriptors are taken");
591 SOCKET(sd, info->domain, info->type, 0);
593 for (i = 4; i < getdtablesize(); i++) {
594 rc = open("/dev/null", O_RDONLY);
595 if (rc == -1) {
596 test_fail("we couldn't open /dev/null for read");
600 errno = 0;
601 sd2 = dup(sd);
602 if (!(sd2 == -1 && errno == EMFILE)) {
603 test_fail("dup(sd) should have failed with errno = EMFILE");
606 for (i = 3; i < getdtablesize(); i++) {
607 CLOSE(i);
610 info->callback_cleanup();
612 debug("leaving test_dup()");
615 void test_dup2(const struct socket_test_info *info)
617 struct stat info1;
618 struct stat info2;
619 int sd;
620 int fd;
621 int rc;
622 int on;
624 debug("entering test_dup2()");
625 info->callback_cleanup();
627 SOCKET(sd, info->domain, info->type, 0);
629 on = 1;
630 (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
632 rc = bind(sd, info->serveraddr, info->serveraddrlen);
633 if (rc != 0) {
634 test_fail("bind() should have worked");
637 fd = open("/dev/null", O_RDONLY);
638 if (fd == -1) {
639 test_fail("open(\"/dev/null\", O_RDONLY) failed");
642 fd = dup2(sd, fd);
643 if (fd == -1) {
644 test_fail("dup2(sd, fd) failed.");
647 memset(&info1, '\0', sizeof(struct stat));
648 memset(&info2, '\0', sizeof(struct stat));
650 rc = fstat(fd, &info1);
651 if (rc == -1) {
652 test_fail("fstat(fd, &info1) failed");
655 rc = fstat(sd, &info2);
656 if (rc == -1) {
657 test_fail("fstat(sd, &info2) failed");
660 if (!(info1.st_ino == info2.st_ino &&
661 major(info1.st_dev) == major(info2.st_dev) &&
662 minor(info1.st_dev) == minor(info2.st_dev))) {
664 test_fail("dup2() failed");
667 CLOSE(fd);
668 CLOSE(sd);
670 info->callback_cleanup();
671 debug("leaving test_dup2()");
676 * A toupper() server. This toy server converts a string to upper case.
678 static void test_xfer_server(const struct socket_test_info *info, pid_t pid)
680 int i;
681 struct timeval tv;
682 fd_set readfds;
683 int status;
684 int rc;
685 int sd;
686 int on;
687 unsigned char buf[BUFSIZE];
688 socklen_t client_addr_size;
689 int client_sd;
690 struct sockaddr_storage client_addr;
692 status = 0;
693 rc = 0;
694 sd = 0;
695 client_sd = 0;
696 client_addr_size = sizeof(struct sockaddr_storage);
698 memset(&buf, '\0', sizeof(buf));
699 memset(&client_addr, '\0', sizeof(client_addr));
701 SOCKET(sd, info->domain, info->type, 0);
703 on = 1;
704 (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
706 rc = bind(sd, info->serveraddr, info->serveraddrlen);
707 if (rc == -1) {
708 test_fail("bind() should have worked");
711 rc = listen(sd, 8);
712 if (rc == -1) {
713 test_fail("listen(sd, 8) should have worked");
716 /* we're ready for connections, time to tell the client to start
717 * the test
719 kill(pid, SIGUSR1);
721 tv.tv_sec = 10;
722 tv.tv_usec = 0;
724 FD_ZERO(&readfds);
725 FD_SET(sd, &readfds);
727 /* use select() in case the client is really broken and never
728 * attempts to connect (we don't want to block on accept()
729 * forever).
731 rc = select(sd + 1, &readfds, NULL, NULL, &tv);
732 if (rc == -1) {
733 test_fail("[server] select() should not have failed");
736 if (rc != 1) {
737 test_fail("[server] select() should have returned 1");
738 printf("[server] select returned %d\n", rc);
741 if (!(FD_ISSET(sd, &readfds))) {
742 test_fail("[server] client didn't connect within 10 seconds");
743 kill(pid, SIGKILL);
744 return;
747 client_sd = accept(sd, (struct sockaddr *) &client_addr,
748 &client_addr_size);
750 if (client_sd == -1) {
751 test_fail("accept() should have worked");
752 kill(pid, SIGKILL);
753 return;
754 } else {
755 debug("[server] client accept()'d");
758 debug("[server] Reading message");
759 rc = read(client_sd, buf, sizeof(buf));
760 if (rc == -1) {
761 test_fail("read() failed unexpectedly");
762 kill(pid, SIGKILL);
763 return;
765 debug("[server] we got the following message:");
766 debug(buf);
768 for (i = 0; i < rc && i < 127; i++) {
769 buf[i] = toupper(buf[i]);
772 debug("[server] Writing message...");
773 rc = write(client_sd, buf, sizeof(buf));
774 if (rc == -1) {
775 test_fail("write(client_sd, buf, sizeof(buf)) failed");
776 kill(pid, SIGKILL);
777 return;
780 if (rc < strlen((char *)buf)) {
781 test_fail("[server] write didn't write all the bytes");
784 memset(&buf, '\0', sizeof(buf));
786 debug("[server] Recv message");
787 rc = recv(client_sd, buf, sizeof(buf), 0);
788 if (rc == -1) {
789 test_fail("recv() failed unexpectedly");
790 kill(pid, SIGKILL);
791 return;
793 debug("[server] we got the following message:");
794 debug(buf);
796 for (i = 0; i < rc && i < 127; i++) {
797 buf[i] = toupper(buf[i]);
800 debug("[server] Sending message...");
801 rc = send(client_sd, buf, sizeof(buf), 0);
802 if (rc == -1) {
803 test_fail("send(client_sd, buf, sizeof(buf), 0) failed");
804 kill(pid, SIGKILL);
805 return;
808 if (rc < strlen((char *)buf)) {
809 test_fail("[server] write didn't write all the bytes");
812 memset(&buf, '\0', sizeof(buf));
814 debug("[server] Recvfrom message");
815 rc = recvfrom(client_sd, buf, sizeof(buf), 0, NULL, 0);
816 if (rc == -1) {
817 test_fail("recvfrom() failed unexpectedly");
818 kill(pid, SIGKILL);
819 return;
821 debug("[server] we got the following message:");
822 debug(buf);
824 for (i = 0; i < rc && i < 127; i++) {
825 buf[i] = toupper(buf[i]);
828 debug("[server] Sendto message...");
829 rc = sendto(client_sd, buf, sizeof(buf), 0, NULL, 0);
830 if (rc == -1) {
831 test_fail("sendto() failed");
832 kill(pid, SIGKILL);
833 return;
836 if (rc < strlen((char *)buf)) {
837 test_fail("[server] write didn't write all the bytes");
840 shutdown(client_sd, SHUT_RDWR);
841 CLOSE(client_sd);
843 shutdown(sd, SHUT_RDWR);
844 CLOSE(sd);
846 /* wait for client to exit */
847 do {
848 errno = 0;
849 rc = waitpid(pid, &status, 0);
850 } while (rc == -1 && errno == EINTR);
852 /* we use the exit status to get its error count */
853 errct += WEXITSTATUS(status);
856 int server_ready = 0;
858 /* signal handler for the client */
859 void test_xfer_sighdlr(int sig)
861 debug("entering signal handler");
862 switch (sig) {
863 /* the server will send SIGUSR1 when it is time for us
864 * to start the tests
866 case SIGUSR1:
867 server_ready = 1;
868 debug("got SIGUSR1, the server is ready for the client");
869 break;
870 default:
871 debug("didn't get SIGUSR1");
873 debug("leaving signal handler");
877 * A toupper() client.
879 static void test_xfer_client(const struct socket_test_info *info)
881 struct timeval tv;
882 fd_set readfds;
883 struct sockaddr_storage peer_addr;
884 socklen_t peer_addr_len;
885 int sd;
886 int rc;
887 char buf[BUFSIZE];
889 debug("[client] entering test_xfer_client()");
890 errct = 0; /* reset error count */
891 memset(&buf, '\0', sizeof(buf));
893 while (server_ready == 0) {
894 debug("[client] waiting for the server to signal");
895 sleep(1);
898 peer_addr_len = sizeof(peer_addr);
901 if (info->callback_xfer_prepclient) info->callback_xfer_prepclient();
903 debug("[client] creating client socket");
904 SOCKET(sd, info->domain, info->type, 0);
906 debug("[client] connecting to server through the symlink");
907 rc = connect(sd, info->clientaddrsym, info->clientaddrsymlen);
908 if (rc == -1) {
909 test_fail("[client] connect() should have worked");
910 } else {
911 debug("[client] connected");
914 debug("[client] testing getpeername()");
915 memset(&peer_addr, '\0', sizeof(peer_addr));
916 rc = getpeername(sd, (struct sockaddr *) &peer_addr, &peer_addr_len);
917 if (rc == -1) {
918 test_fail("[client] getpeername() should have worked");
922 info->callback_check_sockaddr((struct sockaddr *) &peer_addr,
923 peer_addr_len, "getpeername", 1);
925 strncpy(buf, "Hello, World!", sizeof(buf) - 1);
926 debug("[client] send to server");
927 rc = write(sd, buf, sizeof(buf));
928 if (rc == -1) {
929 test_fail("[client] write() failed unexpectedly");
932 memset(buf, '\0', sizeof(buf));
933 debug("[client] read from server");
934 rc = read(sd, buf, sizeof(buf));
935 if (rc == -1) {
936 test_fail("[client] read() failed unexpectedly");
937 } else {
938 debug("[client] we got the following message:");
939 debug(buf);
942 if (strncmp(buf, "HELLO, WORLD!", sizeof(buf)) != 0) {
943 test_fail("[client] We didn't get the correct response");
946 memset(&buf, '\0', sizeof(buf));
947 strncpy(buf, "Bonjour!", sizeof(buf) - 1);
949 debug("[client] send to server");
950 rc = send(sd, buf, sizeof(buf), 0);
951 if (rc == -1) {
952 test_fail("[client] send() failed unexpectedly");
955 if (info->callback_xfer_peercred) info->callback_xfer_peercred(sd);
957 debug("Testing select()");
959 tv.tv_sec = 2;
960 tv.tv_usec = 500000;
962 FD_ZERO(&readfds);
963 FD_SET(sd, &readfds);
965 rc = select(sd + 1, &readfds, NULL, NULL, &tv);
966 if (rc == -1) {
967 test_fail("[client] select() should not have failed");
970 if (rc != 1) {
971 test_fail("[client] select() should have returned 1");
974 if (!(FD_ISSET(sd, &readfds))) {
975 test_fail("The server didn't respond within 2.5 seconds");
978 memset(buf, '\0', sizeof(buf));
979 debug("[client] recv from server");
980 rc = recv(sd, buf, sizeof(buf), 0);
981 if (rc == -1) {
982 test_fail("[client] recv() failed unexpectedly");
983 } else {
984 debug("[client] we got the following message:");
985 debug(buf);
988 if (strncmp(buf, "BONJOUR!", sizeof(buf)) != 0) {
989 test_fail("[client] We didn't get the right response.");
992 memset(&buf, '\0', sizeof(buf));
993 strncpy(buf, "Hola!", sizeof(buf) - 1);
995 debug("[client] sendto to server");
996 rc = sendto(sd, buf, sizeof(buf), 0, NULL, 0);
997 if (rc == -1) {
998 test_fail("[client] sendto() failed");
1001 debug("Testing select()");
1003 tv.tv_sec = 2;
1004 tv.tv_usec = 500000;
1006 FD_ZERO(&readfds);
1007 FD_SET(sd, &readfds);
1009 rc = select(sd + 1, &readfds, NULL, NULL, &tv);
1010 if (rc == -1) {
1011 test_fail("[client] select() should not have failed");
1014 if (rc != 1) {
1015 test_fail("[client] select() should have returned 1");
1018 if (!(FD_ISSET(sd, &readfds))) {
1019 test_fail("[client] The server didn't respond in 2.5 seconds");
1022 memset(buf, '\0', sizeof(buf));
1023 debug("[client] recvfrom from server");
1024 rc = recvfrom(sd, buf, sizeof(buf), 0, NULL, 0);
1025 if (rc == -1) {
1026 test_fail("[cleint] recvfrom() failed unexpectedly");
1027 } else {
1028 debug("[client] we got the following message:");
1029 debug(buf);
1032 if (strncmp(buf, "HOLA!", sizeof(buf)) != 0) {
1033 test_fail("[client] We didn't get the right response.");
1036 debug("[client] closing socket");
1037 CLOSE(sd);
1039 debug("[client] leaving test_xfer_client()");
1040 exit(errct);
1043 void test_xfer(const struct socket_test_info *info)
1045 pid_t pid;
1047 debug("entering test_xfer()");
1048 info->callback_cleanup();
1050 /* the signal handler is only used by the client, but we have to
1051 * install it now. if we don't the server may signal the client
1052 * before the handler is installed.
1054 debug("installing signal handler");
1055 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1056 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1059 debug("signal handler installed");
1061 server_ready = 0;
1063 pid = fork();
1064 if (pid == -1) {
1065 test_fail("fork() failed");
1066 return;
1067 } else if (pid == 0) {
1068 debug("child");
1069 errct = 0;
1070 test_xfer_client(info);
1071 test_fail("we should never get here");
1072 exit(1);
1073 } else {
1074 debug("parent");
1075 test_xfer_server(info, pid);
1076 debug("parent done");
1079 info->callback_cleanup();
1080 debug("leaving test_xfer()");
1083 static void test_simple_client(const struct socket_test_info *info, int type)
1085 char buf[BUFSIZE];
1086 int sd, rc;
1088 sd = socket(info->domain, type, 0);
1089 if (sd == -1) {
1090 test_fail("socket");
1091 exit(errct);
1094 while (server_ready == 0) {
1095 debug("[client] waiting for the server");
1096 sleep(1);
1099 bzero(buf, BUFSIZE);
1100 snprintf(buf, BUFSIZE-1, "Hello, My Name is Client.");
1102 if (type == SOCK_DGRAM) {
1104 rc = sendto(sd, buf, strlen(buf) + 1, 0,
1105 info->clientaddr, info->clientaddrlen);
1106 if (rc == -1) {
1107 test_fail("sendto");
1108 exit(errct);
1111 } else {
1113 rc = connect(sd, info->clientaddr, info->clientaddrlen);
1114 if (rc == -1) {
1115 test_fail("connect");
1116 exit(errct);
1119 rc = write(sd, buf, strlen(buf) + 1);
1121 if (rc == -1) {
1122 test_fail("write");
1125 memset(buf, '\0', BUFSIZE);
1126 rc = read(sd, buf, BUFSIZE);
1127 if (rc == -1) {
1128 test_fail("read");
1131 if (strcmp("Hello, My Name is Server.", buf) != 0) {
1132 test_fail("didn't read the correct string");
1136 rc = close(sd);
1137 if (rc == -1) {
1138 test_fail("close");
1141 exit(errct);
1144 static void test_simple_server(const struct socket_test_info *info, int type,
1145 pid_t pid)
1147 char buf[BUFSIZE];
1148 int sd, rc, client_sd, status, on;
1149 struct sockaddr_storage addr;
1150 socklen_t addr_len;
1152 addr_len = info->clientaddrlen;
1154 sd = socket(info->domain, type, 0);
1155 if (sd == -1) {
1156 test_fail("socket");
1159 on = 1;
1160 (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1162 assert(info->clientaddrlen <= sizeof(addr));
1163 memcpy(&addr, info->clientaddr, info->clientaddrlen);
1165 rc = bind(sd, info->serveraddr, info->serveraddrlen);
1166 if (rc == -1) {
1167 test_fail("bind");
1170 if (type == SOCK_DGRAM) {
1172 /* ready for client */
1173 kill(pid, SIGUSR1);
1175 rc = recvfrom(sd, buf, BUFSIZE, 0,
1176 (struct sockaddr *) &addr, &addr_len);
1177 if (rc == -1) {
1178 test_fail("recvfrom");
1181 } else {
1183 rc = listen(sd, 5);
1184 if (rc == -1) {
1185 test_fail("listen");
1188 /* we're ready for connections, time to tell the client
1189 * to start the test
1191 kill(pid, SIGUSR1);
1193 client_sd = accept(sd, (struct sockaddr *) &addr, &addr_len);
1194 if (client_sd == -1) {
1195 test_fail("accept");
1198 memset(buf, '\0', BUFSIZE);
1199 rc = read(client_sd, buf, BUFSIZE);
1200 if (rc == -1) {
1201 test_fail("read");
1204 if (strcmp("Hello, My Name is Client.", buf) != 0) {
1205 test_fail("didn't read the correct string");
1208 /* added for extra fun to make the client block on read() */
1209 sleep(1);
1211 bzero(buf, BUFSIZE);
1212 snprintf(buf, BUFSIZE-1, "Hello, My Name is Server.");
1214 rc = write(client_sd, buf, strlen(buf) + 1);
1215 if (rc == -1) {
1216 test_fail("write");
1218 rc = close(client_sd);
1219 if (rc == -1) {
1220 test_fail("close");
1224 rc = close(sd);
1225 if (rc == -1) {
1226 test_fail("close");
1229 /* wait for client to exit */
1230 do {
1231 errno = 0;
1232 rc = waitpid(pid, &status, 0);
1233 } while (rc == -1 && errno == EINTR);
1235 /* we use the exit status to get its error count */
1236 errct += WEXITSTATUS(status);
1239 static void test_abort_client(const struct socket_test_info *info,
1240 int abort_type);
1241 static void test_abort_server(const struct socket_test_info *info,
1242 pid_t pid, int abort_type);
1244 void test_abort_client_server(const struct socket_test_info *info,
1245 int abort_type)
1247 pid_t pid;
1249 debug("test_simple_client_server()");
1251 info->callback_cleanup();
1253 /* the signal handler is only used by the client, but we have to
1254 * install it now. if we don't the server may signal the client
1255 * before the handler is installed.
1257 debug("installing signal handler");
1258 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1259 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1262 debug("signal handler installed");
1264 server_ready = 0;
1266 pid = fork();
1267 if (pid == -1) {
1268 test_fail("fork() failed");
1269 return;
1270 } else if (pid == 0) {
1271 debug("child");
1272 errct = 0;
1273 test_abort_client(info, abort_type);
1274 test_fail("we should never get here");
1275 exit(1);
1276 } else {
1277 debug("parent");
1278 test_abort_server(info, pid, abort_type);
1279 debug("parent done");
1282 info->callback_cleanup();
1285 static void test_abort_client(const struct socket_test_info *info,
1286 int abort_type)
1288 char buf[BUFSIZE];
1289 int sd, rc;
1291 sd = socket(info->domain, info->type, 0);
1292 if (sd == -1) {
1293 test_fail("socket");
1294 exit(errct);
1297 while (server_ready == 0) {
1298 debug("[client] waiting for the server");
1299 sleep(1);
1302 bzero(buf, BUFSIZE);
1303 snprintf(buf, BUFSIZE-1, "Hello, My Name is Client.");
1305 rc = connect(sd, info->clientaddr, info->clientaddrlen);
1306 if (rc == -1) {
1307 test_fail("connect");
1308 exit(errct);
1311 if (abort_type == 2) {
1312 /* Give server a chance to close connection */
1313 sleep(2);
1314 rc = write(sd, buf, strlen(buf) + 1);
1315 if (rc != -1) {
1316 if (!info->ignore_write_conn_reset) {
1317 test_fail("write should have failed\n");
1319 } else if (errno != EPIPE && errno != ECONNRESET) {
1320 test_fail("errno should've been EPIPE/ECONNRESET\n");
1324 rc = close(sd);
1325 if (rc == -1) {
1326 test_fail("close");
1329 exit(errct);
1332 static void test_abort_server(const struct socket_test_info *info,
1333 pid_t pid, int abort_type)
1335 char buf[BUFSIZE];
1336 int sd, rc, client_sd, status, on;
1337 struct sockaddr_storage addr;
1338 socklen_t addr_len;
1340 addr_len = info->clientaddrlen;
1342 sd = socket(info->domain, info->type, 0);
1343 if (sd == -1) {
1344 test_fail("socket");
1347 on = 1;
1348 (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1350 assert(sizeof(addr) >= info->clientaddrlen);
1351 memcpy(&addr, info->clientaddr, info->clientaddrlen);
1353 rc = bind(sd, info->serveraddr, info->serveraddrlen);
1354 if (rc == -1) {
1355 test_fail("bind");
1358 rc = listen(sd, 5);
1359 if (rc == -1) {
1360 test_fail("listen");
1363 /* we're ready for connections, time to tell the client
1364 * to start the test
1366 kill(pid, SIGUSR1);
1368 client_sd = accept(sd, (struct sockaddr *) &addr, &addr_len);
1369 if (client_sd == -1) {
1370 test_fail("accept");
1373 if (abort_type == 1) {
1374 memset(buf, '\0', BUFSIZE);
1375 rc = read(client_sd, buf, BUFSIZE);
1376 if (rc != 0 && rc != -1) {
1377 test_fail("read should've failed or returned zero\n");
1379 if (rc != 0 && errno != ECONNRESET) {
1380 test_fail("errno should've been ECONNRESET\n");
1382 } /* else if (abort_type == 2) { */
1383 rc = close(client_sd);
1384 if (rc == -1) {
1385 test_fail("close");
1387 /* } */
1389 rc = close(sd);
1390 if (rc == -1) {
1391 test_fail("close");
1394 /* wait for client to exit */
1395 do {
1396 errno = 0;
1397 rc = waitpid(pid, &status, 0);
1398 } while (rc == -1 && errno == EINTR);
1400 /* we use the exit status to get its error count */
1401 errct += WEXITSTATUS(status);
1404 void test_simple_client_server(const struct socket_test_info *info, int type)
1406 pid_t pid;
1408 debug("entering test_simple_client_server()");
1410 info->callback_cleanup();
1412 /* the signal handler is only used by the client, but we have to
1413 * install it now. if we don't the server may signal the client
1414 * before the handler is installed.
1416 debug("installing signal handler");
1417 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1418 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1421 debug("signal handler installed");
1423 server_ready = 0;
1425 pid = fork();
1426 if (pid == -1) {
1427 test_fail("fork() failed");
1428 return;
1429 } else if (pid == 0) {
1430 debug("child");
1431 errct = 0;
1432 test_simple_client(info, type);
1433 test_fail("we should never get here");
1434 exit(1);
1435 } else {
1436 debug("parent");
1437 test_simple_server(info, type, pid);
1438 debug("parent done");
1441 info->callback_cleanup();
1442 debug("leaving test_simple_client_server()");
1445 void test_msg_dgram(const struct socket_test_info *info)
1447 int rc;
1448 int src;
1449 int dst;
1450 struct sockaddr_storage addr;
1451 struct iovec iov[3];
1452 struct msghdr msg1;
1453 struct msghdr msg2;
1454 char buf1[BUFSIZE];
1455 char buf2[BUFSIZE];
1456 char buf3[BUFSIZE];
1458 debug("entering test_msg_dgram");
1460 info->callback_cleanup();
1462 src = socket(info->domain, SOCK_DGRAM, 0);
1463 if (src == -1) {
1464 test_fail("socket");
1467 dst = socket(info->domain, SOCK_DGRAM, 0);
1468 if (dst == -1) {
1469 test_fail("socket");
1472 rc = bind(src, info->serveraddr2, info->serveraddr2len);
1473 if (rc == -1) {
1474 test_fail("bind");
1477 assert(info->clientaddrlen <= sizeof(addr));
1478 memcpy(&addr, info->clientaddr, info->clientaddrlen);
1480 rc = bind(dst, info->serveraddr, info->serveraddrlen);
1481 if (rc == -1) {
1482 test_fail("bind");
1485 memset(&buf1, '\0', BUFSIZE);
1486 memset(&buf2, '\0', BUFSIZE);
1487 memset(&buf3, '\0', BUFSIZE);
1489 strncpy(buf1, "Minix ", BUFSIZE-1);
1490 strncpy(buf2, "is ", BUFSIZE-1);
1491 strncpy(buf3, "great!", BUFSIZE-1);
1493 iov[0].iov_base = buf1;
1494 iov[0].iov_len = 6;
1495 iov[1].iov_base = buf2;
1496 iov[1].iov_len = 3;
1497 iov[2].iov_base = buf3;
1498 iov[2].iov_len = 32;
1500 memset(&msg1, '\0', sizeof(struct msghdr));
1501 msg1.msg_name = &addr;
1502 msg1.msg_namelen = info->clientaddrlen;
1503 msg1.msg_iov = iov;
1504 msg1.msg_iovlen = 3;
1505 msg1.msg_control = NULL;
1506 msg1.msg_controllen = 0;
1507 msg1.msg_flags = 0;
1509 rc = sendmsg(src, &msg1, 0);
1510 if (rc == -1) {
1511 test_fail("sendmsg");
1514 memset(&buf1, '\0', BUFSIZE);
1515 memset(&buf2, '\0', BUFSIZE);
1517 iov[0].iov_base = buf1;
1518 iov[0].iov_len = 9;
1519 iov[1].iov_base = buf2;
1520 iov[1].iov_len = 32;
1522 memset(&addr, '\0', sizeof(addr));
1523 memset(&msg2, '\0', sizeof(struct msghdr));
1524 msg2.msg_name = &addr;
1525 msg2.msg_namelen = sizeof(addr);
1526 msg2.msg_iov = iov;
1527 msg2.msg_iovlen = 2;
1528 msg2.msg_control = NULL;
1529 msg2.msg_controllen = 0;
1530 msg2.msg_flags = 0;
1532 rc = recvmsg(dst, &msg2, 0);
1533 if (rc == -1) {
1534 test_fail("recvmsg");
1537 if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
1538 test_fail("recvmsg");
1541 info->callback_check_sockaddr((struct sockaddr *) &addr,
1542 msg2.msg_namelen, "recvmsg", 2);
1544 rc = close(dst);
1545 if (rc == -1) {
1546 test_fail("close");
1549 rc = close(src);
1550 if (rc == -1) {
1551 test_fail("close");
1554 info->callback_cleanup();
1555 debug("leaving test_msg_dgram");
1558 #define check_select(sd, rd, wr, block) \
1559 check_select_internal(sd, rd, wr, block, 1, __LINE__)
1560 #define check_select_cond(sd, rd, wr, block, allchecks) \
1561 check_select_internal(sd, rd, wr, block, allchecks, __LINE__)
1563 static void
1564 check_select_internal(int sd, int rd, int wr, int block, int allchecks, int line)
1566 fd_set read_set, write_set;
1567 struct timeval tv;
1569 FD_ZERO(&read_set);
1570 if (rd != -1)
1571 FD_SET(sd, &read_set);
1573 FD_ZERO(&write_set);
1574 if (wr != -1)
1575 FD_SET(sd, &write_set);
1577 tv.tv_sec = block ? 2 : 0;
1578 tv.tv_usec = 0;
1580 errno = 0;
1581 if (select(sd + 1, &read_set, &write_set, NULL, &tv) < 0)
1582 test_fail_fl("select() failed unexpectedly", __FILE__, line);
1584 if (rd != -1 && !!FD_ISSET(sd, &read_set) != rd && allchecks)
1585 test_fail_fl("select() mismatch on read operation",
1586 __FILE__, line);
1588 if (wr != -1 && !!FD_ISSET(sd, &write_set) != wr && allchecks)
1589 test_fail_fl("select() mismatch on write operation",
1590 __FILE__, line);
1594 * Verify that:
1595 * - a nonblocking connecting socket for which there is no accepter, will
1596 * return EINPROGRESS and complete in the background later;
1597 * - a nonblocking listening socket will return EAGAIN on accept;
1598 * - connecting a connecting socket yields EALREADY;
1599 * - connecting a connected socket yields EISCONN;
1600 * - selecting for read and write on a connecting socket will only satisfy the
1601 * write only once it is connected;
1602 * - doing a nonblocking write on a connecting socket yields EAGAIN;
1603 * - doing a nonblocking read on a connected socket with no pending data yields
1604 * EAGAIN.
1606 void
1607 test_nonblock(const struct socket_test_info *info)
1609 char buf[BUFSIZE];
1610 socklen_t len;
1611 int server_sd, client_sd;
1612 struct sockaddr_storage addr;
1613 int status, on;
1615 debug("entering test_nonblock()");
1616 memset(buf, 0, sizeof(buf));
1618 SOCKET(server_sd, info->domain, info->type, 0);
1620 on = 1;
1621 (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1623 if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
1624 test_fail("bind() should have worked");
1626 if (info->callback_set_listen_opt != NULL)
1627 info->callback_set_listen_opt(server_sd);
1629 if (listen(server_sd, 8) == -1)
1630 test_fail("listen() should have worked");
1632 fcntl(server_sd, F_SETFL, fcntl(server_sd, F_GETFL) | O_NONBLOCK);
1634 check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1636 len = sizeof(addr);
1637 if (accept(server_sd, (struct sockaddr *) &addr, &len) != -1 ||
1638 errno != EAGAIN)
1639 test_fail("accept() should have yielded EAGAIN");
1641 SOCKET(client_sd, info->domain, info->type, 0);
1643 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK);
1645 if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) {
1646 test_fail("connect() should have failed");
1647 } else if (errno != EINPROGRESS) {
1648 test_fail("connect() should have yielded EINPROGRESS");
1651 check_select_cond(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/,
1652 !info->ignore_select_delay);
1654 if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) {
1655 test_fail("connect() should have failed");
1656 } else if (errno != EALREADY && errno != EISCONN) {
1657 test_fail("connect() should have yielded EALREADY");
1660 if (recv(client_sd, buf, sizeof(buf), 0) != -1 || errno != EAGAIN)
1661 test_fail("recv() should have yielded EAGAIN");
1663 /* This may be an implementation aspect, or even plain wrong (?). */
1664 if (!info->ignore_send_waiting) {
1665 if (send(client_sd, buf, sizeof(buf), 0) != -1) {
1666 test_fail("send() should have failed");
1667 } else if (errno != EAGAIN) {
1668 test_fail("send() should have yielded EAGAIN");
1672 switch (fork()) {
1673 case 0:
1674 errct = 0;
1675 close(client_sd);
1677 check_select(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1679 len = sizeof(addr);
1680 client_sd = accept(server_sd, (struct sockaddr *) &addr, &len);
1681 if (client_sd == -1)
1682 test_fail("accept() should have succeeded");
1684 check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1686 close(server_sd);
1688 /* Let the socket become writable in the parent process. */
1689 sleep(1);
1691 if (write(client_sd, buf, 1) != 1)
1692 test_fail("write() should have succeeded");
1694 /* Wait for the client side to close. */
1695 check_select_cond(client_sd, 0 /*read*/, 1 /*write*/,
1696 0 /*block*/, !info->ignore_select_delay /*allchecks*/);
1697 check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/);
1698 check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1700 exit(errct);
1701 case -1:
1702 test_fail("can't fork");
1703 default:
1704 break;
1707 close(server_sd);
1709 check_select(client_sd, 0 /*read*/, 1 /*write*/, 1 /*block*/);
1710 check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1712 if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1 ||
1713 errno != EISCONN)
1714 test_fail("connect() should have yielded EISCONN");
1716 check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/);
1717 check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1719 if (read(client_sd, buf, 1) != 1)
1720 test_fail("read() should have succeeded");
1722 check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1724 if (read(client_sd, buf, 1) != -1 || errno != EAGAIN)
1725 test_fail("read() should have yielded EAGAIN");
1727 /* Let the child process block on the select waiting for the close. */
1728 sleep(1);
1730 close(client_sd);
1732 errno = 0;
1733 if (wait(&status) <= 0)
1734 test_fail("wait() should have succeeded");
1735 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
1736 test_fail("child process failed the test");
1738 info->callback_cleanup();
1739 debug("leaving test_nonblock()");
1743 * Verify that a nonblocking connect for which there is an accepter, succeeds
1744 * immediately. A pretty lame test, only here for completeness.
1746 void
1747 test_connect_nb(const struct socket_test_info *info)
1749 socklen_t len;
1750 int server_sd, client_sd;
1751 struct sockaddr_storage addr;
1752 int status, on;
1754 debug("entering test_connect_nb()");
1755 SOCKET(server_sd, info->domain, info->type, 0);
1757 on = 1;
1758 (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1760 if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
1761 test_fail("bind() should have worked");
1763 if (listen(server_sd, 8) == -1)
1764 test_fail("listen() should have worked");
1766 switch (fork()) {
1767 case 0:
1768 errct = 0;
1769 len = sizeof(addr);
1770 if (accept(server_sd, (struct sockaddr *) &addr, &len) == -1)
1771 test_fail("accept() should have succeeded");
1773 exit(errct);
1774 case -1:
1775 test_fail("can't fork");
1776 default:
1777 break;
1780 close(server_sd);
1782 sleep(1);
1784 SOCKET(client_sd, info->domain, info->type, 0);
1786 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK);
1788 if (connect(client_sd, info->clientaddr, info->clientaddrlen) != 0) {
1789 if (!info->ignore_connect_delay) {
1790 test_fail("connect() should have succeeded");
1791 } else if (errno != EINPROGRESS) {
1792 test_fail("connect() should have succeeded or "
1793 "failed with EINPROGRESS");
1797 close(client_sd);
1799 if (wait(&status) <= 0)
1800 test_fail("wait() should have succeeded");
1801 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
1802 test_fail("child process failed the test");
1804 info->callback_cleanup();
1805 debug("leaving test_connect_nb()");
1808 static void
1809 dummy_handler(int sig)
1811 /* Nothing. */
1815 * Verify that:
1816 * - interrupting a blocking connect will return EINTR but complete in the
1817 * background later;
1818 * - doing a blocking write on an asynchronously connecting socket succeeds
1819 * once the socket is connected.
1820 * - doing a nonblocking write on a connected socket with lots of pending data
1821 * yields EAGAIN.
1823 void
1824 test_intr(const struct socket_test_info *info)
1826 struct sigaction act, oact;
1827 char buf[BUFSIZE];
1828 int isconn;
1829 socklen_t len;
1830 int server_sd, client_sd;
1831 struct sockaddr_storage addr;
1832 int r, status, on;
1834 debug("entering test_intr()");
1835 memset(buf, 0, sizeof(buf));
1837 SOCKET(server_sd, info->domain, info->type, 0);
1839 on = 1;
1840 (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1842 if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
1843 test_fail("bind() should have worked");
1845 if (info->callback_set_listen_opt != NULL)
1846 info->callback_set_listen_opt(server_sd);
1848 if (listen(server_sd, 8) == -1)
1849 test_fail("listen() should have worked");
1851 SOCKET(client_sd, info->domain, info->type, 0);
1853 memset(&act, 0, sizeof(act));
1854 act.sa_handler = dummy_handler;
1855 if (sigaction(SIGALRM, &act, &oact) == -1)
1856 test_fail("sigaction() should have succeeded");
1858 if (info->domain != PF_INET) alarm(1);
1860 isconn = 0;
1861 if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) {
1862 if (!info->ignore_connect_unaccepted) {
1863 test_fail("connect() should have failed");
1865 isconn = 1;
1866 } else if (errno != EINTR) {
1867 test_fail("connect() should have yielded EINTR");
1870 alarm(0);
1872 check_select(client_sd, 0 /*read*/, isconn /*write*/, 0 /*block*/);
1874 switch (fork()) {
1875 case 0:
1876 errct = 0;
1877 close(client_sd);
1879 /* Ensure that the parent is blocked on the send(). */
1880 sleep(1);
1882 check_select(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1884 len = sizeof(addr);
1885 client_sd = accept(server_sd, (struct sockaddr *) &addr, &len);
1886 if (client_sd == -1)
1887 test_fail("accept() should have succeeded");
1889 check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1891 close(server_sd);
1893 check_select(client_sd, 1 /*read*/, -1 /*write*/, 1 /*block*/);
1894 check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1896 if (recv(client_sd, buf, sizeof(buf), 0) != sizeof(buf))
1897 test_fail("recv() should have yielded bytes");
1899 /* No partial transfers should be happening. */
1900 check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1902 sleep(1);
1904 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) |
1905 O_NONBLOCK);
1907 /* We can only test nonblocking writes by filling the pipe. */
1908 while ((r = write(client_sd, buf, sizeof(buf))) > 0);
1910 if (r != -1) {
1911 test_fail("write() should have failed");
1912 } else if (errno != EAGAIN) {
1913 test_fail("write() should have yielded EAGAIN");
1916 check_select(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/);
1918 if (write(client_sd, buf, 1) != -1) {
1919 test_fail("write() should have failed");
1920 } else if (errno != EAGAIN) {
1921 test_fail("write() should have yielded EAGAIN");
1924 exit(errct);
1925 case -1:
1926 test_fail("can't fork");
1927 default:
1928 break;
1931 close(server_sd);
1933 if (send(client_sd, buf, sizeof(buf), 0) != sizeof(buf))
1934 test_fail("send() should have succeded");
1936 check_select(client_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1938 if (wait(&status) <= 0)
1939 test_fail("wait() should have succeeded");
1940 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
1941 test_fail("child process failed the test");
1943 check_select(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/);
1945 close(client_sd);
1947 sigaction(SIGALRM, &oact, NULL);
1949 info->callback_cleanup();
1950 debug("leaving test_intr()");
1954 * Verify that closing a connecting socket before it is accepted will result in
1955 * no activity on the accepting side later.
1957 void
1958 test_connect_close(const struct socket_test_info *info)
1960 int server_sd, client_sd, sd, on;
1961 struct sockaddr_storage addr;
1962 socklen_t len;
1964 debug("entering test_connect_close()");
1965 SOCKET(server_sd, info->domain, info->type, 0);
1967 on = 1;
1968 (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1970 if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
1971 test_fail("bind() should have worked");
1973 if (info->callback_set_listen_opt != NULL)
1974 info->callback_set_listen_opt(server_sd);
1976 if (listen(server_sd, 8) == -1)
1977 test_fail("listen() should have worked");
1979 fcntl(server_sd, F_SETFL, fcntl(server_sd, F_GETFL) | O_NONBLOCK);
1981 check_select(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/);
1983 SOCKET(client_sd, info->domain, info->type, 0);
1985 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK);
1987 if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1 ||
1988 errno != EINPROGRESS)
1989 test_fail("connect() should have yielded EINPROGRESS");
1991 check_select_cond(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/,
1992 !info->ignore_select_delay);
1993 check_select_cond(server_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/,
1994 !info->ignore_select_delay);
1996 close(client_sd);
1998 check_select_cond(server_sd, 0 /*read*/, 1 /*write*/, 0 /*block*/,
1999 !info->ignore_select_delay);
2001 len = sizeof(addr);
2002 errno = 0;
2003 if ((sd = accept(server_sd, (struct sockaddr *) &addr, &len)) != -1) {
2004 if (!info->ignore_accept_delay) {
2005 test_fail("accept() should have failed");
2007 close(sd);
2008 } else if (errno != EAGAIN) {
2009 test_fail("accept() should have yielded EAGAIN");
2011 close(server_sd);
2013 info->callback_cleanup();
2014 debug("leaving test_connect_close()");
2018 * Verify that closing a listening socket will cause a blocking connect to fail
2019 * with ECONNRESET, and that a subsequent write will yield EPIPE. This test
2020 * works only if the connect(2) does not succeed before accept(2) is called at
2021 * all, which means it is limited to UDS with LOCAL_CONNWAIT right now.
2023 void
2024 test_listen_close(const struct socket_test_info *info)
2026 int server_sd, client_sd;
2027 int status, on;
2028 char byte;
2030 debug("entering test_listen_close()");
2031 SOCKET(server_sd, info->domain, info->type, 0);
2033 on = 1;
2034 (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
2036 if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
2037 test_fail("bind() should have worked");
2039 if (info->callback_set_listen_opt != NULL)
2040 info->callback_set_listen_opt(server_sd);
2042 if (listen(server_sd, 8) == -1)
2043 test_fail("listen() should have worked");
2045 switch (fork()) {
2046 case 0:
2047 sleep(1);
2049 exit(0);
2050 case -1:
2051 test_fail("can't fork");
2052 default:
2053 break;
2056 close(server_sd);
2058 SOCKET(client_sd, info->domain, info->type, 0);
2060 byte = 0;
2061 if (write(client_sd, &byte, 1) != -1 || errno != ENOTCONN)
2062 test_fail("write() should have yielded ENOTCONN");
2064 if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) {
2065 test_fail("connect() should have failed");
2066 } else if (errno != ECONNRESET) {
2067 test_fail("connect() should have yielded ECONNRESET");
2071 * The error we get on the next write() depends on whether the socket
2072 * may be reused after a failed connect. For UDS, it may be, so we get
2073 * ENOTCONN. Otherwise we would expect EPIPE.
2075 if (write(client_sd, &byte, 1) != -1 || errno != ENOTCONN)
2076 test_fail("write() should have yielded ENOTCONN");
2078 close(client_sd);
2080 if (wait(&status) <= 0)
2081 test_fail("wait() should have succeeded");
2082 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
2083 test_fail("child process failed the test");
2085 info->callback_cleanup();
2086 debug("leaving test_listen_close()");
2090 * Verify that closing a listening socket will cause a nonblocking connect to
2091 * result in the socket becoming readable and writable, and yielding ECONNRESET
2092 * and EPIPE on the next two writes, respectively.
2094 void
2095 test_listen_close_nb(const struct socket_test_info *info)
2097 int server_sd, client_sd;
2098 int status, on;
2099 char byte;
2101 debug("entering test_listen_close_nb()");
2102 SOCKET(server_sd, info->domain, info->type, 0);
2104 on = 1;
2105 (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
2107 if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
2108 test_fail("bind() should have worked");
2110 if (info->callback_set_listen_opt != NULL)
2111 info->callback_set_listen_opt(server_sd);
2113 if (listen(server_sd, 8) == -1)
2114 test_fail("listen() should have worked");
2116 switch (fork()) {
2117 case 0:
2118 sleep(1);
2120 exit(0);
2121 case -1:
2122 test_fail("can't fork");
2123 default:
2124 break;
2127 close(server_sd);
2129 SOCKET(client_sd, info->domain, info->type, 0);
2131 fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK);
2133 if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1 ||
2134 errno != EINPROGRESS)
2135 test_fail("connect() should have yielded EINPROGRESS");
2137 check_select_cond(client_sd, 0 /*read*/, 0 /*write*/, 0 /*block*/,
2138 !info->ignore_select_delay);
2139 check_select_cond(client_sd, 1 /*read*/, 1 /*write*/, 1 /*block*/,
2140 !info->ignore_select_delay);
2142 byte = 0;
2143 if (write(client_sd, &byte, 1) != -1) {
2144 if (!info->ignore_write_conn_reset) {
2145 test_fail("write() should have failed");
2147 } else if (errno != ECONNRESET) {
2148 test_fail("write() should have yielded ECONNRESET");
2151 check_select_cond(client_sd, 1 /*read*/, 1 /*write*/, 0 /*block*/,
2152 !info->ignore_select_delay);
2154 close(client_sd);
2156 if (wait(&status) <= 0)
2157 test_fail("wait() should have succeeded");
2158 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
2159 test_fail("child process failed the test");
2161 info->callback_cleanup();
2162 debug("leaving test_listen_close_nb()");