select tests: EBADF tests.
authorBruno Haible <bruno@clisp.org>
Tue, 20 Sep 2011 21:59:33 +0000 (23:59 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 20 Sep 2011 21:59:33 +0000 (23:59 +0200)
* tests/test-select.h (do_select_bad_fd, do_select_bad_fd_nowait,
test_bad_fd): New functions.
(test_function): Invoke also test_bad_fd.

ChangeLog
tests/test-select.h

index 5728324..a653b15 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2011-09-20  Bruno Haible  <bruno@clisp.org>
 
+       select tests: EBADF tests.
+       * tests/test-select.h (do_select_bad_fd, do_select_bad_fd_nowait,
+       test_bad_fd): New functions.
+       (test_function): Invoke also test_bad_fd.
+
+2011-09-20  Bruno Haible  <bruno@clisp.org>
+
        Tests for module 'posix_spawn_file_actions_addopen.
        * modules/posix_spawn_file_actions_addopen-tests: New file.
        * tests/test-posix_spawn_file_actions_addopen.c: New file.
index 1ddfda3..85c561a 100644 (file)
@@ -227,6 +227,60 @@ test_tty (select_fn my_select)
 #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
@@ -362,14 +416,15 @@ test_pipe (select_fn my_select)
 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");