regex: also remove dependency on HAVE_WCSCOLL
[gnulib.git] / lib / pselect.c
index 7eec89c..3089303 100644 (file)
@@ -1,6 +1,6 @@
 /* pselect - synchronous I/O multiplexing
 
-   Copyright 2011 Free Software Foundation, Inc.
+   Copyright 2011-2013 Free Software Foundation, Inc.
 
    This file is part of gnulib.
 
@@ -15,8 +15,7 @@
    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, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
 /* written by Paul Eggert */
 
@@ -27,8 +26,6 @@
 #include <errno.h>
 #include <signal.h>
 
-#undef pselect
-
 /* Examine the size-NFDS file descriptor sets in RFDS, WFDS, and XFDS
    to see whether some of their descriptors are ready for reading,
    ready for writing, or have exceptions pending.  Wait for at most
    pointer parameter stands for no descriptors, an infinite timeout,
    or an unaffected signal mask.  */
 
+#if !HAVE_PSELECT
+
 int
-rpl_pselect (int nfds, fd_set *restrict rfds,
-             fd_set *restrict wfds, fd_set *restrict xfds,
-             struct timespec const *restrict timeout,
-             sigset_t const *restrict sigmask)
+pselect (int nfds, fd_set *restrict rfds,
+         fd_set *restrict wfds, fd_set *restrict xfds,
+         struct timespec const *restrict timeout,
+         sigset_t const *restrict sigmask)
 {
   int select_result;
   sigset_t origmask;
@@ -64,16 +63,48 @@ rpl_pselect (int nfds, fd_set *restrict rfds,
   /* Signal mask munging should be atomic, but this is the best we can
      do in this emulation.  */
   if (sigmask)
-    sigprocmask (SIG_SETMASK, sigmask, &origmask);
+    pthread_sigmask (SIG_SETMASK, sigmask, &origmask);
 
   select_result = select (nfds, rfds, wfds, xfds, tvp);
 
   if (sigmask)
     {
       int select_errno = errno;
-      sigprocmask (SIG_SETMASK, &origmask, NULL);
+      pthread_sigmask (SIG_SETMASK, &origmask, NULL);
       errno = select_errno;
     }
 
   return select_result;
 }
+
+#else /* HAVE_PSELECT */
+# include <unistd.h>
+# undef pselect
+
+int
+rpl_pselect (int nfds, fd_set *restrict rfds,
+            fd_set *restrict wfds, fd_set *restrict xfds,
+             struct timespec const *restrict timeout,
+            sigset_t const *restrict sigmask)
+{
+  int i;
+
+  /* FreeBSD 8.2 has a bug: it does not always detect invalid fds.  */
+  if (nfds < 0 || nfds > FD_SETSIZE)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  for (i = 0; i < nfds; i++)
+    {
+      if (((rfds && FD_ISSET (i, rfds))
+           || (wfds && FD_ISSET (i, wfds))
+           || (xfds && FD_ISSET (i, xfds)))
+          && dup2 (i, i) != i)
+        return -1;
+    }
+
+  return pselect (nfds, rfds, wfds, xfds, timeout, sigmask);
+}
+
+#endif