md5, sha1, sha256, sha512: add gl_SET_CRYPTO_CHECK_DEFAULT
[gnulib.git] / lib / pselect.c
index 6b9ba22..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 */
 
@@ -34,6 +33,8 @@
    pointer parameter stands for no descriptors, an infinite timeout,
    or an unaffected signal mask.  */
 
+#if !HAVE_PSELECT
+
 int
 pselect (int nfds, fd_set *restrict rfds,
          fd_set *restrict wfds, fd_set *restrict xfds,
@@ -62,16 +63,48 @@ 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