summaryrefslogtreecommitdiff
path: root/m4
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2012-10-02 15:29:13 -0600
committerEric Blake <eblake@redhat.com>2012-10-02 19:39:20 -0600
commit9500a55f083bb8e55ee938e4532ae6baea702e6b (patch)
tree763986d43ad9152c39da431080287959e3c8d5e9 /m4
parent2f58d08d66740bfe7fe5c581027965da04afecd7 (diff)
downloadgnulib-9500a55f083bb8e55ee938e4532ae6baea702e6b.tar.gz
select: reject invalid file descriptors
POSIX requires invalid file descriptors to be detected rather than silently ignored. FreeBSD 8.2 detects if fd 0 has been closed and appears in a set while fd 1 is still open, but mistakenly optimizes and refuses to check any fds in the set beyond the maximum open fd. * m4/select.m4 (gl_FUNC_SELECT): Probe for FreeBSD bug. * lib/select.c (rpl_select) [!win32]: Work around it. * modules/select (Depends-on): Add dup2. * doc/posix-functions/select.texi (select): Document this.
Diffstat (limited to 'm4')
-rw-r--r--m4/select.m440
1 files changed, 39 insertions, 1 deletions
diff --git a/m4/select.m4 b/m4/select.m4
index 037b3d3cfc..d135a39db9 100644
--- a/m4/select.m4
+++ b/m4/select.m4
@@ -1,4 +1,4 @@
-# select.m4 serial 6
+# select.m4 serial 7
dnl Copyright (C) 2009-2012 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -46,6 +46,44 @@ changequote([,])dnl
*yes) ;;
*) REPLACE_SELECT=1 ;;
esac
+
+ dnl On FreeBSD 8.2, select() doesn't always reject bad fds.
+ AC_CACHE_CHECK([whether select detects invalid fds],
+ [gl_cv_func_select_detects_ebadf],
+ [
+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/time.h>
+#if HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+#include <unistd.h>
+#include <errno.h>
+]],[[
+ fd_set set;
+ dup2(0, 16);
+ FD_ZERO(&set);
+ FD_SET(16, &set);
+ close(16);
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 5;
+ return select (17, &set, NULL, NULL, &timeout) != -1 || errno != EBADF;
+]])], [gl_cv_func_select_detects_ebadf=yes],
+ [gl_cv_func_select_detects_ebadf=no],
+ [
+ case "$host_os" in
+ # Guess yes on glibc systems.
+ *-gnu*) gl_cv_func_select_detects_ebadf="guessing yes" ;;
+ # If we don't know, assume the worst.
+ *) gl_cv_func_select_detects_ebadf="guessing no" ;;
+ esac
+ ])
+ ])
+ case $gl_cv_func_select_detects_ebadf in
+ *yes) ;;
+ *) REPLACE_SELECT=1 ;;
+ esac
fi
dnl Determine the needed libraries.