[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 02/10] test-pselect: new module
From: |
Bruno Haible |
Subject: |
Re: [PATCH 02/10] test-pselect: new module |
Date: |
Sat, 23 Jul 2011 04:13:21 +0200 |
User-agent: |
KMail/1.13.6 (Linux/2.6.37.6-0.5-desktop; KDE/4.6.0; x86_64; ; ) |
Paul Eggert wrote on 2011-07-05:
> --- /dev/null
> +++ b/tests/test-pselect.c
> @@ -0,0 +1,2 @@
> +#define TEST_PSELECT
> +#include "test-select.c"
> diff --git a/tests/test-select.c b/tests/test-select.c
> index 5c15320..9e927f8 100644
> --- a/tests/test-select.c
> +++ b/tests/test-select.c
> @@ -21,8 +21,16 @@
> #include <sys/select.h>
>
> #include "signature.h"
> +
> +#ifdef TEST_PSELECT
> +SIGNATURE_CHECK (pselect, int,
> + (int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
> + struct timespec const *restrict, const sigset_t
> *restrict));
> +#else
> SIGNATURE_CHECK (select, int, (int, fd_set *, fd_set *, fd_set *,
> struct timeval *));
> +#endif
> +
> /* The following may be macros without underlying functions, so only
> check signature if they are not macros. */
> #ifndef FD_CLR
> @@ -190,7 +198,20 @@ do_select (int fd, int ev, struct timeval *timeout)
> FD_SET (fd, &wfds);
> if (ev & SEL_EXC)
> FD_SET (fd, &xfds);
> +#ifdef TEST_PSELECT
> + {
This is quite a bit of #ifdefology, for my taste. Here's a proposed refactoring
that moves the common code to a .h file. So that it is clear and easy to add
new code to the tests:
- new code for select() goes in tests-select.c.
- new code for pselect() goes in tests-pselect.c.
- new code for both goes in tests-select.h.
Objections to this change?
2011-07-22 Bruno Haible <address@hidden>
select tests, pselect tests: Refactor.
* tests/test-select.h: New file, extracted from tests/test-select.c.
(select_fn): New type.
(test, do_select, do_select_nowait, do_select_wait, test_tty,
test_connect_first, test_accept_first, test_pair, test_socket_pair,
test_pipe): Add my_select argument.
(test_function): Renamed from main. Add my_select argument.
* modules/select-tests (Files): Add tests/test-select.h.
* tests/test-pselect.c: Include test-select.h instead of test-select.c.
(my_select, main): New functions.
* modules/pselect-tests (Files): Add tests/test-select.h,
tests/macros.h,
tests/signature.h.
(Depends-on): Remove select-tests. Add dependencies of test-select.h.
(configure.ac): Check for <sys/wait.h>.
============================= tests/test-select.h =============================
/* Test of select() substitute.
Copyright (C) 2008-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Paolo Bonzini, 2008. */
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "macros.h"
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# define WIN32_NATIVE
#endif
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
#ifndef SO_REUSEPORT
# define SO_REUSEPORT SO_REUSEADDR
#endif
#define TEST_PORT 12345
typedef int (*select_fn) (int, fd_set *, fd_set *, fd_set *, struct timeval *);
/* Minimal testing infrastructure. */
static int failures;
static void
failed (const char *reason)
{
if (++failures > 1)
printf (" ");
printf ("failed (%s)\n", reason);
}
static int
test (void (*fn) (select_fn), select_fn my_select, const char *msg)
{
failures = 0;
printf ("%s... ", msg);
fflush (stdout);
fn (my_select);
if (!failures)
printf ("passed\n");
return failures;
}
/* Funny socket code. */
static int
open_server_socket (void)
{
int s, x;
struct sockaddr_in ia;
s = socket (AF_INET, SOCK_STREAM, 0);
memset (&ia, 0, sizeof (ia));
ia.sin_family = AF_INET;
inet_pton (AF_INET, "127.0.0.1", &ia.sin_addr);
ia.sin_port = htons (TEST_PORT);
if (bind (s, (struct sockaddr *) &ia, sizeof (ia)) < 0)
{
perror ("bind");
exit (77);
}
x = 1;
setsockopt (s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof (x));
if (listen (s, 1) < 0)
{
perror ("listen");
exit (77);
}
return s;
}
static int
connect_to_socket (bool blocking)
{
int s;
struct sockaddr_in ia;
s = socket (AF_INET, SOCK_STREAM, 0);
memset (&ia, 0, sizeof (ia));
ia.sin_family = AF_INET;
inet_pton (AF_INET, "127.0.0.1", &ia.sin_addr);
ia.sin_port = htons (TEST_PORT);
if (!blocking)
{
#ifdef WIN32_NATIVE
unsigned long iMode = 1;
ioctl (s, FIONBIO, (char *) &iMode);
#elif defined F_GETFL
int oldflags = fcntl (s, F_GETFL, NULL);
if (!(oldflags & O_NONBLOCK))
fcntl (s, F_SETFL, oldflags | O_NONBLOCK);
#endif
}
if (connect (s, (struct sockaddr *) &ia, sizeof (ia)) < 0
&& (blocking || errno != EINPROGRESS))
{
perror ("connect");
exit (77);
}
return s;
}
/* A slightly more convenient interface to select(2).
Waits until a specific event occurs on a file descriptor FD.
EV is a bit mask of events to look for:
SEL_IN - input can be polled without blocking,
SEL_OUT - output can be provided without blocking,
SEL_EXC - an exception occurred,
A maximum wait time is specified by TIMEOUT.
*TIMEOUT = { 0, 0 } means to return immediately,
TIMEOUT = NULL means to wait indefinitely. */
enum { SEL_IN = 1, SEL_OUT = 2, SEL_EXC = 4 };
static int
do_select (int fd, int ev, struct timeval *timeout, select_fn my_select)
{
fd_set rfds, wfds, xfds;
int r, rev;
FD_ZERO (&rfds);
FD_ZERO (&wfds);
FD_ZERO (&xfds);
if (ev & SEL_IN)
FD_SET (fd, &rfds);
if (ev & SEL_OUT)
FD_SET (fd, &wfds);
if (ev & SEL_EXC)
FD_SET (fd, &xfds);
r = my_select (fd + 1, &rfds, &wfds, &xfds, timeout);
if (r < 0)
return r;
rev = 0;
if (FD_ISSET (fd, &rfds))
rev |= SEL_IN;
if (FD_ISSET (fd, &wfds))
rev |= SEL_OUT;
if (FD_ISSET (fd, &xfds))
rev |= SEL_EXC;
if (rev && r == 0)
failed ("select returned 0");
if (rev & ~ev)
failed ("select returned unrequested events");
return rev;
}
static int
do_select_nowait (int fd, int ev, select_fn my_select)
{
struct timeval tv0;
tv0.tv_sec = 0;
tv0.tv_usec = 0;
return do_select (fd, ev, &tv0, my_select);
}
static int
do_select_wait (int fd, int ev, select_fn my_select)
{
return do_select (fd, ev, NULL, my_select);
}
/* Test select(2) for TTYs. */
#ifdef INTERACTIVE
static void
test_tty (select_fn my_select)
{
if (do_select_nowait (0, SEL_IN, my_select) != 0)
failed ("can read");
if (do_select_nowait (0, SEL_OUT, my_select) == 0)
failed ("cannot write");
if (do_select_wait (0, SEL_IN, my_select) == 0)
failed ("return with infinite timeout");
getchar ();
if (do_select_nowait (0, SEL_IN, my_select) != 0)
failed ("can read after getc");
}
#endif
/* Test select(2) for unconnected nonblocking sockets. */
static void
test_connect_first (select_fn my_select)
{
int s = open_server_socket ();
struct sockaddr_in ia;
socklen_t addrlen;
int c1, c2;
if (do_select_nowait (s, SEL_IN | SEL_EXC, my_select) != 0)
failed ("can read, socket not connected");
c1 = connect_to_socket (false);
if (do_select_wait (s, SEL_IN | SEL_EXC, my_select) != SEL_IN)
failed ("expecting readability on passive socket");
if (do_select_nowait (s, SEL_IN | SEL_EXC, my_select) != SEL_IN)
failed ("expecting readability on passive socket");
addrlen = sizeof (ia);
c2 = accept (s, (struct sockaddr *) &ia, &addrlen);
ASSERT (close (s) == 0);
ASSERT (close (c1) == 0);
ASSERT (close (c2) == 0);
}
/* Test select(2) for unconnected blocking sockets. */
static void
test_accept_first (select_fn my_select)
{
#ifndef WIN32_NATIVE
int s = open_server_socket ();
struct sockaddr_in ia;
socklen_t addrlen;
char buf[3];
int c, pid;
pid = fork ();
if (pid < 0)
return;
if (pid == 0)
{
addrlen = sizeof (ia);
c = accept (s, (struct sockaddr *) &ia, &addrlen);
ASSERT (close (s) == 0);
ASSERT (write (c, "foo", 3) == 3);
ASSERT (read (c, buf, 3) == 3);
shutdown (c, SHUT_RD);
ASSERT (close (c) == 0);
exit (0);
}
else
{
ASSERT (close (s) == 0);
c = connect_to_socket (true);
if (do_select_nowait (c, SEL_OUT, my_select) != SEL_OUT)
failed ("cannot write after blocking connect");
ASSERT (write (c, "foo", 3) == 3);
wait (&pid);
if (do_select_wait (c, SEL_IN, my_select) != SEL_IN)
failed ("cannot read data left in the socket by closed process");
ASSERT (read (c, buf, 3) == 3);
ASSERT (write (c, "foo", 3) == 3);
(void) close (c); /* may fail with errno = ECONNRESET */
}
#endif
}
/* Common code for pipes and connected sockets. */
static void
test_pair (int rd, int wd, select_fn my_select)
{
char buf[3];
if (do_select_wait (wd, SEL_IN | SEL_OUT | SEL_EXC, my_select) != SEL_OUT)
failed ("expecting writability before writing");
if (do_select_nowait (wd, SEL_IN | SEL_OUT | SEL_EXC, my_select) != SEL_OUT)
failed ("expecting writability before writing");
ASSERT (write (wd, "foo", 3) == 3);
if (do_select_wait (rd, SEL_IN, my_select) != SEL_IN)
failed ("expecting readability after writing");
if (do_select_nowait (rd, SEL_IN, my_select) != SEL_IN)
failed ("expecting readability after writing");
ASSERT (read (rd, buf, 3) == 3);
}
/* Test select(2) on connected sockets. */
static void
test_socket_pair (select_fn my_select)
{
struct sockaddr_in ia;
socklen_t addrlen = sizeof (ia);
int s = open_server_socket ();
int c1 = connect_to_socket (false);
int c2 = accept (s, (struct sockaddr *) &ia, &addrlen);
ASSERT (close (s) == 0);
test_pair (c1, c2, my_select);
ASSERT (close (c1) == 0);
ASSERT (write (c2, "foo", 3) == 3);
(void) close (c2); /* may fail with errno = ECONNRESET */
}
/* Test select(2) on pipes. */
static void
test_pipe (select_fn my_select)
{
int fd[2];
ASSERT (pipe (fd) == 0);
test_pair (fd[0], fd[1], my_select);
ASSERT (close (fd[0]) == 0);
ASSERT (close (fd[1]) == 0);
}
/* Do them all. */
int
test_function (select_fn my_select)
{
int result;
#ifdef INTERACTIVE
printf ("Please press Enter\n");
test (test_tty, "TTY", my_select);
#endif
result = test (test_connect_first, my_select, "Unconnected socket test");
result += test (test_socket_pair, my_select, "Connected sockets test");
result += test (test_accept_first, my_select, "General socket test with
fork");
result += test (test_pipe, my_select, "Pipe test");
return result;
}
===============================================================================
--- modules/pselect-tests.orig Sat Jul 23 04:00:38 2011
+++ modules/pselect-tests Sat Jul 23 03:50:36 2011
@@ -1,10 +1,31 @@
Files:
tests/test-pselect.c
+tests/test-select.h
+tests/macros.h
+tests/signature.h
Depends-on:
-select-tests
+stdbool
+netinet_in
+arpa_inet
+unistd
+sys_ioctl
+extensions
+inet_pton
+errno
+perror
+pipe-posix
+socket
+bind
+setsockopt
+listen
+connect
+accept
+ioctl
+close
configure.ac:
+AC_CHECK_HEADERS_ONCE([sys/wait.h])
Makefile.am:
TESTS += test-pselect
--- modules/select-tests.orig Sat Jul 23 04:00:38 2011
+++ modules/select-tests Sat Jul 23 03:26:58 2011
@@ -2,6 +2,7 @@
tests/macros.h
tests/signature.h
tests/test-select.c
+tests/test-select.h
tests/test-select-fd.c
tests/test-select-in.sh
tests/test-select-out.sh
--- tests/test-pselect.c.orig Sat Jul 23 04:00:38 2011
+++ tests/test-pselect.c Sat Jul 23 03:49:56 2011
@@ -1,2 +1,48 @@
-#define TEST_PSELECT
-#include "test-select.c"
+/* Test of pselect() substitute.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <sys/select.h>
+
+#include "signature.h"
+
+SIGNATURE_CHECK (pselect, int,
+ (int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
+ struct timespec const *restrict, const sigset_t *restrict));
+
+#include "test-select.h"
+
+static int
+my_select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ struct timeval *timeout)
+{
+ struct timespec ts;
+ struct timespec *pts = NULL;
+ if (timeout)
+ {
+ ts.tv_sec = timeout->tv_sec;
+ ts.tv_nsec = timeout->tv_usec * 1000;
+ pts = &ts;
+ }
+ return pselect (nfds, readfds, writefds, exceptfds, pts, NULL);
+}
+
+int
+main (void)
+{
+ return test_function (my_select);
+}
--- tests/test-select.c.orig Sat Jul 23 04:00:38 2011
+++ tests/test-select.c Sat Jul 23 03:39:11 2011
@@ -22,382 +22,13 @@
#include "signature.h"
-#ifdef TEST_PSELECT
-SIGNATURE_CHECK (pselect, int,
- (int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
- struct timespec const *restrict, const sigset_t *restrict));
-#else
SIGNATURE_CHECK (select, int, (int, fd_set *, fd_set *, fd_set *,
struct timeval *));
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include "macros.h"
-
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-# define WIN32_NATIVE
-#endif
-
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-#ifndef SO_REUSEPORT
-# define SO_REUSEPORT SO_REUSEADDR
-#endif
-
-#define TEST_PORT 12345
-
-
-/* Minimal testing infrastructure. */
-
-static int failures;
-
-static void
-failed (const char *reason)
-{
- if (++failures > 1)
- printf (" ");
- printf ("failed (%s)\n", reason);
-}
-
-static int
-test (void (*fn) (void), const char *msg)
-{
- failures = 0;
- printf ("%s... ", msg);
- fflush (stdout);
- fn ();
-
- if (!failures)
- printf ("passed\n");
-
- return failures;
-}
-
-
-/* Funny socket code. */
-
-static int
-open_server_socket (void)
-{
- int s, x;
- struct sockaddr_in ia;
-
- s = socket (AF_INET, SOCK_STREAM, 0);
-
- memset (&ia, 0, sizeof (ia));
- ia.sin_family = AF_INET;
- inet_pton (AF_INET, "127.0.0.1", &ia.sin_addr);
- ia.sin_port = htons (TEST_PORT);
- if (bind (s, (struct sockaddr *) &ia, sizeof (ia)) < 0)
- {
- perror ("bind");
- exit (77);
- }
-
- x = 1;
- setsockopt (s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof (x));
-
- if (listen (s, 1) < 0)
- {
- perror ("listen");
- exit (77);
- }
-
- return s;
-}
-
-static int
-connect_to_socket (bool blocking)
-{
- int s;
- struct sockaddr_in ia;
-
- s = socket (AF_INET, SOCK_STREAM, 0);
-
- memset (&ia, 0, sizeof (ia));
- ia.sin_family = AF_INET;
- inet_pton (AF_INET, "127.0.0.1", &ia.sin_addr);
- ia.sin_port = htons (TEST_PORT);
-
- if (!blocking)
- {
-#ifdef WIN32_NATIVE
- unsigned long iMode = 1;
- ioctl (s, FIONBIO, (char *) &iMode);
-
-#elif defined F_GETFL
- int oldflags = fcntl (s, F_GETFL, NULL);
-
- if (!(oldflags & O_NONBLOCK))
- fcntl (s, F_SETFL, oldflags | O_NONBLOCK);
-#endif
- }
-
- if (connect (s, (struct sockaddr *) &ia, sizeof (ia)) < 0
- && (blocking || errno != EINPROGRESS))
- {
- perror ("connect");
- exit (77);
- }
-
- return s;
-}
-
-
-/* A slightly more convenient interface to select(2).
- Waits until a specific event occurs on a file descriptor FD.
- EV is a bit mask of events to look for:
- SEL_IN - input can be polled without blocking,
- SEL_OUT - output can be provided without blocking,
- SEL_EXC - an exception occurred,
- A maximum wait time is specified by TIMEOUT.
- *TIMEOUT = { 0, 0 } means to return immediately,
- TIMEOUT = NULL means to wait indefinitely. */
-
-enum { SEL_IN = 1, SEL_OUT = 2, SEL_EXC = 4 };
-
-static int
-do_select (int fd, int ev, struct timeval *timeout)
-{
- fd_set rfds, wfds, xfds;
- int r, rev;
-
- FD_ZERO (&rfds);
- FD_ZERO (&wfds);
- FD_ZERO (&xfds);
- if (ev & SEL_IN)
- FD_SET (fd, &rfds);
- if (ev & SEL_OUT)
- FD_SET (fd, &wfds);
- if (ev & SEL_EXC)
- FD_SET (fd, &xfds);
-#ifdef TEST_PSELECT
- {
- struct timespec ts, *pts = NULL;
- if (timeout)
- {
- ts.tv_sec = timeout->tv_sec;
- ts.tv_nsec = timeout->tv_usec * 1000;
- pts = &ts;
- }
- r = pselect (fd + 1, &rfds, &wfds, &xfds, pts, NULL);
- }
-#else
- r = select (fd + 1, &rfds, &wfds, &xfds, timeout);
-#endif
- if (r < 0)
- return r;
-
- rev = 0;
- if (FD_ISSET (fd, &rfds))
- rev |= SEL_IN;
- if (FD_ISSET (fd, &wfds))
- rev |= SEL_OUT;
- if (FD_ISSET (fd, &xfds))
- rev |= SEL_EXC;
- if (rev && r == 0)
- failed ("select returned 0");
- if (rev & ~ev)
- failed ("select returned unrequested events");
-
- return rev;
-}
-
-static int
-do_select_nowait (int fd, int ev)
-{
- struct timeval tv0;
- tv0.tv_sec = 0;
- tv0.tv_usec = 0;
- return do_select (fd, ev, &tv0);
-}
-
-static int
-do_select_wait (int fd, int ev)
-{
- return do_select (fd, ev, NULL);
-}
-
-
-/* Test select(2) for TTYs. */
-
-#ifdef INTERACTIVE
-static void
-test_tty (void)
-{
- if (do_select_nowait (0, SEL_IN) != 0)
- failed ("can read");
- if (do_select_nowait (0, SEL_OUT) == 0)
- failed ("cannot write");
-
- if (do_select_wait (0, SEL_IN) == 0)
- failed ("return with infinite timeout");
-
- getchar ();
- if (do_select_nowait (0, SEL_IN) != 0)
- failed ("can read after getc");
-}
-#endif
-
-
-/* Test select(2) for unconnected nonblocking sockets. */
-
-static void
-test_connect_first (void)
-{
- int s = open_server_socket ();
- struct sockaddr_in ia;
- socklen_t addrlen;
-
- int c1, c2;
-
- if (do_select_nowait (s, SEL_IN | SEL_EXC) != 0)
- failed ("can read, socket not connected");
-
- c1 = connect_to_socket (false);
-
- if (do_select_wait (s, SEL_IN | SEL_EXC) != SEL_IN)
- failed ("expecting readability on passive socket");
- if (do_select_nowait (s, SEL_IN | SEL_EXC) != SEL_IN)
- failed ("expecting readability on passive socket");
-
- addrlen = sizeof (ia);
- c2 = accept (s, (struct sockaddr *) &ia, &addrlen);
- ASSERT (close (s) == 0);
- ASSERT (close (c1) == 0);
- ASSERT (close (c2) == 0);
-}
-
-
-/* Test select(2) for unconnected blocking sockets. */
-
-static void
-test_accept_first (void)
-{
-#ifndef WIN32_NATIVE
- int s = open_server_socket ();
- struct sockaddr_in ia;
- socklen_t addrlen;
- char buf[3];
- int c, pid;
-
- pid = fork ();
- if (pid < 0)
- return;
-
- if (pid == 0)
- {
- addrlen = sizeof (ia);
- c = accept (s, (struct sockaddr *) &ia, &addrlen);
- ASSERT (close (s) == 0);
- ASSERT (write (c, "foo", 3) == 3);
- ASSERT (read (c, buf, 3) == 3);
- shutdown (c, SHUT_RD);
- ASSERT (close (c) == 0);
- exit (0);
- }
- else
- {
- ASSERT (close (s) == 0);
- c = connect_to_socket (true);
- if (do_select_nowait (c, SEL_OUT) != SEL_OUT)
- failed ("cannot write after blocking connect");
- ASSERT (write (c, "foo", 3) == 3);
- wait (&pid);
- if (do_select_wait (c, SEL_IN) != SEL_IN)
- failed ("cannot read data left in the socket by closed process");
- ASSERT (read (c, buf, 3) == 3);
- ASSERT (write (c, "foo", 3) == 3);
- (void) close (c); /* may fail with errno = ECONNRESET */
- }
-#endif
-}
-
-
-/* Common code for pipes and connected sockets. */
-
-static void
-test_pair (int rd, int wd)
-{
- char buf[3];
- if (do_select_wait (wd, SEL_IN | SEL_OUT | SEL_EXC) != SEL_OUT)
- failed ("expecting writability before writing");
- if (do_select_nowait (wd, SEL_IN | SEL_OUT | SEL_EXC) != SEL_OUT)
- failed ("expecting writability before writing");
-
- ASSERT (write (wd, "foo", 3) == 3);
- if (do_select_wait (rd, SEL_IN) != SEL_IN)
- failed ("expecting readability after writing");
- if (do_select_nowait (rd, SEL_IN) != SEL_IN)
- failed ("expecting readability after writing");
-
- ASSERT (read (rd, buf, 3) == 3);
-}
-
-
-/* Test select(2) on connected sockets. */
-
-static void
-test_socket_pair (void)
-{
- struct sockaddr_in ia;
-
- socklen_t addrlen = sizeof (ia);
- int s = open_server_socket ();
- int c1 = connect_to_socket (false);
- int c2 = accept (s, (struct sockaddr *) &ia, &addrlen);
-
- ASSERT (close (s) == 0);
-
- test_pair (c1, c2);
- ASSERT (close (c1) == 0);
- ASSERT (write (c2, "foo", 3) == 3);
- (void) close (c2); /* may fail with errno = ECONNRESET */
-}
-
-
-/* Test select(2) on pipes. */
-
-static void
-test_pipe (void)
-{
- int fd[2];
-
- ASSERT (pipe (fd) == 0);
- test_pair (fd[0], fd[1]);
- ASSERT (close (fd[0]) == 0);
- ASSERT (close (fd[1]) == 0);
-}
-
-
-/* Do them all. */
+#include "test-select.h"
int
main (void)
{
- int result;
-
-#ifdef INTERACTIVE
- printf ("Please press Enter\n");
- test (test_tty, "TTY");
-#endif
-
- result = test (test_connect_first, "Unconnected socket test");
- result += test (test_socket_pair, "Connected sockets test");
- result += test (test_accept_first, "General socket test with fork");
- result += test (test_pipe, "Pipe test");
-
- exit (result);
+ return test_function (select);
}
--
In memoriam Dmitry Pavlov <http://en.wikipedia.org/wiki/Dmitry_Pavlov_(general)>