#endif
+/* Test select(2) on invalid file descriptors. */
+
+static int
+do_select_bad_fd (int fd, int ev, struct timeval *timeout, select_fn my_select)
+{
+ fd_set rfds, wfds, xfds;
+
+ 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);
+ return my_select (fd + 1, &rfds, &wfds, &xfds, timeout);
+ /* In this case, when fd is invalid, on some platforms, the bit for fd
+ is left alone in the fd_set, whereas on other platforms it is cleared.
+ So, don't check the bit for fd here. */
+}
+
+static int
+do_select_bad_fd_nowait (int fd, int ev, select_fn my_select)
+{
+ struct timeval tv0;
+ tv0.tv_sec = 0;
+ tv0.tv_usec = 0;
+ return do_select_bad_fd (fd, ev, &tv0, my_select);
+}
+
+static void
+test_bad_fd (select_fn my_select)
+{
+ int fd;
+
+ /* On Linux, MacOS X, *BSD, and OSF/1, values of fd like 99 or 399 are
+ discarded by the kernel early and therefore do *not* lead to EBADF,
+ as required by POSIX. */
+#if defined __linux__ || (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __osf__
+ fd = 16;
+#else
+ fd = 99;
+#endif
+
+ if (do_select_bad_fd_nowait (fd, SEL_IN, my_select) == 0 || errno != EBADF)
+ failed ("invalid fd among rfds");
+ if (do_select_bad_fd_nowait (fd, SEL_OUT, my_select) == 0 || errno != EBADF)
+ failed ("invalid fd among wfds");
+ if (do_select_bad_fd_nowait (fd, SEL_EXC, my_select) == 0 || errno != EBADF)
+ failed ("invalid fd among xfds");
+}
+
+
/* Test select(2) for unconnected nonblocking sockets. */
static void
static int
test_function (select_fn my_select)
{
- int result;
+ int result = 0;
#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_bad_fd, my_select, "Invalid fd test");
+ 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");