diff options
author | Marco S Hyman <marc@cvs.openbsd.org> | 2002-10-10 00:45:21 +0000 |
---|---|---|
committer | Marco S Hyman <marc@cvs.openbsd.org> | 2002-10-10 00:45:21 +0000 |
commit | b4cc30588310e4a96d6ca1572f9c9f0a7424673c (patch) | |
tree | 2f310ae27a0b005e37c1a36dbfe7cebf47d27d61 /regress/lib/libpthread/socket | |
parent | 7fe821d45d2fd0c6ca0edd62f5b4efcf9e53e4b0 (diff) |
add socket test to check blocking/non-blocking mode on accept.
Enable test in makefile
Diffstat (limited to 'regress/lib/libpthread/socket')
-rw-r--r-- | regress/lib/libpthread/socket/3/Makefile | 6 | ||||
-rw-r--r-- | regress/lib/libpthread/socket/3/socket3.c | 121 | ||||
-rw-r--r-- | regress/lib/libpthread/socket/Makefile | 4 |
3 files changed, 129 insertions, 2 deletions
diff --git a/regress/lib/libpthread/socket/3/Makefile b/regress/lib/libpthread/socket/3/Makefile new file mode 100644 index 00000000000..a958deccdec --- /dev/null +++ b/regress/lib/libpthread/socket/3/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2002/10/10 00:45:20 marc Exp $ + +PROG= socket3 +CFLAGS+= -I${.CURDIR}/../../include + +.include <bsd.regress.mk> diff --git a/regress/lib/libpthread/socket/3/socket3.c b/regress/lib/libpthread/socket/3/socket3.c new file mode 100644 index 00000000000..03242f6768f --- /dev/null +++ b/regress/lib/libpthread/socket/3/socket3.c @@ -0,0 +1,121 @@ +/* $OpenBSD: socket3.c,v 1.1 2002/10/10 00:45:20 marc Exp $ */ +/* PUBLIC DOMAIN Oct 2002 <marc@snafu.org> */ + +/* Test blocking/non-blocking mode inheritance on accept */ + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <fcntl.h> +#include <poll.h> +#include <pthread.h> +#include <string.h> +#include <unistd.h> + +#include "test.h" + +/* + * connect to the test port passed in arg, then close the connection + * and return. + */ +void * +sock_connect(void *arg) +{ + struct sockaddr_in sin; + int port; + int sock; + + SET_NAME("connect"); + port = (int)arg; + CHECKe(sock = socket(AF_INET, SOCK_STREAM, 0)); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + CHECKe(connect(sock, (struct sockaddr *)&sin, sizeof sin)); + CHECKe(close(sock)); + return NULL; +} + +/* + * listen for a connection, accept it using a non-blocking socket, and + * verify that the blocking mode of the socket returned from accept is + * also non-blocking + */ +void * +sock_accept(void *arg) +{ + pthread_t connect_thread; + struct pollfd fds; + struct sockaddr_in sa; + struct sockaddr accept_sa; + int accept_fd; + int accept_sa_size; + int flags; + int listen_fd; + int port; + + SET_NAME("accept"); + + /* listen for a connection */ + + port = 6543; + memset(&sa, 0, sizeof sa); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sa.sin_port = htons(port); + CHECKe(listen_fd = socket(AF_INET, SOCK_STREAM, 0)); + printf("listen_fd = %d\n", listen_fd); + while (1) { + if (bind(listen_fd, (struct sockaddr *)&sa, sizeof(sa)) == 0) + break; + if (errno == EADDRINUSE) { + sa.sin_port = htons(++port); + continue; + } + DIE(errno, "bind"); + } + CHECKe(listen(listen_fd, 2)); + + /* Create another thread to connect to the listening socket. */ + CHECKr(pthread_create(&connect_thread, NULL, sock_connect, + (void*)port)); + + /* + * Use poll to check for a pending connection as the socket + * passed to accept will be in non-blocking mode. + */ + fds.fd = listen_fd; + fds.events = POLLIN; + CHECKe(poll(&fds, 1, INFTIM)); + + /* + * set non blocking mode on the listening socket and close stdin + * (fd 0) so the accept will use fd 0 (needed to test boundary + * condition in the pthread accept code). + */ + flags = fcntl(listen_fd, F_GETFL); + CHECKr(fcntl(listen_fd, F_SETFL, flags |= O_NONBLOCK)); + CHECKe(close(STDIN_FILENO)); + accept_sa_size = sizeof accept_sa; + CHECKe(accept_fd = accept(listen_fd, &accept_sa, &accept_sa_size)); + flags = fcntl(accept_fd, F_GETFL); + printf("accept_fd = %d, flags = %x\n", accept_fd, flags); + /* XXX the above should abort if flags & O_NOBLOCK is zero */ + /* ASSERT(flags & O_NONBLOCK); */ + CHECKe(close(listen_fd)); + CHECKe(close(accept_fd)); + CHECKr(pthread_join(connect_thread, NULL)); + return NULL; +} + +int +main(int argc, char * argv[]) +{ + pthread_t accept_thread; + + CHECKr(pthread_create(&accept_thread, NULL, sock_accept, NULL)); + CHECKr(pthread_join(accept_thread, NULL)); + SUCCEED; +} diff --git a/regress/lib/libpthread/socket/Makefile b/regress/lib/libpthread/socket/Makefile index a1a150efd7f..5b242a0faaf 100644 --- a/regress/lib/libpthread/socket/Makefile +++ b/regress/lib/libpthread/socket/Makefile @@ -1,5 +1,5 @@ -# $OpenBSD: Makefile,v 1.2 2002/02/23 01:25:11 art Exp $ +# $OpenBSD: Makefile,v 1.3 2002/10/10 00:45:20 marc Exp $ -SUBDIR= 1 2a 2 +SUBDIR= 1 2a 2 3 .include <bsd.subdir.mk> |