Back to index

glibc  2.9
poll.c
Go to the documentation of this file.
00001 /* Poll system call, with emulation if it is not available.
00002    Copyright (C) 1997,1998,1999,2000,2001,2002,2006
00003        Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <errno.h>
00022 #include <sys/poll.h>
00023 
00024 #include <sysdep-cancel.h>
00025 #include <sys/syscall.h>
00026 #include <bp-checks.h>
00027 
00028 #include <kernel-features.h>
00029 
00030 #if defined __NR_poll || __ASSUME_POLL_SYSCALL > 0
00031 
00032 # if __ASSUME_POLL_SYSCALL == 0
00033 static int __emulate_poll (struct pollfd *fds, nfds_t nfds,
00034                         int timeout) internal_function;
00035 # endif
00036 
00037 
00038 # if __ASSUME_POLL_SYSCALL == 0
00039 /* For loser kernels.  */
00040 static int
00041 loser_poll (struct pollfd *fds, nfds_t nfds, int timeout)
00042 {
00043   static int must_emulate;
00044 
00045   if (!must_emulate)
00046     {
00047       int errno_saved = errno;
00048       int retval = INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds,
00049                                timeout);
00050 
00051       if (retval >= 0 || errno != ENOSYS)
00052        return retval;
00053 
00054       __set_errno (errno_saved);
00055       must_emulate = 1;
00056     }
00057 
00058   return __emulate_poll (fds, nfds, timeout);
00059 }
00060 # endif
00061 
00062 
00063 /* The real implementation.  */
00064 int
00065 __poll (fds, nfds, timeout)
00066      struct pollfd *fds;
00067      nfds_t nfds;
00068      int timeout;
00069 {
00070 # if __ASSUME_POLL_SYSCALL == 0
00071   if (SINGLE_THREAD_P)
00072     return loser_poll (CHECK_N (fds, nfds), nfds, timeout);
00073 
00074   int oldtype = LIBC_CANCEL_ASYNC ();
00075 
00076   int result = loser_poll (CHECK_N (fds, nfds), nfds, timeout);
00077 
00078    LIBC_CANCEL_RESET (oldtype);
00079 
00080   return result;
00081 # else
00082   if (SINGLE_THREAD_P)
00083     return INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds, timeout);
00084 
00085   int oldtype = LIBC_CANCEL_ASYNC ();
00086 
00087   int result = INLINE_SYSCALL (poll, 3, CHECK_N (fds, nfds), nfds, timeout);
00088 
00089    LIBC_CANCEL_RESET (oldtype);
00090 
00091   return result;
00092 # endif
00093 }
00094 libc_hidden_def (__poll)
00095 weak_alias (__poll, poll)
00096 strong_alias (__poll, __libc_poll)
00097 
00098 /* Get the emulation code.  */
00099 # define __poll(fds, nfds, timeout) \
00100   static internal_function __emulate_poll (fds, nfds, timeout)
00101 #endif
00102 
00103 #if __ASSUME_POLL_SYSCALL == 0
00104 # include <sysdeps/unix/bsd/poll.c>
00105 #endif