aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sys/poll.h13
-rw-r--r--sysdeps/unix/sysv/linux/ppoll.c49
2 files changed, 57 insertions, 5 deletions
diff --git a/include/sys/poll.h b/include/sys/poll.h
index a42bc93873..f904e21f89 100644
--- a/include/sys/poll.h
+++ b/include/sys/poll.h
@@ -6,6 +6,17 @@ extern int __poll (struct pollfd *__fds, unsigned long int __nfds,
int __timeout);
libc_hidden_proto (__poll)
libc_hidden_proto (ppoll)
-#endif
+# if __TIMESIZE == 64
+# define __ppoll64 __ppoll
+# else
+# include <time.h>
+# include <signal.h>
+
+extern int __ppoll64 (struct pollfd *fds, nfds_t nfds,
+ const struct __timespec64 *timeout,
+ const sigset_t *sigmask);
+libc_hidden_proto (__ppoll64)
+# endif
+#endif
#endif
diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c
index 8a6ccd1dcc..beafeb3809 100644
--- a/sysdeps/unix/sysv/linux/ppoll.c
+++ b/sysdeps/unix/sysv/linux/ppoll.c
@@ -21,21 +21,62 @@
#include <time.h>
#include <sys/poll.h>
#include <sysdep-cancel.h>
+#include <kernel-features.h>
int
-ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
- const sigset_t *sigmask)
+__ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
+ const sigset_t *sigmask)
{
/* The Linux kernel can in some situations update the timeout value.
We do not want that so use a local variable. */
- struct timespec tval;
+ struct __timespec64 tval;
if (timeout != NULL)
{
tval = *timeout;
timeout = &tval;
}
- return SYSCALL_CANCEL (ppoll, fds, nfds, timeout, sigmask, _NSIG / 8);
+#ifdef __ASSUME_TIME64_SYSCALLS
+# ifndef __NR_ppoll_time64
+# define __NR_ppoll_time64 __NR_ppoll
+# endif
+ return SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask, _NSIG / 8);
+#else
+# ifdef __NR_ppoll_time64
+ int ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
+ _NSIG / 8);
+ if (ret >= 0 || errno != ENOSYS)
+ return ret;
+# endif
+ struct timespec ts32;
+ if (timeout)
+ {
+ if (! in_time_t_range (timeout->tv_sec))
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ ts32 = valid_timespec64_to_timespec (*timeout);
+ }
+
+ return SYSCALL_CANCEL (ppoll, fds, nfds, timeout ? &ts32 : NULL, sigmask,
+ _NSIG / 8);
+#endif
+}
+
+#if __TIMESIZE != 64
+int
+__ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
+ const sigset_t *sigmask)
+{
+ struct __timespec64 ts64;
+ if (timeout)
+ ts64 = valid_timespec_to_timespec64 (*timeout);
+
+ return __ppoll64 (fds, nfds, timeout ? &ts64 : NULL, sigmask);
}
+#endif
+strong_alias (__ppoll, ppoll)
libc_hidden_def (ppoll)