Fix large-file macro usage in bits/statvfs.h
[kopensolaris-gnu/glibc.git] / io / ppoll.c
1 /* Copyright (C) 2006 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <errno.h>
21 #include <limits.h>
22 #include <signal.h>
23 #include <stddef.h>     /* For NULL.  */
24 #include <sys/poll.h>
25 #include <sysdep-cancel.h>
26
27
28 int
29 ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
30        const sigset_t *sigmask)
31 {
32   int tval = -1;
33
34   /* poll uses a simple millisecond value.  Convert it.  */
35   if (timeout != NULL)
36     {
37       if (timeout->tv_sec < 0
38           || timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)
39         {
40           __set_errno (EINVAL);
41           return -1;
42         }
43
44       if (timeout->tv_sec > INT_MAX / 1000
45           || (timeout->tv_sec == INT_MAX / 1000
46               && ((timeout->tv_nsec + 999999) / 1000000 > INT_MAX % 1000)))
47         /* We cannot represent the timeout in an int value.  Wait
48            forever.  */
49         tval = -1;
50       else
51         tval = (timeout->tv_sec * 1000
52                 + (timeout->tv_nsec + 999999) / 1000000);
53     }
54
55   /* The setting and restoring of the signal mask and the select call
56      should be an atomic operation.  This can't be done without kernel
57      help.  */
58   sigset_t savemask;
59   if (sigmask != NULL)
60     __sigprocmask (SIG_SETMASK, sigmask, &savemask);
61
62   /* Note the ppoll() is a cancellation point.  But since we call
63      poll() which itself is a cancellation point we do not have
64      to do anything here.  */
65   int retval = __poll (fds, nfds, tval);
66
67   if (sigmask != NULL)
68     __sigprocmask (SIG_SETMASK, &savemask, NULL);
69
70   return retval;
71 }
72
73 #ifndef ppoll
74 /* __poll handles cancellation.  */
75 LIBC_CANCEL_HANDLED ();
76 #endif