changeset 15726:1a3894d5ce47

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.
author Bruno Haible <bruno@clisp.org>
date Tue, 20 Sep 2011 23:59:33 +0200
parents 93373b43df61
children 144db791c6fa
files ChangeLog tests/test-select.h
diffstat 2 files changed, 64 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+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.
--- a/tests/test-select.h
+++ b/tests/test-select.h
@@ -227,6 +227,60 @@
 #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 @@
 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");