RFC: y2038: linux: Adjust __poll function implementation to use __ppoll64

Message ID 20191113134719.21874-1-lukma@denx.de
State Deferred
Headers

Commit Message

Lukasz Majewski Nov. 13, 2019, 1:47 p.m. UTC
  The __poll implementation (./sysdeps/unix/sysv/linux/poll.c) when the
__NR_poll is not defined uses ppoll syscall.
Adjust this code to use glibc's internal, Y2038 safe struct __timespec64
and __ppoll64 function.

The explicit __ppoll declaration is necessary to allow aliasing of __ppoll64
either via #define or using it directly.

By using __ppoll64 instead of __ppoll, systems with TIMESIZE == 32 gain support
for 64 bit time (as e.g. glibc's internal struct __timespec64 is used to pass
arguments).
---
 include/sys/poll.h             | 9 ++++++---
 sysdeps/unix/sysv/linux/poll.c | 6 +++---
 2 files changed, 9 insertions(+), 6 deletions(-)
  

Comments

Adhemerval Zanella Netto Nov. 14, 2019, 9:03 p.m. UTC | #1
On 13/11/2019 10:47, Lukasz Majewski wrote:
> The __poll implementation (./sysdeps/unix/sysv/linux/poll.c) when the
> __NR_poll is not defined uses ppoll syscall.
> Adjust this code to use glibc's internal, Y2038 safe struct __timespec64
> and __ppoll64 function.
> 
> The explicit __ppoll declaration is necessary to allow aliasing of __ppoll64
> either via #define or using it directly.
> 
> By using __ppoll64 instead of __ppoll, systems with TIMESIZE == 32 gain support
> for 64 bit time (as e.g. glibc's internal struct __timespec64 is used to pass
> arguments).

LGTM.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

> ---
>  include/sys/poll.h             | 9 ++++++---
>  sysdeps/unix/sysv/linux/poll.c | 6 +++---
>  2 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/include/sys/poll.h b/include/sys/poll.h
> index f904e21f89..a599426dc6 100644
> --- a/include/sys/poll.h
> +++ b/include/sys/poll.h
> @@ -7,12 +7,15 @@ extern int __poll (struct pollfd *__fds, unsigned long int __nfds,
>  libc_hidden_proto (__poll)
>  libc_hidden_proto (ppoll)
>  
> -# if __TIMESIZE == 64
> -#  define __ppoll64 __ppoll
> -# else
>  # include <time.h>
>  # include <signal.h>
> +extern int __ppoll (struct pollfd *fds, nfds_t nfds,
> +                    const struct timespec *timeout,
> +                    const sigset_t *sigmask);
>  
> +# if __TIMESIZE == 64
> +#  define __ppoll64 __ppoll
> +# else
>  extern int __ppoll64 (struct pollfd *fds, nfds_t nfds,
>                        const struct __timespec64 *timeout,
>                        const sigset_t *sigmask);
> diff --git a/sysdeps/unix/sysv/linux/poll.c b/sysdeps/unix/sysv/linux/poll.c
> index 8ea00563a4..588069c898 100644
> --- a/sysdeps/unix/sysv/linux/poll.c
> +++ b/sysdeps/unix/sysv/linux/poll.c
> @@ -28,8 +28,8 @@ __poll (struct pollfd *fds, nfds_t nfds, int timeout)
>  #ifdef __NR_poll
>    return SYSCALL_CANCEL (poll, fds, nfds, timeout);
>  #else
> -  struct timespec timeout_ts;
> -  struct timespec *timeout_ts_p = NULL;
> +  struct __timespec64 timeout_ts;
> +  struct __timespec64 *timeout_ts_p = NULL;
>  
>    if (timeout >= 0)
>      {
> @@ -38,7 +38,7 @@ __poll (struct pollfd *fds, nfds_t nfds, int timeout)
>        timeout_ts_p = &timeout_ts;
>      }
>  
> -  return SYSCALL_CANCEL (ppoll, fds, nfds, timeout_ts_p, NULL, 0);
> +  return __ppoll64 (fds, nfds, timeout_ts_p, NULL);
>  #endif
>  }
>  libc_hidden_def (__poll)
>
  

Patch

diff --git a/include/sys/poll.h b/include/sys/poll.h
index f904e21f89..a599426dc6 100644
--- a/include/sys/poll.h
+++ b/include/sys/poll.h
@@ -7,12 +7,15 @@  extern int __poll (struct pollfd *__fds, unsigned long int __nfds,
 libc_hidden_proto (__poll)
 libc_hidden_proto (ppoll)
 
-# if __TIMESIZE == 64
-#  define __ppoll64 __ppoll
-# else
 # include <time.h>
 # include <signal.h>
+extern int __ppoll (struct pollfd *fds, nfds_t nfds,
+                    const struct timespec *timeout,
+                    const sigset_t *sigmask);
 
+# if __TIMESIZE == 64
+#  define __ppoll64 __ppoll
+# else
 extern int __ppoll64 (struct pollfd *fds, nfds_t nfds,
                       const struct __timespec64 *timeout,
                       const sigset_t *sigmask);
diff --git a/sysdeps/unix/sysv/linux/poll.c b/sysdeps/unix/sysv/linux/poll.c
index 8ea00563a4..588069c898 100644
--- a/sysdeps/unix/sysv/linux/poll.c
+++ b/sysdeps/unix/sysv/linux/poll.c
@@ -28,8 +28,8 @@  __poll (struct pollfd *fds, nfds_t nfds, int timeout)
 #ifdef __NR_poll
   return SYSCALL_CANCEL (poll, fds, nfds, timeout);
 #else
-  struct timespec timeout_ts;
-  struct timespec *timeout_ts_p = NULL;
+  struct __timespec64 timeout_ts;
+  struct __timespec64 *timeout_ts_p = NULL;
 
   if (timeout >= 0)
     {
@@ -38,7 +38,7 @@  __poll (struct pollfd *fds, nfds_t nfds, int timeout)
       timeout_ts_p = &timeout_ts;
     }
 
-  return SYSCALL_CANCEL (ppoll, fds, nfds, timeout_ts_p, NULL, 0);
+  return __ppoll64 (fds, nfds, timeout_ts_p, NULL);
 #endif
 }
 libc_hidden_def (__poll)