Back to index

glibc  2.9
ppoll.c
Go to the documentation of this file.
00001 /* Copyright (C) 2006 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 <limits.h>
00022 #include <signal.h>
00023 #include <stddef.h>  /* For NULL.  */
00024 #include <sys/poll.h>
00025 #include <sysdep-cancel.h>
00026 
00027 
00028 int
00029 ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
00030        const sigset_t *sigmask)
00031 {
00032   int tval = -1;
00033 
00034   /* poll uses a simple millisecond value.  Convert it.  */
00035   if (timeout != NULL)
00036     {
00037       if (timeout->tv_sec < 0
00038          || timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)
00039        {
00040          __set_errno (EINVAL);
00041          return -1;
00042        }
00043 
00044       if (timeout->tv_sec > INT_MAX / 1000
00045          || (timeout->tv_sec == INT_MAX / 1000
00046              && ((timeout->tv_nsec + 999999) / 1000000 > INT_MAX % 1000)))
00047        /* We cannot represent the timeout in an int value.  Wait
00048           forever.  */
00049        tval = -1;
00050       else
00051        tval = (timeout->tv_sec * 1000
00052               + (timeout->tv_nsec + 999999) / 1000000);
00053     }
00054 
00055   /* The setting and restoring of the signal mask and the select call
00056      should be an atomic operation.  This can't be done without kernel
00057      help.  */
00058   sigset_t savemask;
00059   if (sigmask != NULL)
00060     __sigprocmask (SIG_SETMASK, sigmask, &savemask);
00061 
00062   /* Note the ppoll() is a cancellation point.  But since we call
00063      poll() which itself is a cancellation point we do not have
00064      to do anything here.  */
00065   int retval = __poll (fds, nfds, tval);
00066 
00067   if (sigmask != NULL)
00068     __sigprocmask (SIG_SETMASK, &savemask, NULL);
00069 
00070   return retval;
00071 }
00072 
00073 #ifndef ppoll
00074 /* __poll handles cancellation.  */
00075 LIBC_CANCEL_HANDLED ();
00076 #endif