diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2019-11-12 12:17:41 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2019-11-12 12:17:41 -0300 |
commit | 023ea2130ce4191e3db8000c51befbf8782a3e4b (patch) | |
tree | e132954a0eb2bc04a908d4500661c0d4d622e98f | |
parent | f31de7b04764dc966216f849fbdebe7b59e12cee (diff) | |
download | glibc-azanella/pselect-time64.tar.gz |
y2038: linux: Provide __pselect64 implementationazanella/pselect-time64
-rw-r--r-- | include/sys/select.h | 17 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/pselect.c | 51 |
2 files changed, 61 insertions, 7 deletions
diff --git a/include/sys/select.h b/include/sys/select.h index 07bb49b994..6f6b848e29 100644 --- a/include/sys/select.h +++ b/include/sys/select.h @@ -14,5 +14,18 @@ extern int __select (int __nfds, fd_set *__restrict __readfds, struct timeval *__restrict __timeout); libc_hidden_proto (__select) -#endif -#endif +# if __TIMESIZE == 64 +# define __pselect64 __pselect +# else +# include <time.h> +# include <signal.h> + +extern int __pselect64 (int __nfds, fd_set *__readfds, fd_set *__writefds, + fd_set *__exceptfds, + const struct __timespec64 *__timeout, + const sigset_t *__sigmask); +libc_hidden_proto (__pselect64) +# endif /* __TIMESIZE == 64 */ + +#endif /* _ISOMAC */ +#endif /* _SYS_SELECT_H */ diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c index 77a5179925..45a3b4ab58 100644 --- a/sysdeps/unix/sysv/linux/pselect.c +++ b/sysdeps/unix/sysv/linux/pselect.c @@ -23,13 +23,13 @@ #include <kernel-features.h> #include <sysdep-cancel.h> -int -__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - const struct timespec *timeout, const sigset_t *sigmask) +int __pselect64 (int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, 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; @@ -49,9 +49,50 @@ __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, data.ss = (__syscall_ulong_t) (uintptr_t) sigmask; data.ss_len = _NSIG / 8; +#ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_pselect6_time64 +# define __NR_pselect6_time64 __NR_pselect6 +# endif + return SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds, + timeout, &data); +#else +# ifdef __NR_ppoll_time64 + int ret = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, + exceptfds, timeout, &data); + 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 (pselect6, nfds, readfds, writefds, exceptfds, - timeout, &data); + timeout ? &ts32 : NULL, &data); +#endif /* __ASSUME_TIME64_SYSCALLS */ } + +#if __TIMESIZE != 64 +int +__pselect (int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, const struct timespec *timeout, + const sigset_t *sigmask) +{ + struct __timespec64 ts64; + if (timeout) + ts64 = valid_timespec_to_timespec64 (*timeout); + + return __pselect64 (nfds, readfds, writefds, exceptfds, + timeout ? &ts64 : NULL, sigmask); +} +#endif #ifndef __pselect weak_alias (__pselect, pselect) #endif |