Back to index

glibc  2.9
pselect.c
Go to the documentation of this file.
00001 /* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <signal.h>
00022 #include <time.h>
00023 #include <sys/poll.h>
00024 #include <kernel-features.h>
00025 #include <sysdep-cancel.h>
00026 
00027 
00028 #ifdef __NR_pselect6
00029 # ifndef __ASSUME_PSELECT
00030 static int __generic_pselect (int nfds, fd_set *readfds, fd_set *writefds,
00031                            fd_set *exceptfds,
00032                            const struct timespec *timeout,
00033                            const sigset_t *sigmask);
00034 # endif
00035 
00036 
00037 int
00038 __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
00039           const struct timespec *timeout, const sigset_t *sigmask)
00040 {
00041   /* The Linux kernel can in some situations update the timeout value.
00042      We do not want that so use a local variable.  */
00043   struct timespec tval;
00044   if (timeout != NULL)
00045     {
00046       tval = *timeout;
00047       timeout = &tval;
00048     }
00049 
00050   /* Note: the system call expects 7 values but on most architectures
00051      we can only pass in 6 directly.  If there is an architecture with
00052      support for more parameters a new version of this file needs to
00053      be created.  */
00054   struct
00055   {
00056     const sigset_t *ss;
00057     size_t ss_len;
00058   } data;
00059 
00060   data.ss = sigmask;
00061   data.ss_len = _NSIG / 8;
00062 
00063   int result;
00064 
00065 #ifndef CALL_PSELECT6
00066 # define CALL_PSELECT6(nfds, readfds, writefds, exceptfds, timeout, data) \
00067   INLINE_SYSCALL (pselect6, 6, nfds, readfds, writefds, exceptfds,          \
00068                 timeout, data)
00069 #endif
00070 
00071   if (SINGLE_THREAD_P)
00072     result = CALL_PSELECT6 (nfds, readfds, writefds, exceptfds, timeout,
00073                          &data);
00074   else
00075     {
00076       int oldtype = LIBC_CANCEL_ASYNC ();
00077 
00078       result = CALL_PSELECT6 (nfds, readfds, writefds, exceptfds, timeout,
00079                            &data);
00080 
00081       LIBC_CANCEL_RESET (oldtype);
00082     }
00083 
00084 # ifndef __ASSUME_PSELECT
00085   if (result == -1 && errno == ENOSYS)
00086     result = __generic_pselect (nfds, readfds, writefds, exceptfds, timeout,
00087                             sigmask);
00088 # endif
00089 
00090   return result;
00091 }
00092 weak_alias (__pselect, pselect)
00093 strong_alias (__pselect, __libc_pselect)
00094 
00095 # ifndef __ASSUME_PSELECT
00096 #  define __pselect static __generic_pselect
00097 # endif
00098 #endif
00099 
00100 #ifndef __ASSUME_PSELECT
00101 # include <misc/pselect.c>
00102 #endif