unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls
@ 2020-02-14 16:31 Alistair Francis
  2020-02-14 16:31 ` [PATCH v3 1/8] sysv/linux: Rename alpha functions to be alpha specific Alistair Francis
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: Alistair Francis @ 2020-02-14 16:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, Alistair Francis

On y2038 safe 32-bit systems the Linux kernel expects itimerval
and rusage to use a 32-bit time_t, even though the other time_t's
are 64-bit.

This series converts getitimer, setitimer, getrusage and wait4 to be
both y2038 safe and pass a 32-bit time_t based on the
__KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 macro. On 32-bit systems
we will pass a 32-bit time to the kernel (no matter the time_t size). This is
no change for most 64-bit architectures or 32-bit architectures with a 32-bit time_t.

We can also remove the old Alpha functions as this is now handled genericly.

I don't have a way to test this on Alpha, would someone mind testing it for me?

This follows the standard y2038 conversion so that we don't break
backwards compatibility but we expose a 64-bit version for y2038 safe
architectrures (like RV32).

This series was tested by running:
  ./scripts/build-many-glibcs.py ... compilers
  ./scripts/build-many-glibcs.py ... glibcs
on my x86_64 machine.

I also ran make check on RV32 and I only see a total of 10 test failures.

Alistair Francis (8):
  sysv/linux: Rename alpha functions to be alpha specific
  time: Add a timeval with a 32-bit tv_sec and tv_usec
  time: Add a __itimerval64 struct
  sysv: Define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
  linux: Use long time_t __getitimer/__setitimer
  resource: Add a __rusage64 struct
  linux: Use long time_t for wait4/getrusage
  sysv/alpha: Use generic __timeval32 and helpers

 bits/typesizes.h                              |   6 +
 include/sys/resource.h                        | 120 ++++++++++++++++++
 include/time.h                                |  71 +++++++++++
 .../unix/sysv/linux/alpha/bits/typesizes.h    |   3 +
 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c   |   7 +-
 sysdeps/unix/sysv/linux/alpha/osf_getitimer.c |   3 +-
 sysdeps/unix/sysv/linux/alpha/osf_getrusage.c |   8 +-
 .../unix/sysv/linux/alpha/osf_gettimeofday.c  |   4 +-
 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c |   5 +-
 .../unix/sysv/linux/alpha/osf_settimeofday.c  |   4 +-
 sysdeps/unix/sysv/linux/alpha/osf_utimes.c    |   4 +-
 sysdeps/unix/sysv/linux/alpha/osf_wait4.c     |   8 +-
 .../unix/sysv/linux/generic/bits/typesizes.h  |   7 +
 sysdeps/unix/sysv/linux/getitimer.c           |  61 +++++++++
 sysdeps/unix/sysv/linux/getrusage.c           |  58 +++++++++
 sysdeps/unix/sysv/linux/s390/bits/typesizes.h |   6 +
 sysdeps/unix/sysv/linux/setitimer.c           |  95 ++++++++++++++
 .../unix/sysv/linux/sparc/bits/typesizes.h    |   6 +
 .../unix/sysv/linux/{alpha => }/tv32-compat.h |  86 +++++--------
 sysdeps/unix/sysv/linux/wait4.c               |  49 ++++++-
 sysdeps/unix/sysv/linux/x86/bits/typesizes.h  |   3 +
 21 files changed, 541 insertions(+), 73 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/getitimer.c
 create mode 100644 sysdeps/unix/sysv/linux/getrusage.c
 create mode 100644 sysdeps/unix/sysv/linux/setitimer.c
 rename sysdeps/unix/sysv/linux/{alpha => }/tv32-compat.h (59%)

-- 
2.25.0


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3 1/8] sysv/linux: Rename alpha functions to be alpha specific
  2020-02-14 16:31 [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls Alistair Francis
@ 2020-02-14 16:31 ` Alistair Francis
  2020-02-15 13:54   ` Lukasz Majewski
  2020-02-14 16:31 ` [PATCH v3 2/8] time: Add a timeval with a 32-bit tv_sec and tv_usec Alistair Francis
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Alistair Francis @ 2020-02-14 16:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, Alistair Francis

These functions are alpha specifc, rename them to be clear.

Let's also rename the header file from tv32-compat.h to
alpha-tv32-compat.h. This is to avoid conflicts with the one we will
introduce later.
---
 .../alpha/{tv32-compat.h => alpha-tv32-compat.h} | 16 ++++++++--------
 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c      | 10 +++++-----
 sysdeps/unix/sysv/linux/alpha/osf_getitimer.c    |  6 +++---
 sysdeps/unix/sysv/linux/alpha/osf_getrusage.c    |  4 ++--
 sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c |  4 ++--
 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c    | 10 +++++-----
 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c |  4 ++--
 sysdeps/unix/sysv/linux/alpha/osf_utimes.c       |  6 +++---
 sysdeps/unix/sysv/linux/alpha/osf_wait4.c        |  4 ++--
 9 files changed, 32 insertions(+), 32 deletions(-)
 rename sysdeps/unix/sysv/linux/alpha/{tv32-compat.h => alpha-tv32-compat.h} (88%)

diff --git a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h b/sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h
similarity index 88%
rename from sysdeps/unix/sysv/linux/alpha/tv32-compat.h
rename to sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h
index 8e34ed1c1b..3073005c65 100644
--- a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
+++ b/sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h
@@ -70,13 +70,13 @@ struct rusage32
    overflow, they write { INT32_MAX, TV_USEC_MAX } to the output.  */
 
 static inline struct timeval
-valid_timeval32_to_timeval (const struct timeval32 tv)
+alpha_valid_timeval32_to_timeval (const struct timeval32 tv)
 {
   return (struct timeval) { tv.tv_sec, tv.tv_usec };
 }
 
 static inline struct timeval32
-valid_timeval_to_timeval32 (const struct timeval tv64)
+alpha_valid_timeval_to_timeval32 (const struct timeval tv64)
 {
   if (__glibc_unlikely (tv64.tv_sec > (time_t) INT32_MAX))
     return (struct timeval32) { INT32_MAX, TV_USEC_MAX};
@@ -84,27 +84,27 @@ valid_timeval_to_timeval32 (const struct timeval tv64)
 }
 
 static inline struct timespec
-valid_timeval32_to_timespec (const struct timeval32 tv)
+alpha_valid_timeval32_to_timespec (const struct timeval32 tv)
 {
   return (struct timespec) { tv.tv_sec, tv.tv_usec * 1000 };
 }
 
 static inline struct timeval32
-valid_timespec_to_timeval32 (const struct timespec ts)
+alpha_valid_timespec_to_timeval32 (const struct timespec ts)
 {
   return (struct timeval32) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
 }
 
 static inline void
-rusage64_to_rusage32 (struct rusage32 *restrict r32,
+alpha_rusage64_to_rusage32 (struct rusage32 *restrict r32,
                       const struct rusage *restrict r64)
 {
   /* Make sure the entire output structure is cleared, including
      padding and reserved fields.  */
   memset (r32, 0, sizeof *r32);
 
-  r32->ru_utime    = valid_timeval_to_timeval32 (r64->ru_utime);
-  r32->ru_stime    = valid_timeval_to_timeval32 (r64->ru_stime);
+  r32->ru_utime    = alpha_valid_timeval_to_timeval32 (r64->ru_utime);
+  r32->ru_stime    = alpha_valid_timeval_to_timeval32 (r64->ru_stime);
   r32->ru_maxrss   = r64->ru_maxrss;
   r32->ru_ixrss    = r64->ru_ixrss;
   r32->ru_idrss    = r64->ru_idrss;
@@ -121,4 +121,4 @@ rusage64_to_rusage32 (struct rusage32 *restrict r32,
   r32->ru_nivcsw   = r64->ru_nivcsw;
 }
 
-#endif /* tv32-compat.h */
+#endif /* alpha-tv32-compat.h */
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
index 9825a4734d..f0a1123639 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
@@ -22,7 +22,7 @@
 
 #include <sys/time.h>
 #include <sys/timex.h>
-#include <tv32-compat.h>
+#include <alpha-tv32-compat.h>
 
 struct timex32 {
 	unsigned int modes;	/* mode selector */
@@ -57,13 +57,13 @@ int
 attribute_compat_text_section
 __adjtime_tv32 (const struct timeval32 *itv, struct timeval32 *otv)
 {
-  struct timeval itv64 = valid_timeval32_to_timeval (*itv);
+  struct timeval itv64 = alpha_valid_timeval32_to_timeval (*itv);
   struct timeval otv64;
 
   if (__adjtime (&itv64, &otv64) == -1)
     return -1;
 
-  *otv = valid_timeval_to_timeval32 (otv64);
+  *otv = alpha_valid_timeval_to_timeval32 (otv64);
   return 0;
 }
 
@@ -91,7 +91,7 @@ __adjtimex_tv32 (struct timex32 *tx)
   tx64.calcnt    = tx->calcnt;
   tx64.errcnt    = tx->errcnt;
   tx64.stbcnt    = tx->stbcnt;
-  tx64.time      = valid_timeval32_to_timeval (tx->time);
+  tx64.time      = alpha_valid_timeval32_to_timeval (tx->time);
 
   int status = __adjtimex (&tx64);
   if (status < 0)
@@ -116,7 +116,7 @@ __adjtimex_tv32 (struct timex32 *tx)
   tx->calcnt    = tx64.calcnt;
   tx->errcnt    = tx64.errcnt;
   tx->stbcnt    = tx64.stbcnt;
-  tx->time      = valid_timeval_to_timeval32 (tx64.time);
+  tx->time      = alpha_valid_timeval_to_timeval32 (tx64.time);
 
   return status;
 }
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
index e9de2b287b..204d4ba796 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
@@ -21,7 +21,7 @@
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
 #include <sys/time.h>
-#include <tv32-compat.h>
+#include <alpha-tv32-compat.h>
 
 int
 attribute_compat_text_section
@@ -33,9 +33,9 @@ __getitimer_tv32 (int which, struct itimerval32 *curr_value)
 
   /* Write all fields of 'curr_value' regardless of overflow.  */
   curr_value->it_interval
-    = valid_timeval_to_timeval32 (curr_value_64.it_interval);
+    = alpha_valid_timeval_to_timeval32 (curr_value_64.it_interval);
   curr_value->it_value
-    = valid_timeval_to_timeval32 (curr_value_64.it_value);
+    = alpha_valid_timeval_to_timeval32 (curr_value_64.it_value);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
index 74c6fb49aa..be81994654 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
@@ -22,7 +22,7 @@
 
 #include <sys/time.h>
 #include <sys/resource.h>
-#include <tv32-compat.h>
+#include <alpha-tv32-compat.h>
 
 int
 __getrusage_tv32 (int who, struct rusage32 *usage32)
@@ -31,7 +31,7 @@ __getrusage_tv32 (int who, struct rusage32 *usage32)
   if (__getrusage (who, &usage64) == -1)
     return -1;
 
-  rusage64_to_rusage32 (usage32, &usage64);
+  alpha_rusage64_to_rusage32 (usage32, &usage64);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
index df7f06765b..9ffda2fde3 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
@@ -23,7 +23,7 @@
 #include <string.h>
 #include <time.h>
 #include <sys/time.h>
-#include <tv32-compat.h>
+#include <alpha-tv32-compat.h>
 
 /* Get the current time of day and timezone information putting it
    into *TV and *TZ.  */
@@ -38,7 +38,7 @@ __gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict tz)
   struct timespec ts;
   __clock_gettime (CLOCK_REALTIME, &ts);
 
-  *tv32 = valid_timespec_to_timeval32 (ts);
+  *tv32 = alpha_valid_timespec_to_timeval32 (ts);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
index 7df2d1b71c..726dfc8b0e 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
@@ -21,7 +21,7 @@
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
 #include <sys/time.h>
-#include <tv32-compat.h>
+#include <alpha-tv32-compat.h>
 
 int
 attribute_compat_text_section
@@ -30,9 +30,9 @@ __setitimer_tv32 (int which, const struct itimerval32 *restrict new_value,
 {
   struct itimerval new_value_64;
   new_value_64.it_interval
-    = valid_timeval32_to_timeval (new_value->it_interval);
+    = alpha_valid_timeval32_to_timeval (new_value->it_interval);
   new_value_64.it_value
-    = valid_timeval32_to_timeval (new_value->it_value);
+    = alpha_valid_timeval32_to_timeval (new_value->it_value);
 
   if (old_value == NULL)
     return __setitimer (which, &new_value_64, NULL);
@@ -43,9 +43,9 @@ __setitimer_tv32 (int which, const struct itimerval32 *restrict new_value,
 
   /* Write all fields of 'old_value' regardless of overflow.  */
   old_value->it_interval
-     = valid_timeval_to_timeval32 (old_value_64.it_interval);
+     = alpha_valid_timeval_to_timeval32 (old_value_64.it_interval);
   old_value->it_value
-     = valid_timeval_to_timeval32 (old_value_64.it_value);
+     = alpha_valid_timeval_to_timeval32 (old_value_64.it_value);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
index 6e17a95a47..044363e079 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -23,7 +23,7 @@
 #include <sys/time.h>
 #include <time.h>
 #include <errno.h>
-#include <tv32-compat.h>
+#include <alpha-tv32-compat.h>
 
 /* Set the current time of day and timezone information.
    This call is restricted to the super-user.  */
@@ -42,7 +42,7 @@ __settimeofday_tv32 (const struct timeval32 *tv32,
       return __settimezone (tz);
     }
 
-  struct timespec ts = valid_timeval32_to_timespec (*tv32);
+  struct timespec ts = alpha_valid_timeval32_to_timespec (*tv32);
   return __clock_settime (CLOCK_REALTIME, &ts);
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_utimes.c b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
index 6c3fad0132..8ad9fb567c 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
@@ -21,15 +21,15 @@
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
 #include <sys/time.h>
-#include <tv32-compat.h>
+#include <alpha-tv32-compat.h>
 
 int
 attribute_compat_text_section
 __utimes_tv32 (const char *filename, const struct timeval32 times32[2])
 {
   struct timeval times[2];
-  times[0] = valid_timeval32_to_timeval (times32[0]);
-  times[1] = valid_timeval32_to_timeval (times32[1]);
+  times[0] = alpha_valid_timeval32_to_timeval (times32[0]);
+  times[1] = alpha_valid_timeval32_to_timeval (times32[1]);
   return __utimes (filename, times);
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
index 6af8347871..c664e8e93f 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
@@ -23,7 +23,7 @@
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/wait.h>
-#include <tv32-compat.h>
+#include <alpha-tv32-compat.h>
 
 pid_t
 attribute_compat_text_section
@@ -33,7 +33,7 @@ __wait4_tv32 (pid_t pid, int *status, int options, struct rusage32 *usage32)
   pid_t child = __wait4 (pid, status, options, &usage64);
 
   if (child >= 0 && usage32 != NULL)
-    rusage64_to_rusage32 (usage32, &usage64);
+    alpha_rusage64_to_rusage32 (usage32, &usage64);
   return child;
 }
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 2/8] time: Add a timeval with a 32-bit tv_sec and tv_usec
  2020-02-14 16:31 [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls Alistair Francis
  2020-02-14 16:31 ` [PATCH v3 1/8] sysv/linux: Rename alpha functions to be alpha specific Alistair Francis
@ 2020-02-14 16:31 ` Alistair Francis
  2020-02-15 13:57   ` Lukasz Majewski
  2020-02-14 16:31 ` [PATCH v3 3/8] time: Add a __itimerval64 struct Alistair Francis
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Alistair Francis @ 2020-02-14 16:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, Alistair Francis

On y2038 safe 32-bit systems the Linux kernel expects itimerval to
use a 32-bit time_t, even though the other time_t's are 64-bit. To
address this let's add a __timeval32 struct to be used internally.
---
 include/time.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/include/time.h b/include/time.h
index 73f66277ac..ddc0ded640 100644
--- a/include/time.h
+++ b/include/time.h
@@ -400,6 +400,51 @@ timespec64_to_timeval64 (const struct __timespec64 ts64)
   return tv64;
 }
 
+/* A version of 'struct timeval' with 32-bit time_t
+   and suseconds_t.  */
+struct __timeval32
+{
+  __int32_t tv_sec;         /* Seconds.  */
+  __int32_t tv_usec;        /* Microseconds.  */
+};
+
+/* Conversion functions for converting to/from __timeval32  */
+static inline struct __timeval64
+valid_timeval32_to_timeval64 (const struct __timeval32 tv)
+{
+  return (struct __timeval64) { tv.tv_sec, tv.tv_usec };
+}
+
+static inline struct __timeval32
+valid_timeval64_to_timeval32 (const struct __timeval64 tv64)
+{
+  return (struct __timeval32) { tv64.tv_sec, tv64.tv_usec };
+}
+
+static inline struct timeval
+valid_timeval32_to_timeval (const struct __timeval32 tv)
+{
+  return (struct timeval) { tv.tv_sec, tv.tv_usec };
+}
+
+static inline struct __timeval32
+valid_timeval_to_timeval32 (const struct timeval tv)
+{
+  return (struct __timeval32) { tv.tv_sec, tv.tv_usec };
+}
+
+static inline struct timespec
+valid_timeval32_to_timespec (const struct __timeval32 tv)
+{
+  return (struct timespec) { tv.tv_sec, tv.tv_usec * 1000 };
+}
+
+static inline struct __timeval32
+valid_timespec_to_timeval32 (const struct timespec ts)
+{
+  return (struct __timeval32) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
+}
+
 /* Check if a value is in the valid nanoseconds range. Return true if
    it is, false otherwise.  */
 static inline bool
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 3/8] time: Add a __itimerval64 struct
  2020-02-14 16:31 [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls Alistair Francis
  2020-02-14 16:31 ` [PATCH v3 1/8] sysv/linux: Rename alpha functions to be alpha specific Alistair Francis
  2020-02-14 16:31 ` [PATCH v3 2/8] time: Add a timeval with a 32-bit tv_sec and tv_usec Alistair Francis
@ 2020-02-14 16:31 ` Alistair Francis
  2020-02-14 16:31 ` [PATCH v3 4/8] sysv: Define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 Alistair Francis
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-02-14 16:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, Alistair Francis, Lukasz Majewski

Add a __itimerval64 which always uses a 64-bit time_t.

Reviewed-by: Lukasz Majewski <lukma@denx.de>
---
 include/time.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/time.h b/include/time.h
index ddc0ded640..34dffaf95f 100644
--- a/include/time.h
+++ b/include/time.h
@@ -108,6 +108,17 @@ struct __timeval64
 };
 #endif
 
+#if __TIMESIZE == 64
+# define __itimerval64 itimerval
+#else
+/* The glibc's internal representation of the struct itimerval.  */
+struct __itimerval64
+{
+  struct __timeval64 it_interval;
+  struct __timeval64 it_value;
+};
+#endif
+
 #if __TIMESIZE == 64
 # define __ctime64 ctime
 #else
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 4/8] sysv: Define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
  2020-02-14 16:31 [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls Alistair Francis
                   ` (2 preceding siblings ...)
  2020-02-14 16:31 ` [PATCH v3 3/8] time: Add a __itimerval64 struct Alistair Francis
@ 2020-02-14 16:31 ` Alistair Francis
  2020-02-15 14:03   ` Lukasz Majewski
  2020-02-14 16:31 ` [PATCH v3 5/8] linux: Use long time_t __getitimer/__setitimer Alistair Francis
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Alistair Francis @ 2020-02-14 16:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, Alistair Francis

On y2038 safe 32-bit systems the Linux kernel expects itimerval
and rusage to use a 32-bit time_t, even though the other time_t's
are 64-bit.

There are also other occurances where the time passed to the kernel via
timeval doesn't match the wordsize.

To handle these cases let's define a new macro
__KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64. This macro specifies if the
kernel's old_timeval matches the new timeval64. This should be true for
64-bit architectures (expect for Alpha) and x32.
---
 bits/typesizes.h                                 | 6 ++++++
 sysdeps/unix/sysv/linux/alpha/bits/typesizes.h   | 3 +++
 sysdeps/unix/sysv/linux/generic/bits/typesizes.h | 7 +++++++
 sysdeps/unix/sysv/linux/s390/bits/typesizes.h    | 6 ++++++
 sysdeps/unix/sysv/linux/sparc/bits/typesizes.h   | 6 ++++++
 sysdeps/unix/sysv/linux/x86/bits/typesizes.h     | 3 +++
 6 files changed, 31 insertions(+)

diff --git a/bits/typesizes.h b/bits/typesizes.h
index 599408973e..8f16903a21 100644
--- a/bits/typesizes.h
+++ b/bits/typesizes.h
@@ -76,10 +76,16 @@
 
 /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
 # define __STATFS_MATCHES_STATFS64  1
+
+/* And for getitimer, setitimer and rusage  */
+# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
 #else
 # define __RLIM_T_MATCHES_RLIM64_T	0
 
 # define __STATFS_MATCHES_STATFS64  0
+
+/* And for getitimer, setitimer and rusage  */
+# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
 #endif
 
 /* Number of descriptors that can fit in an `fd_set'.  */
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h b/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
index 28ee3e5920..e5d7774468 100644
--- a/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
+++ b/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
@@ -73,6 +73,9 @@
 /* Not for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
 # define __STATFS_MATCHES_STATFS64  0
 
+/* And for getitimer, setitimer and rusage  */
+#define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
+
 /* Number of descriptors that can fit in an `fd_set'.  */
 #define	__FD_SETSIZE		1024
 
diff --git a/sysdeps/unix/sysv/linux/generic/bits/typesizes.h b/sysdeps/unix/sysv/linux/generic/bits/typesizes.h
index 7c963e523e..48727c1da7 100644
--- a/sysdeps/unix/sysv/linux/generic/bits/typesizes.h
+++ b/sysdeps/unix/sysv/linux/generic/bits/typesizes.h
@@ -77,11 +77,18 @@
 
 /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
 # define __STATFS_MATCHES_STATFS64  1
+
+/* And for getitimer, setitimer and rusage  */
+# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
 #else
 # define __RLIM_T_MATCHES_RLIM64_T	0
 
 # define __STATFS_MATCHES_STATFS64  0
+
+/* And for getitimer, setitimer and rusage  */
+# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
 #endif
+
 /* Number of descriptors that can fit in an `fd_set'.  */
 #define	__FD_SETSIZE		1024
 
diff --git a/sysdeps/unix/sysv/linux/s390/bits/typesizes.h b/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
index e775e460bb..2bc87c1079 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
+++ b/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
@@ -82,10 +82,16 @@
 
 /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
 # define __STATFS_MATCHES_STATFS64  1
+
+/* And for getitimer, setitimer and rusage  */
+# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
 #else
 # define __RLIM_T_MATCHES_RLIM64_T	0
 
 # define __STATFS_MATCHES_STATFS64  0
+
+/* And for getitimer, setitimer and rusage  */
+# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
 #endif
 
 /* Number of descriptors that can fit in an `fd_set'.  */
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h b/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
index ac48c23e37..288a902b5f 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
@@ -76,10 +76,16 @@
 
 /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
 # define __STATFS_MATCHES_STATFS64  1
+
+/* And for getitimer, setitimer and rusage  */
+# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
 #else
 # define __RLIM_T_MATCHES_RLIM64_T	0
 
 # define __STATFS_MATCHES_STATFS64  0
+
+/* And for getitimer, setitimer and rusage  */
+# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
 #endif
 
 /* Number of descriptors that can fit in an `fd_set'.  */
diff --git a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h
index 87c50a4f32..f68dfecc90 100644
--- a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h
+++ b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h
@@ -94,6 +94,9 @@
 # define __STATFS_MATCHES_STATFS64  0
 #endif
 
+/* And for getitimer, setitimer and rusage  */
+#define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
+
 /* Number of descriptors that can fit in an `fd_set'.  */
 #define __FD_SETSIZE		1024
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 5/8] linux: Use long time_t __getitimer/__setitimer
  2020-02-14 16:31 [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls Alistair Francis
                   ` (3 preceding siblings ...)
  2020-02-14 16:31 ` [PATCH v3 4/8] sysv: Define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 Alistair Francis
@ 2020-02-14 16:31 ` Alistair Francis
  2020-02-15 16:26   ` Lukasz Majewski
  2020-02-14 16:31 ` [PATCH v3 6/8] resource: Add a __rusage64 struct Alistair Francis
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: Alistair Francis @ 2020-02-14 16:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, Alistair Francis

The Linux kernel expects itimerval to use a 32-bit time_t, even on archs
with a 64-bit time_t (like RV32). To address this let's convert
itimerval to/from 32-bit and 64-bit to ensure the kernel always gets
a 32-bit time_t.

While we are converting these functions let's also convert them to be
the y2038 safe versions. This means there is a *64 function that is
called by a backwards compatible wrapper.
---
 include/time.h                        | 15 +++++
 sysdeps/unix/sysv/linux/getitimer.c   | 61 +++++++++++++++++
 sysdeps/unix/sysv/linux/setitimer.c   | 95 +++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/tv32-compat.h | 35 ++++++++++
 4 files changed, 206 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/getitimer.c
 create mode 100644 sysdeps/unix/sysv/linux/setitimer.c
 create mode 100644 sysdeps/unix/sysv/linux/tv32-compat.h

diff --git a/include/time.h b/include/time.h
index 34dffaf95f..cdaf461c3f 100644
--- a/include/time.h
+++ b/include/time.h
@@ -6,6 +6,7 @@
 # include <bits/types/locale_t.h>
 # include <stdbool.h>
 # include <time/mktime-internal.h>
+# include <sys/time.h>
 # include <endian.h>
 # include <time-clockid.h>
 # include <sys/time.h>
@@ -119,6 +120,20 @@ struct __itimerval64
 };
 #endif
 
+#if __TIMESIZE == 64
+# define __getitimer64 __getitimer
+# define __setitimer64 __setitimer
+#else
+extern int __getitimer64 (enum __itimer_which __which,
+                          struct __itimerval64 *__value);
+
+libc_hidden_proto (__getitimer64)
+extern int __setitimer64 (enum __itimer_which __which,
+                          const struct __itimerval64 *__restrict __new,
+                          struct __itimerval64 *__restrict __old);
+libc_hidden_proto (__setitimer64)
+#endif
+
 #if __TIMESIZE == 64
 # define __ctime64 ctime
 #else
diff --git a/sysdeps/unix/sysv/linux/getitimer.c b/sysdeps/unix/sysv/linux/getitimer.c
new file mode 100644
index 0000000000..62d58a7af5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/getitimer.c
@@ -0,0 +1,61 @@
+/* getitimer -- Get the state of an interval timer.  Linux/tv32 version.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sysdep.h>
+#include <tv32-compat.h>
+
+int
+__getitimer64 (__itimer_which_t which, struct __itimerval64 *curr_value)
+{
+
+#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
+  return INLINE_SYSCALL_CALL (getitimer, which, curr_value);
+#else
+  struct __itimerval32 curr_value_32;
+  if (INLINE_SYSCALL_CALL (getitimer, which, &curr_value_32) == -1)
+    return -1;
+
+  /* Write all fields of 'curr_value' regardless of overflow.  */
+  curr_value->it_interval
+    = valid_timeval32_to_timeval64 (curr_value_32.it_interval);
+  curr_value->it_value
+    = valid_timeval32_to_timeval64 (curr_value_32.it_value);
+  return 0;
+#endif
+}
+
+
+#if __TIMESIZE != 64
+libc_hidden_def (__getitimer64)
+int
+__getitimer (__itimer_which_t which, struct itimerval *curr_value)
+{
+  struct __itimerval64 val64;
+
+  val64.it_interval
+    = valid_timeval_to_timeval64 (curr_value->it_interval);
+  val64.it_value
+    = valid_timeval_to_timeval64 (curr_value->it_value);
+
+  return __getitimer64 (which, &val64);
+}
+#endif
+weak_alias (__getitimer, getitimer)
diff --git a/sysdeps/unix/sysv/linux/setitimer.c b/sysdeps/unix/sysv/linux/setitimer.c
new file mode 100644
index 0000000000..238853dd33
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/setitimer.c
@@ -0,0 +1,95 @@
+/* setitimer -- Set the state of an interval timer.  Linux/tv32 version.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sysdep.h>
+#include <tv32-compat.h>
+
+int
+__setitimer64 (__itimer_which_t which,
+               const struct __itimerval64 *restrict new_value,
+               struct __itimerval64 *restrict old_value)
+{
+#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
+  return INLINE_SYSCALL_CALL (setitimer, which, new_value, old_value);
+#else
+  struct __itimerval32 new_value_32;
+
+  if (! in_time_t_range (new_value->it_interval.tv_sec))
+  {
+    __set_errno (EOVERFLOW);
+    return -1;
+  }
+  new_value_32.it_interval
+    = valid_timeval64_to_timeval32 (new_value->it_interval);
+
+  if (! in_time_t_range (new_value->it_value.tv_sec))
+  {
+    __set_errno (EOVERFLOW);
+    return -1;
+  }
+  new_value_32.it_value
+    = valid_timeval64_to_timeval32 (new_value->it_value);
+
+  if (old_value == NULL)
+    return INLINE_SYSCALL_CALL (setitimer, which, &new_value_32, NULL);
+
+  struct __itimerval32 old_value_32;
+  if (INLINE_SYSCALL_CALL (setitimer, which, &new_value_32, &old_value_32) == -1)
+    return -1;
+
+  /* Write all fields of 'old_value' regardless of overflow.  */
+  old_value->it_interval
+     = valid_timeval32_to_timeval64 (old_value_32.it_interval);
+  old_value->it_value
+     = valid_timeval32_to_timeval64 (old_value_32.it_value);
+  return 0;
+#endif
+}
+
+#if __TIMESIZE != 64
+libc_hidden_def (__setitimer64)
+int
+__setitimer (__itimer_which_t which,
+             const struct itimerval *restrict new_value,
+             struct itimerval *restrict old_value)
+{
+  int ret;
+  struct __itimerval64 new64, old64;
+
+  new64.it_interval
+    = valid_timeval_to_timeval64 (new_value->it_interval);
+  new64.it_value
+    = valid_timeval_to_timeval64 (new_value->it_value);
+
+  ret = __setitimer64 (which, &new64, old_value ? &old64 : NULL);
+
+  if (ret == 0 && old_value)
+    {
+      old_value->it_interval
+        = valid_timeval64_to_timeval (old64.it_interval);
+      old_value->it_value
+        = valid_timeval64_to_timeval (old64.it_value);
+    }
+
+  return ret;
+}
+#endif
+weak_alias (__setitimer, setitimer)
diff --git a/sysdeps/unix/sysv/linux/tv32-compat.h b/sysdeps/unix/sysv/linux/tv32-compat.h
new file mode 100644
index 0000000000..4eb6f216ea
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tv32-compat.h
@@ -0,0 +1,35 @@
+/* Compatibility definitions for `struct timeval' with 32-bit time_t.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TV32_COMPAT_H
+#define _TV32_COMPAT_H 1
+
+#include <features.h>
+
+#include <bits/types.h>
+#include <bits/types/time_t.h>
+#include <bits/types/struct_timeval.h>
+
+/* Structures containing 'struct timeval' with 32-bit time_t.  */
+struct __itimerval32
+{
+  struct __timeval32 it_interval;
+  struct __timeval32 it_value;
+};
+
+#endif /* tv32-compat.h */
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 6/8] resource: Add a __rusage64 struct
  2020-02-14 16:31 [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls Alistair Francis
                   ` (4 preceding siblings ...)
  2020-02-14 16:31 ` [PATCH v3 5/8] linux: Use long time_t __getitimer/__setitimer Alistair Francis
@ 2020-02-14 16:31 ` Alistair Francis
  2020-02-14 16:31 ` [PATCH v3 7/8] linux: Use long time_t for wait4/getrusage Alistair Francis
  2020-02-14 16:31 ` [PATCH v3 8/8] sysv/alpha: Use generic __timeval32 and helpers Alistair Francis
  7 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-02-14 16:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, Alistair Francis, Lukasz Majewski

Add a __rusage64 struct which always uses a 64-bit time_t.

Reviewed-by: Lukasz Majewski <lukma@denx.de>
---
 include/sys/resource.h | 110 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/include/sys/resource.h b/include/sys/resource.h
index c55d4e63bd..9d604dfe3e 100644
--- a/include/sys/resource.h
+++ b/include/sys/resource.h
@@ -2,6 +2,116 @@
 #include <resource/sys/resource.h>
 
 #ifndef _ISOMAC
+# include <time.h>
+# include <string.h>
+
+/* Internal version of rusage with a 64-bit time_t. */
+#if __TIMESIZE == 64
+# define __rusage64 rusage
+#else
+struct __rusage64
+  {
+    struct __timeval64 ru_utime;
+    struct __timeval64 ru_stime;
+    __extension__ union
+      {
+	long int ru_maxrss;
+	__syscall_slong_t __ru_maxrss_word;
+      };
+    __extension__ union
+      {
+	long int ru_ixrss;
+	__syscall_slong_t __ru_ixrss_word;
+      };
+    __extension__ union
+      {
+	long int ru_idrss;
+	__syscall_slong_t __ru_idrss_word;
+      };
+    __extension__ union
+      {
+	long int ru_isrss;
+	 __syscall_slong_t __ru_isrss_word;
+      };
+    __extension__ union
+      {
+	long int ru_minflt;
+	__syscall_slong_t __ru_minflt_word;
+      };
+    __extension__ union
+      {
+	long int ru_majflt;
+	__syscall_slong_t __ru_majflt_word;
+      };
+    __extension__ union
+      {
+	long int ru_nswap;
+	__syscall_slong_t __ru_nswap_word;
+      };
+    __extension__ union
+      {
+	long int ru_inblock;
+	__syscall_slong_t __ru_inblock_word;
+      };
+    __extension__ union
+      {
+	long int ru_oublock;
+	__syscall_slong_t __ru_oublock_word;
+      };
+    __extension__ union
+      {
+	long int ru_msgsnd;
+	__syscall_slong_t __ru_msgsnd_word;
+      };
+    __extension__ union
+      {
+	long int ru_msgrcv;
+	__syscall_slong_t __ru_msgrcv_word;
+      };
+    __extension__ union
+      {
+	long int ru_nsignals;
+	__syscall_slong_t __ru_nsignals_word;
+      };
+    __extension__ union
+      {
+	long int ru_nvcsw;
+	__syscall_slong_t __ru_nvcsw_word;
+      };
+    __extension__ union
+      {
+	long int ru_nivcsw;
+	__syscall_slong_t __ru_nivcsw_word;
+      };
+  };
+#endif
+
+static inline void
+rusage64_to_rusage (const struct __rusage64 *restrict r64,
+                    struct rusage *restrict r)
+{
+  /* Make sure the entire output structure is cleared, including
+     padding and reserved fields.  */
+  memset (r, 0, sizeof *r);
+
+  r->ru_utime    = valid_timeval64_to_timeval (r64->ru_utime);
+  r->ru_stime    = valid_timeval64_to_timeval (r64->ru_stime);
+  r->ru_maxrss   = r64->ru_maxrss;
+  r->ru_ixrss    = r64->ru_ixrss;
+  r->ru_idrss    = r64->ru_idrss;
+  r->ru_isrss    = r64->ru_isrss;
+  r->ru_minflt   = r64->ru_minflt;
+  r->ru_majflt   = r64->ru_majflt;
+  r->ru_nswap    = r64->ru_nswap;
+  r->ru_inblock  = r64->ru_inblock;
+  r->ru_oublock  = r64->ru_oublock;
+  r->ru_msgsnd   = r64->ru_msgsnd;
+  r->ru_msgrcv   = r64->ru_msgrcv;
+  r->ru_nsignals = r64->ru_nsignals;
+  r->ru_nvcsw    = r64->ru_nvcsw;
+  r->ru_nivcsw   = r64->ru_nivcsw;
+}
+
 /* Prototypes repeated instead of using __typeof because
    sys/resource.h is included in C++ tests, and declaring functions
    with __typeof and __THROW doesn't work for C++.  */
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 7/8] linux: Use long time_t for wait4/getrusage
  2020-02-14 16:31 [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls Alistair Francis
                   ` (5 preceding siblings ...)
  2020-02-14 16:31 ` [PATCH v3 6/8] resource: Add a __rusage64 struct Alistair Francis
@ 2020-02-14 16:31 ` Alistair Francis
  2020-02-15 16:27   ` Lukasz Majewski
  2020-02-14 16:31 ` [PATCH v3 8/8] sysv/alpha: Use generic __timeval32 and helpers Alistair Francis
  7 siblings, 1 reply; 17+ messages in thread
From: Alistair Francis @ 2020-02-14 16:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, Alistair Francis

The Linux kernel expects rusage to use a 32-bit time_t, even on archs
with a 64-bit time_t (like RV32). To address this let's convert
rusage to/from 32-bit and 64-bit to ensure the kernel always gets
a 32-bit time_t.

While we are converting these functions let's also convert them to be
the y2038 safe versions. This means there is a *64 function that is
called by a backwards compatible wrapper.
---
 include/sys/resource.h                | 10 +++++
 sysdeps/unix/sysv/linux/getrusage.c   | 58 +++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/tv32-compat.h | 47 ++++++++++++++++++++++
 sysdeps/unix/sysv/linux/wait4.c       | 49 +++++++++++++++++++++-
 4 files changed, 162 insertions(+), 2 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/getrusage.c

diff --git a/include/sys/resource.h b/include/sys/resource.h
index 9d604dfe3e..1a530fb62d 100644
--- a/include/sys/resource.h
+++ b/include/sys/resource.h
@@ -134,5 +134,15 @@ extern int __getrusage (enum __rusage_who __who, struct rusage *__usage)
 extern int __setrlimit (enum __rlimit_resource __resource,
 			const struct rlimit *__rlimits);
 libc_hidden_proto (__setrlimit);
+
+#if __TIMESIZE == 64
+# define __getrusage64 __getrusage
+# define __wait4_time64 __wait4
+#else
+extern int __getrusage64 (enum __rusage_who who, struct __rusage64 *usage);
+libc_hidden_proto (__getrusage64)
+pid_t __wait4_time64 (pid_t pid, int *stat_loc, int options, struct __rusage64 *usage);
+libc_hidden_proto (__wait4_time64)
+#endif
 #endif
 #endif
diff --git a/sysdeps/unix/sysv/linux/getrusage.c b/sysdeps/unix/sysv/linux/getrusage.c
new file mode 100644
index 0000000000..a4e382ed53
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/getrusage.c
@@ -0,0 +1,58 @@
+/* getrusage -- get the rusage struct.  Linux version.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sysdep.h>
+#include <tv32-compat.h>
+
+int
+__getrusage64 (enum __rusage_who who, struct __rusage64 *usage)
+{
+#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
+  return INLINE_SYSCALL_CALL (getrusage, who, usage);
+#else
+  struct __rusage32 usage32;
+  if (INLINE_SYSCALL_CALL (getrusage, who, &usage32) == -1)
+    return -1;
+
+  rusage32_to_rusage64 (&usage32, usage);
+  return 0;
+#endif
+}
+
+#if __TIMESIZE != 64
+libc_hidden_def (__getrusage64)
+int
+__getrusage (enum __rusage_who who, struct rusage *usage)
+{
+  int ret ;
+  struct __rusage64 usage64;
+
+  ret = __getrusage64 (who, &usage64);
+
+  if (ret != 0)
+    return ret;
+
+  rusage64_to_rusage (&usage64, usage);
+
+  return ret;
+}
+#endif
+weak_alias (__getrusage, getrusage)
diff --git a/sysdeps/unix/sysv/linux/tv32-compat.h b/sysdeps/unix/sysv/linux/tv32-compat.h
index 4eb6f216ea..c2231f042f 100644
--- a/sysdeps/unix/sysv/linux/tv32-compat.h
+++ b/sysdeps/unix/sysv/linux/tv32-compat.h
@@ -24,6 +24,7 @@
 #include <bits/types.h>
 #include <bits/types/time_t.h>
 #include <bits/types/struct_timeval.h>
+#include <sys/resource.h>
 
 /* Structures containing 'struct timeval' with 32-bit time_t.  */
 struct __itimerval32
@@ -32,4 +33,50 @@ struct __itimerval32
   struct __timeval32 it_value;
 };
 
+struct __rusage32
+{
+  struct __timeval32 ru_utime;	/* user time used */
+  struct __timeval32 ru_stime;	/* system time used */
+  long ru_maxrss;		/* maximum resident set size */
+  long ru_ixrss;		/* integral shared memory size */
+  long ru_idrss;		/* integral unshared data size */
+  long ru_isrss;		/* integral unshared stack size */
+  long ru_minflt;		/* page reclaims */
+  long ru_majflt;		/* page faults */
+  long ru_nswap;		/* swaps */
+  long ru_inblock;		/* block input operations */
+  long ru_oublock;		/* block output operations */
+  long ru_msgsnd;		/* messages sent */
+  long ru_msgrcv;		/* messages received */
+  long ru_nsignals;		/* signals received */
+  long ru_nvcsw;		/* voluntary context switches */
+  long ru_nivcsw;		/* involuntary " */
+};
+
+static inline void
+rusage32_to_rusage64 (const struct __rusage32 *restrict r32,
+                    struct __rusage64 *restrict r64)
+{
+  /* Make sure the entire output structure is cleared, including
+     padding and reserved fields.  */
+  memset (r64, 0, sizeof *r64);
+
+  r64->ru_utime    = valid_timeval32_to_timeval64 (r32->ru_utime);
+  r64->ru_stime    = valid_timeval32_to_timeval64 (r32->ru_stime);
+  r64->ru_maxrss   = r32->ru_maxrss;
+  r64->ru_ixrss    = r32->ru_ixrss;
+  r64->ru_idrss    = r32->ru_idrss;
+  r64->ru_isrss    = r32->ru_isrss;
+  r64->ru_minflt   = r32->ru_minflt;
+  r64->ru_majflt   = r32->ru_majflt;
+  r64->ru_nswap    = r32->ru_nswap;
+  r64->ru_inblock  = r32->ru_inblock;
+  r64->ru_oublock  = r32->ru_oublock;
+  r64->ru_msgsnd   = r32->ru_msgsnd;
+  r64->ru_msgrcv   = r32->ru_msgrcv;
+  r64->ru_nsignals = r32->ru_nsignals;
+  r64->ru_nvcsw    = r32->ru_nvcsw;
+  r64->ru_nivcsw   = r32->ru_nivcsw;
+}
+
 #endif /* tv32-compat.h */
diff --git a/sysdeps/unix/sysv/linux/wait4.c b/sysdeps/unix/sysv/linux/wait4.c
index 3a8bed1169..f4df1c3b99 100644
--- a/sysdeps/unix/sysv/linux/wait4.c
+++ b/sysdeps/unix/sysv/linux/wait4.c
@@ -18,14 +18,30 @@
 
 #include <sys/wait.h>
 #include <sys/resource.h>
+#include <sys/types.h>
 #include <sysdep-cancel.h>
+#include <tv32-compat.h>
 
 pid_t
-__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
+__wait4_time64 (pid_t pid, int *stat_loc, int options, struct __rusage64 *usage)
 {
 #ifdef __NR_wait4
+# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
   return SYSCALL_CANCEL (wait4, pid, stat_loc, options, usage);
+# else
+  struct __rusage32 usage32;
+  pid_t ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options, &usage32);
+
+  if (ret != 0)
+    return ret;
+
+  if (usage != NULL)
+      rusage32_to_rusage64 (&usage32, usage);
+
+  return ret;
+# endif
 #elif defined (__ASSUME_WAITID_PID0_P_PGID)
+  struct __rusage32 usage32;
   idtype_t idtype = P_PID;
 
   if (pid < -1)
@@ -41,7 +57,12 @@ __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
   options |= WEXITED;
 
   siginfo_t infop;
+
+# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
   if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, usage) < 0)
+# else
+  if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, &usage32) < 0)
+# endif
     return -1;
 
   if (stat_loc)
@@ -70,8 +91,13 @@ __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
         }
     }
 
+# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 == 0
+  if (usage != NULL)
+      rusage32_to_rusage64 (&usage32, usage);
+# endif
+
   return infop.si_pid;
-# else
+#else
 /* Linux waitid prior kernel 5.4 does not support waiting for the current
    process.  It is possible to emulate wait4 it by calling getpgid for
    PID 0, however, it would require an additional syscall and it is inherent
@@ -81,5 +107,24 @@ __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
 # error "The kernel ABI does not provide a way to implement wait4"
 #endif
 }
+libc_hidden_def (__wait4_time64)
+
+#if __TIMESIZE != 64
+pid_t
+__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
+{
+  pid_t ret ;
+  struct __rusage64 usage64;
+
+  ret = __wait4_time64 (pid, stat_loc, options, &usage64);
+
+  if (ret != 0)
+    return ret;
+
+  rusage64_to_rusage (&usage64, usage);
+
+  return ret;
+}
 libc_hidden_def (__wait4);
+#endif
 weak_alias (__wait4, wait4)
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 8/8] sysv/alpha: Use generic __timeval32 and helpers
  2020-02-14 16:31 [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls Alistair Francis
                   ` (6 preceding siblings ...)
  2020-02-14 16:31 ` [PATCH v3 7/8] linux: Use long time_t for wait4/getrusage Alistair Francis
@ 2020-02-14 16:31 ` Alistair Francis
  7 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-02-14 16:31 UTC (permalink / raw)
  To: libc-alpha; +Cc: alistair23, Alistair Francis

Now there is a generic __timeval32 and helpers we can use them for Alpha
instead of the Alpha specific ones.
---
 .../unix/sysv/linux/alpha/alpha-tv32-compat.h | 124 ------------------
 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c   |  15 ++-
 sysdeps/unix/sysv/linux/alpha/osf_getitimer.c |   9 +-
 sysdeps/unix/sysv/linux/alpha/osf_getrusage.c |  10 +-
 .../unix/sysv/linux/alpha/osf_gettimeofday.c  |   6 +-
 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c |  15 ++-
 .../unix/sysv/linux/alpha/osf_settimeofday.c  |   6 +-
 sysdeps/unix/sysv/linux/alpha/osf_utimes.c    |   8 +-
 sysdeps/unix/sysv/linux/alpha/osf_wait4.c     |  10 +-
 sysdeps/unix/sysv/linux/tv32-compat.h         |  26 ++++
 10 files changed, 67 insertions(+), 162 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h

diff --git a/sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h b/sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h
deleted file mode 100644
index 3073005c65..0000000000
--- a/sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Compatibility definitions for `struct timeval' with 32-bit time_t.
-   Copyright (C) 2019-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _TV32_COMPAT_H
-#define _TV32_COMPAT_H 1
-
-#include <features.h>
-
-#include <bits/types.h>
-#include <bits/types/time_t.h>
-#include <bits/types/struct_timeval.h>
-#include <bits/types/struct_timespec.h>
-#include <bits/types/struct_rusage.h>
-
-#include <stdint.h> // for INT32_MAX
-#include <string.h> // for memset
-
-#define TV_USEC_MAX 999999 // 10**6 - 1
-
-/* A version of 'struct timeval' with 32-bit time_t.  */
-struct timeval32
-{
-  int32_t tv_sec;
-  int32_t tv_usec;
-};
-
-/* Structures containing 'struct timeval' with 32-bit time_t.  */
-struct itimerval32
-{
-  struct timeval32 it_interval;
-  struct timeval32 it_value;
-};
-
-struct rusage32
-{
-  struct timeval32 ru_utime;	/* user time used */
-  struct timeval32 ru_stime;	/* system time used */
-  long ru_maxrss;		/* maximum resident set size */
-  long ru_ixrss;		/* integral shared memory size */
-  long ru_idrss;		/* integral unshared data size */
-  long ru_isrss;		/* integral unshared stack size */
-  long ru_minflt;		/* page reclaims */
-  long ru_majflt;		/* page faults */
-  long ru_nswap;		/* swaps */
-  long ru_inblock;		/* block input operations */
-  long ru_oublock;		/* block output operations */
-  long ru_msgsnd;		/* messages sent */
-  long ru_msgrcv;		/* messages received */
-  long ru_nsignals;		/* signals received */
-  long ru_nvcsw;		/* voluntary context switches */
-  long ru_nivcsw;		/* involuntary " */
-};
-
-/* Conversion functions.  If the seconds field of a timeval32 would
-   overflow, they write { INT32_MAX, TV_USEC_MAX } to the output.  */
-
-static inline struct timeval
-alpha_valid_timeval32_to_timeval (const struct timeval32 tv)
-{
-  return (struct timeval) { tv.tv_sec, tv.tv_usec };
-}
-
-static inline struct timeval32
-alpha_valid_timeval_to_timeval32 (const struct timeval tv64)
-{
-  if (__glibc_unlikely (tv64.tv_sec > (time_t) INT32_MAX))
-    return (struct timeval32) { INT32_MAX, TV_USEC_MAX};
-  return (struct timeval32) { tv64.tv_sec, tv64.tv_usec };
-}
-
-static inline struct timespec
-alpha_valid_timeval32_to_timespec (const struct timeval32 tv)
-{
-  return (struct timespec) { tv.tv_sec, tv.tv_usec * 1000 };
-}
-
-static inline struct timeval32
-alpha_valid_timespec_to_timeval32 (const struct timespec ts)
-{
-  return (struct timeval32) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
-}
-
-static inline void
-alpha_rusage64_to_rusage32 (struct rusage32 *restrict r32,
-                      const struct rusage *restrict r64)
-{
-  /* Make sure the entire output structure is cleared, including
-     padding and reserved fields.  */
-  memset (r32, 0, sizeof *r32);
-
-  r32->ru_utime    = alpha_valid_timeval_to_timeval32 (r64->ru_utime);
-  r32->ru_stime    = alpha_valid_timeval_to_timeval32 (r64->ru_stime);
-  r32->ru_maxrss   = r64->ru_maxrss;
-  r32->ru_ixrss    = r64->ru_ixrss;
-  r32->ru_idrss    = r64->ru_idrss;
-  r32->ru_isrss    = r64->ru_isrss;
-  r32->ru_minflt   = r64->ru_minflt;
-  r32->ru_majflt   = r64->ru_majflt;
-  r32->ru_nswap    = r64->ru_nswap;
-  r32->ru_inblock  = r64->ru_inblock;
-  r32->ru_oublock  = r64->ru_oublock;
-  r32->ru_msgsnd   = r64->ru_msgsnd;
-  r32->ru_msgrcv   = r64->ru_msgrcv;
-  r32->ru_nsignals = r64->ru_nsignals;
-  r32->ru_nvcsw    = r64->ru_nvcsw;
-  r32->ru_nivcsw   = r64->ru_nivcsw;
-}
-
-#endif /* alpha-tv32-compat.h */
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
index f0a1123639..95d646452e 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
@@ -20,9 +20,10 @@
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
+#include <time.h>
 #include <sys/time.h>
 #include <sys/timex.h>
-#include <alpha-tv32-compat.h>
+#include <string.h>
 
 struct timex32 {
 	unsigned int modes;	/* mode selector */
@@ -36,7 +37,7 @@ struct timex32 {
 	long tolerance;		/* clock frequency tolerance (ppm)
 				 * (read only)
 				 */
-	struct timeval32 time;	/* (read only) */
+	struct __timeval32 time;	/* (read only) */
 	long tick;		/* (modified) usecs between clock ticks */
 
 	long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
@@ -55,15 +56,15 @@ struct timex32 {
 
 int
 attribute_compat_text_section
-__adjtime_tv32 (const struct timeval32 *itv, struct timeval32 *otv)
+__adjtime_tv32 (const struct __timeval32 *itv, struct __timeval32 *otv)
 {
-  struct timeval itv64 = alpha_valid_timeval32_to_timeval (*itv);
+  struct timeval itv64 = valid_timeval32_to_timeval (*itv);
   struct timeval otv64;
 
   if (__adjtime (&itv64, &otv64) == -1)
     return -1;
 
-  *otv = alpha_valid_timeval_to_timeval32 (otv64);
+  *otv = valid_timeval_to_timeval32 (otv64);
   return 0;
 }
 
@@ -91,7 +92,7 @@ __adjtimex_tv32 (struct timex32 *tx)
   tx64.calcnt    = tx->calcnt;
   tx64.errcnt    = tx->errcnt;
   tx64.stbcnt    = tx->stbcnt;
-  tx64.time      = alpha_valid_timeval32_to_timeval (tx->time);
+  tx64.time      = valid_timeval32_to_timeval (tx->time);
 
   int status = __adjtimex (&tx64);
   if (status < 0)
@@ -116,7 +117,7 @@ __adjtimex_tv32 (struct timex32 *tx)
   tx->calcnt    = tx64.calcnt;
   tx->errcnt    = tx64.errcnt;
   tx->stbcnt    = tx64.stbcnt;
-  tx->time      = alpha_valid_timeval_to_timeval32 (tx64.time);
+  tx->time      = valid_timeval_to_timeval32 (tx64.time);
 
   return status;
 }
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
index 204d4ba796..4d25060e96 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
@@ -20,12 +20,13 @@
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
+#include <time.h>
 #include <sys/time.h>
-#include <alpha-tv32-compat.h>
+#include <tv32-compat.h>
 
 int
 attribute_compat_text_section
-__getitimer_tv32 (int which, struct itimerval32 *curr_value)
+__getitimer_tv32 (int which, struct __itimerval32 *curr_value)
 {
   struct itimerval curr_value_64;
   if (__getitimer (which, &curr_value_64) == -1)
@@ -33,9 +34,9 @@ __getitimer_tv32 (int which, struct itimerval32 *curr_value)
 
   /* Write all fields of 'curr_value' regardless of overflow.  */
   curr_value->it_interval
-    = alpha_valid_timeval_to_timeval32 (curr_value_64.it_interval);
+    = valid_timeval_to_timeval32 (curr_value_64.it_interval);
   curr_value->it_value
-    = alpha_valid_timeval_to_timeval32 (curr_value_64.it_value);
+    = valid_timeval_to_timeval32 (curr_value_64.it_value);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
index be81994654..95cedb0cf6 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
@@ -22,16 +22,16 @@
 
 #include <sys/time.h>
 #include <sys/resource.h>
-#include <alpha-tv32-compat.h>
+#include <tv32-compat.h>
 
 int
-__getrusage_tv32 (int who, struct rusage32 *usage32)
+__getrusage_tv32 (int who, struct __rusage32 *usage32)
 {
-  struct rusage usage64;
-  if (__getrusage (who, &usage64) == -1)
+  struct rusage usage;
+  if (__getrusage (who, &usage) == -1)
     return -1;
 
-  alpha_rusage64_to_rusage32 (usage32, &usage64);
+  rusage64_to_rusage32 (&usage, usage32);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
index 9ffda2fde3..8cf5d303f9 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
@@ -20,17 +20,17 @@
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
+#include <time.h>
 #include <string.h>
 #include <time.h>
 #include <sys/time.h>
-#include <alpha-tv32-compat.h>
 
 /* Get the current time of day and timezone information putting it
    into *TV and *TZ.  */
 
 int
 attribute_compat_text_section
-__gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict tz)
+__gettimeofday_tv32 (struct __timeval32 *restrict tv32, void *restrict tz)
 {
   if (__glibc_unlikely (tz != 0))
     memset (tz, 0, sizeof (struct timezone));
@@ -38,7 +38,7 @@ __gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict tz)
   struct timespec ts;
   __clock_gettime (CLOCK_REALTIME, &ts);
 
-  *tv32 = alpha_valid_timespec_to_timeval32 (ts);
+  *tv32 = valid_timespec_to_timeval32 (ts);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
index 726dfc8b0e..842ab5f64e 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
@@ -20,19 +20,20 @@
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
+#include <time.h>
 #include <sys/time.h>
-#include <alpha-tv32-compat.h>
+#include <tv32-compat.h>
 
 int
 attribute_compat_text_section
-__setitimer_tv32 (int which, const struct itimerval32 *restrict new_value,
-		  struct itimerval32 *restrict old_value)
+__setitimer_tv32 (int which, const struct __itimerval32 *restrict new_value,
+		  struct __itimerval32 *restrict old_value)
 {
   struct itimerval new_value_64;
   new_value_64.it_interval
-    = alpha_valid_timeval32_to_timeval (new_value->it_interval);
+    = valid_timeval32_to_timeval (new_value->it_interval);
   new_value_64.it_value
-    = alpha_valid_timeval32_to_timeval (new_value->it_value);
+    = valid_timeval32_to_timeval (new_value->it_value);
 
   if (old_value == NULL)
     return __setitimer (which, &new_value_64, NULL);
@@ -43,9 +44,9 @@ __setitimer_tv32 (int which, const struct itimerval32 *restrict new_value,
 
   /* Write all fields of 'old_value' regardless of overflow.  */
   old_value->it_interval
-     = alpha_valid_timeval_to_timeval32 (old_value_64.it_interval);
+     = valid_timeval_to_timeval32 (old_value_64.it_interval);
   old_value->it_value
-     = alpha_valid_timeval_to_timeval32 (old_value_64.it_value);
+     = valid_timeval_to_timeval32 (old_value_64.it_value);
   return 0;
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
index 044363e079..5ea0a5afb7 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -20,16 +20,16 @@
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
+#include <time.h>
 #include <sys/time.h>
 #include <time.h>
 #include <errno.h>
-#include <alpha-tv32-compat.h>
 
 /* Set the current time of day and timezone information.
    This call is restricted to the super-user.  */
 int
 attribute_compat_text_section
-__settimeofday_tv32 (const struct timeval32 *tv32,
+__settimeofday_tv32 (const struct __timeval32 *tv32,
                      const struct timezone *tz)
 {
   if (__glibc_unlikely (tz != 0))
@@ -42,7 +42,7 @@ __settimeofday_tv32 (const struct timeval32 *tv32,
       return __settimezone (tz);
     }
 
-  struct timespec ts = alpha_valid_timeval32_to_timespec (*tv32);
+  struct timespec ts = valid_timeval32_to_timespec (*tv32);
   return __clock_settime (CLOCK_REALTIME, &ts);
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_utimes.c b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
index 8ad9fb567c..8afbf12185 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
@@ -20,16 +20,16 @@
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
 
+#include <time.h>
 #include <sys/time.h>
-#include <alpha-tv32-compat.h>
 
 int
 attribute_compat_text_section
-__utimes_tv32 (const char *filename, const struct timeval32 times32[2])
+__utimes_tv32 (const char *filename, const struct __timeval32 times32[2])
 {
   struct timeval times[2];
-  times[0] = alpha_valid_timeval32_to_timeval (times32[0]);
-  times[1] = alpha_valid_timeval32_to_timeval (times32[1]);
+  times[0] = valid_timeval32_to_timeval (times32[0]);
+  times[1] = valid_timeval32_to_timeval (times32[1]);
   return __utimes (filename, times);
 }
 
diff --git a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
index c664e8e93f..4242d5227f 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
@@ -23,17 +23,17 @@
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/wait.h>
-#include <alpha-tv32-compat.h>
+#include <tv32-compat.h>
 
 pid_t
 attribute_compat_text_section
-__wait4_tv32 (pid_t pid, int *status, int options, struct rusage32 *usage32)
+__wait4_tv32 (pid_t pid, int *status, int options, struct __rusage32 *usage32)
 {
-  struct rusage usage64;
-  pid_t child = __wait4 (pid, status, options, &usage64);
+  struct rusage usage;
+  pid_t child = __wait4 (pid, status, options, &usage);
 
   if (child >= 0 && usage32 != NULL)
-    alpha_rusage64_to_rusage32 (usage32, &usage64);
+    rusage64_to_rusage32 (&usage, usage32);
   return child;
 }
 
diff --git a/sysdeps/unix/sysv/linux/tv32-compat.h b/sysdeps/unix/sysv/linux/tv32-compat.h
index c2231f042f..244a2005c6 100644
--- a/sysdeps/unix/sysv/linux/tv32-compat.h
+++ b/sysdeps/unix/sysv/linux/tv32-compat.h
@@ -79,4 +79,30 @@ rusage32_to_rusage64 (const struct __rusage32 *restrict r32,
   r64->ru_nivcsw   = r32->ru_nivcsw;
 }
 
+static inline void
+rusage64_to_rusage32 (const struct __rusage64 *restrict r64,
+                    struct __rusage32 *restrict r32)
+{
+  /* Make sure the entire output structure is cleared, including
+     padding and reserved fields.  */
+  memset (r32, 0, sizeof *r32);
+
+  r32->ru_utime    = valid_timeval64_to_timeval32 (r64->ru_utime);
+  r32->ru_stime    = valid_timeval64_to_timeval32 (r64->ru_stime);
+  r32->ru_maxrss   = r64->ru_maxrss;
+  r32->ru_ixrss    = r64->ru_ixrss;
+  r32->ru_idrss    = r64->ru_idrss;
+  r32->ru_isrss    = r64->ru_isrss;
+  r32->ru_minflt   = r64->ru_minflt;
+  r32->ru_majflt   = r64->ru_majflt;
+  r32->ru_nswap    = r64->ru_nswap;
+  r32->ru_inblock  = r64->ru_inblock;
+  r32->ru_oublock  = r64->ru_oublock;
+  r32->ru_msgsnd   = r64->ru_msgsnd;
+  r32->ru_msgrcv   = r64->ru_msgrcv;
+  r32->ru_nsignals = r64->ru_nsignals;
+  r32->ru_nvcsw    = r64->ru_nvcsw;
+  r32->ru_nivcsw   = r64->ru_nivcsw;
+}
+
 #endif /* tv32-compat.h */
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 1/8] sysv/linux: Rename alpha functions to be alpha specific
  2020-02-14 16:31 ` [PATCH v3 1/8] sysv/linux: Rename alpha functions to be alpha specific Alistair Francis
@ 2020-02-15 13:54   ` Lukasz Majewski
  0 siblings, 0 replies; 17+ messages in thread
From: Lukasz Majewski @ 2020-02-15 13:54 UTC (permalink / raw)
  To: Alistair Francis; +Cc: libc-alpha, alistair23

[-- Attachment #1: Type: text/plain, Size: 12177 bytes --]

Hi Alistair,

> These functions are alpha specifc, rename them to be clear.
> 
> Let's also rename the header file from tv32-compat.h to
> alpha-tv32-compat.h. This is to avoid conflicts with the one we will
> introduce later.

Reviewed-by: Lukasz Majewski <lukma@denx.de>

> ---
>  .../alpha/{tv32-compat.h => alpha-tv32-compat.h} | 16
> ++++++++-------- sysdeps/unix/sysv/linux/alpha/osf_adjtime.c      |
> 10 +++++----- sysdeps/unix/sysv/linux/alpha/osf_getitimer.c    |  6
> +++--- sysdeps/unix/sysv/linux/alpha/osf_getrusage.c    |  4 ++--
>  sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c |  4 ++--
>  sysdeps/unix/sysv/linux/alpha/osf_setitimer.c    | 10 +++++-----
>  sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c |  4 ++--
>  sysdeps/unix/sysv/linux/alpha/osf_utimes.c       |  6 +++---
>  sysdeps/unix/sysv/linux/alpha/osf_wait4.c        |  4 ++--
>  9 files changed, 32 insertions(+), 32 deletions(-)
>  rename sysdeps/unix/sysv/linux/alpha/{tv32-compat.h =>
> alpha-tv32-compat.h} (88%)
> 
> diff --git a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
> b/sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h similarity index
> 88% rename from sysdeps/unix/sysv/linux/alpha/tv32-compat.h
> rename to sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h
> index 8e34ed1c1b..3073005c65 100644
> --- a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h
> +++ b/sysdeps/unix/sysv/linux/alpha/alpha-tv32-compat.h
> @@ -70,13 +70,13 @@ struct rusage32
>     overflow, they write { INT32_MAX, TV_USEC_MAX } to the output.  */
>  
>  static inline struct timeval
> -valid_timeval32_to_timeval (const struct timeval32 tv)
> +alpha_valid_timeval32_to_timeval (const struct timeval32 tv)
>  {
>    return (struct timeval) { tv.tv_sec, tv.tv_usec };
>  }
>  
>  static inline struct timeval32
> -valid_timeval_to_timeval32 (const struct timeval tv64)
> +alpha_valid_timeval_to_timeval32 (const struct timeval tv64)
>  {
>    if (__glibc_unlikely (tv64.tv_sec > (time_t) INT32_MAX))
>      return (struct timeval32) { INT32_MAX, TV_USEC_MAX};
> @@ -84,27 +84,27 @@ valid_timeval_to_timeval32 (const struct timeval
> tv64) }
>  
>  static inline struct timespec
> -valid_timeval32_to_timespec (const struct timeval32 tv)
> +alpha_valid_timeval32_to_timespec (const struct timeval32 tv)
>  {
>    return (struct timespec) { tv.tv_sec, tv.tv_usec * 1000 };
>  }
>  
>  static inline struct timeval32
> -valid_timespec_to_timeval32 (const struct timespec ts)
> +alpha_valid_timespec_to_timeval32 (const struct timespec ts)
>  {
>    return (struct timeval32) { (time_t) ts.tv_sec, ts.tv_nsec / 1000
> }; }
>  
>  static inline void
> -rusage64_to_rusage32 (struct rusage32 *restrict r32,
> +alpha_rusage64_to_rusage32 (struct rusage32 *restrict r32,
>                        const struct rusage *restrict r64)
>  {
>    /* Make sure the entire output structure is cleared, including
>       padding and reserved fields.  */
>    memset (r32, 0, sizeof *r32);
>  
> -  r32->ru_utime    = valid_timeval_to_timeval32 (r64->ru_utime);
> -  r32->ru_stime    = valid_timeval_to_timeval32 (r64->ru_stime);
> +  r32->ru_utime    = alpha_valid_timeval_to_timeval32
> (r64->ru_utime);
> +  r32->ru_stime    = alpha_valid_timeval_to_timeval32
> (r64->ru_stime); r32->ru_maxrss   = r64->ru_maxrss;
>    r32->ru_ixrss    = r64->ru_ixrss;
>    r32->ru_idrss    = r64->ru_idrss;
> @@ -121,4 +121,4 @@ rusage64_to_rusage32 (struct rusage32 *restrict
> r32, r32->ru_nivcsw   = r64->ru_nivcsw;
>  }
>  
> -#endif /* tv32-compat.h */
> +#endif /* alpha-tv32-compat.h */
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c
> b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c index
> 9825a4734d..f0a1123639 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c @@ -22,7 +22,7 @@
>  
>  #include <sys/time.h>
>  #include <sys/timex.h>
> -#include <tv32-compat.h>
> +#include <alpha-tv32-compat.h>
>  
>  struct timex32 {
>  	unsigned int modes;	/* mode selector */
> @@ -57,13 +57,13 @@ int
>  attribute_compat_text_section
>  __adjtime_tv32 (const struct timeval32 *itv, struct timeval32 *otv)
>  {
> -  struct timeval itv64 = valid_timeval32_to_timeval (*itv);
> +  struct timeval itv64 = alpha_valid_timeval32_to_timeval (*itv);
>    struct timeval otv64;
>  
>    if (__adjtime (&itv64, &otv64) == -1)
>      return -1;
>  
> -  *otv = valid_timeval_to_timeval32 (otv64);
> +  *otv = alpha_valid_timeval_to_timeval32 (otv64);
>    return 0;
>  }
>  
> @@ -91,7 +91,7 @@ __adjtimex_tv32 (struct timex32 *tx)
>    tx64.calcnt    = tx->calcnt;
>    tx64.errcnt    = tx->errcnt;
>    tx64.stbcnt    = tx->stbcnt;
> -  tx64.time      = valid_timeval32_to_timeval (tx->time);
> +  tx64.time      = alpha_valid_timeval32_to_timeval (tx->time);
>  
>    int status = __adjtimex (&tx64);
>    if (status < 0)
> @@ -116,7 +116,7 @@ __adjtimex_tv32 (struct timex32 *tx)
>    tx->calcnt    = tx64.calcnt;
>    tx->errcnt    = tx64.errcnt;
>    tx->stbcnt    = tx64.stbcnt;
> -  tx->time      = valid_timeval_to_timeval32 (tx64.time);
> +  tx->time      = alpha_valid_timeval_to_timeval32 (tx64.time);
>  
>    return status;
>  }
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c
> b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c index
> e9de2b287b..204d4ba796 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c @@ -21,7 +21,7 @@
>  #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
>  
>  #include <sys/time.h>
> -#include <tv32-compat.h>
> +#include <alpha-tv32-compat.h>
>  
>  int
>  attribute_compat_text_section
> @@ -33,9 +33,9 @@ __getitimer_tv32 (int which, struct itimerval32
> *curr_value) 
>    /* Write all fields of 'curr_value' regardless of overflow.  */
>    curr_value->it_interval
> -    = valid_timeval_to_timeval32 (curr_value_64.it_interval);
> +    = alpha_valid_timeval_to_timeval32 (curr_value_64.it_interval);
>    curr_value->it_value
> -    = valid_timeval_to_timeval32 (curr_value_64.it_value);
> +    = alpha_valid_timeval_to_timeval32 (curr_value_64.it_value);
>    return 0;
>  }
>  
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c
> b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c index
> 74c6fb49aa..be81994654 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c @@ -22,7 +22,7 @@
>  
>  #include <sys/time.h>
>  #include <sys/resource.h>
> -#include <tv32-compat.h>
> +#include <alpha-tv32-compat.h>
>  
>  int
>  __getrusage_tv32 (int who, struct rusage32 *usage32)
> @@ -31,7 +31,7 @@ __getrusage_tv32 (int who, struct rusage32 *usage32)
>    if (__getrusage (who, &usage64) == -1)
>      return -1;
>  
> -  rusage64_to_rusage32 (usage32, &usage64);
> +  alpha_rusage64_to_rusage32 (usage32, &usage64);
>    return 0;
>  }
>  
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c
> b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c index
> df7f06765b..9ffda2fde3 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c @@ -23,7 +23,7 @@
>  #include <string.h>
>  #include <time.h>
>  #include <sys/time.h>
> -#include <tv32-compat.h>
> +#include <alpha-tv32-compat.h>
>  
>  /* Get the current time of day and timezone information putting it
>     into *TV and *TZ.  */
> @@ -38,7 +38,7 @@ __gettimeofday_tv32 (struct timeval32 *restrict
> tv32, void *restrict tz) struct timespec ts;
>    __clock_gettime (CLOCK_REALTIME, &ts);
>  
> -  *tv32 = valid_timespec_to_timeval32 (ts);
> +  *tv32 = alpha_valid_timespec_to_timeval32 (ts);
>    return 0;
>  }
>  
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c
> b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c index
> 7df2d1b71c..726dfc8b0e 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c @@ -21,7 +21,7 @@
>  #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
>  
>  #include <sys/time.h>
> -#include <tv32-compat.h>
> +#include <alpha-tv32-compat.h>
>  
>  int
>  attribute_compat_text_section
> @@ -30,9 +30,9 @@ __setitimer_tv32 (int which, const struct
> itimerval32 *restrict new_value, {
>    struct itimerval new_value_64;
>    new_value_64.it_interval
> -    = valid_timeval32_to_timeval (new_value->it_interval);
> +    = alpha_valid_timeval32_to_timeval (new_value->it_interval);
>    new_value_64.it_value
> -    = valid_timeval32_to_timeval (new_value->it_value);
> +    = alpha_valid_timeval32_to_timeval (new_value->it_value);
>  
>    if (old_value == NULL)
>      return __setitimer (which, &new_value_64, NULL);
> @@ -43,9 +43,9 @@ __setitimer_tv32 (int which, const struct
> itimerval32 *restrict new_value, 
>    /* Write all fields of 'old_value' regardless of overflow.  */
>    old_value->it_interval
> -     = valid_timeval_to_timeval32 (old_value_64.it_interval);
> +     = alpha_valid_timeval_to_timeval32 (old_value_64.it_interval);
>    old_value->it_value
> -     = valid_timeval_to_timeval32 (old_value_64.it_value);
> +     = alpha_valid_timeval_to_timeval32 (old_value_64.it_value);
>    return 0;
>  }
>  
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
> b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c index
> 6e17a95a47..044363e079 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c @@ -23,7 +23,7 @@
>  #include <sys/time.h>
>  #include <time.h>
>  #include <errno.h>
> -#include <tv32-compat.h>
> +#include <alpha-tv32-compat.h>
>  
>  /* Set the current time of day and timezone information.
>     This call is restricted to the super-user.  */
> @@ -42,7 +42,7 @@ __settimeofday_tv32 (const struct timeval32 *tv32,
>        return __settimezone (tz);
>      }
>  
> -  struct timespec ts = valid_timeval32_to_timespec (*tv32);
> +  struct timespec ts = alpha_valid_timeval32_to_timespec (*tv32);
>    return __clock_settime (CLOCK_REALTIME, &ts);
>  }
>  
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_utimes.c
> b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c index
> 6c3fad0132..8ad9fb567c 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_utimes.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c @@ -21,15 +21,15 @@
>  #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
>  
>  #include <sys/time.h>
> -#include <tv32-compat.h>
> +#include <alpha-tv32-compat.h>
>  
>  int
>  attribute_compat_text_section
>  __utimes_tv32 (const char *filename, const struct timeval32
> times32[2]) {
>    struct timeval times[2];
> -  times[0] = valid_timeval32_to_timeval (times32[0]);
> -  times[1] = valid_timeval32_to_timeval (times32[1]);
> +  times[0] = alpha_valid_timeval32_to_timeval (times32[0]);
> +  times[1] = alpha_valid_timeval32_to_timeval (times32[1]);
>    return __utimes (filename, times);
>  }
>  
> diff --git a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c
> b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c index
> 6af8347871..c664e8e93f 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c +++
> b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c @@ -23,7 +23,7 @@
>  #include <sys/time.h>
>  #include <sys/resource.h>
>  #include <sys/wait.h>
> -#include <tv32-compat.h>
> +#include <alpha-tv32-compat.h>
>  
>  pid_t
>  attribute_compat_text_section
> @@ -33,7 +33,7 @@ __wait4_tv32 (pid_t pid, int *status, int options,
> struct rusage32 *usage32) pid_t child = __wait4 (pid, status,
> options, &usage64); 
>    if (child >= 0 && usage32 != NULL)
> -    rusage64_to_rusage32 (usage32, &usage64);
> +    alpha_rusage64_to_rusage32 (usage32, &usage64);
>    return child;
>  }
>  




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 2/8] time: Add a timeval with a 32-bit tv_sec and tv_usec
  2020-02-14 16:31 ` [PATCH v3 2/8] time: Add a timeval with a 32-bit tv_sec and tv_usec Alistair Francis
@ 2020-02-15 13:57   ` Lukasz Majewski
  0 siblings, 0 replies; 17+ messages in thread
From: Lukasz Majewski @ 2020-02-15 13:57 UTC (permalink / raw)
  To: Alistair Francis; +Cc: libc-alpha, alistair23

[-- Attachment #1: Type: text/plain, Size: 2472 bytes --]

On Fri, 14 Feb 2020 08:31:28 -0800
Alistair Francis <alistair.francis@wdc.com> wrote:

> On y2038 safe 32-bit systems the Linux kernel expects itimerval to
> use a 32-bit time_t, even though the other time_t's are 64-bit. To
> address this let's add a __timeval32 struct to be used internally.

Reviewed-by: Lukasz Majewski <lukma@denx.de>

> ---
>  include/time.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/include/time.h b/include/time.h
> index 73f66277ac..ddc0ded640 100644
> --- a/include/time.h
> +++ b/include/time.h
> @@ -400,6 +400,51 @@ timespec64_to_timeval64 (const struct
> __timespec64 ts64) return tv64;
>  }
>  
> +/* A version of 'struct timeval' with 32-bit time_t
> +   and suseconds_t.  */
> +struct __timeval32
> +{
> +  __int32_t tv_sec;         /* Seconds.  */
> +  __int32_t tv_usec;        /* Microseconds.  */
> +};
> +
> +/* Conversion functions for converting to/from __timeval32  */
> +static inline struct __timeval64
> +valid_timeval32_to_timeval64 (const struct __timeval32 tv)
> +{
> +  return (struct __timeval64) { tv.tv_sec, tv.tv_usec };
> +}
> +
> +static inline struct __timeval32
> +valid_timeval64_to_timeval32 (const struct __timeval64 tv64)
> +{
> +  return (struct __timeval32) { tv64.tv_sec, tv64.tv_usec };
> +}
> +
> +static inline struct timeval
> +valid_timeval32_to_timeval (const struct __timeval32 tv)
> +{
> +  return (struct timeval) { tv.tv_sec, tv.tv_usec };
> +}
> +
> +static inline struct __timeval32
> +valid_timeval_to_timeval32 (const struct timeval tv)
> +{
> +  return (struct __timeval32) { tv.tv_sec, tv.tv_usec };
> +}
> +
> +static inline struct timespec
> +valid_timeval32_to_timespec (const struct __timeval32 tv)
> +{
> +  return (struct timespec) { tv.tv_sec, tv.tv_usec * 1000 };
> +}
> +
> +static inline struct __timeval32
> +valid_timespec_to_timeval32 (const struct timespec ts)
> +{
> +  return (struct __timeval32) { (time_t) ts.tv_sec, ts.tv_nsec /
> 1000 }; +}
> +
>  /* Check if a value is in the valid nanoseconds range. Return true if
>     it is, false otherwise.  */
>  static inline bool




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 4/8] sysv: Define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
  2020-02-14 16:31 ` [PATCH v3 4/8] sysv: Define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 Alistair Francis
@ 2020-02-15 14:03   ` Lukasz Majewski
  0 siblings, 0 replies; 17+ messages in thread
From: Lukasz Majewski @ 2020-02-15 14:03 UTC (permalink / raw)
  To: Alistair Francis; +Cc: libc-alpha, alistair23

[-- Attachment #1: Type: text/plain, Size: 5640 bytes --]

On Fri, 14 Feb 2020 08:31:30 -0800
Alistair Francis <alistair.francis@wdc.com> wrote:

> On y2038 safe 32-bit systems the Linux kernel expects itimerval
> and rusage to use a 32-bit time_t, even though the other time_t's
> are 64-bit.
> 
> There are also other occurances where the time passed to the kernel
> via timeval doesn't match the wordsize.
> 
> To handle these cases let's define a new macro
> __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64. This macro specifies if the
> kernel's old_timeval matches the new timeval64. This should be true
> for 64-bit architectures (expect for Alpha) and x32.

Reviewed-by: Lukasz Majewski <lukma@denx.de>

> ---
>  bits/typesizes.h                                 | 6 ++++++
>  sysdeps/unix/sysv/linux/alpha/bits/typesizes.h   | 3 +++
>  sysdeps/unix/sysv/linux/generic/bits/typesizes.h | 7 +++++++
>  sysdeps/unix/sysv/linux/s390/bits/typesizes.h    | 6 ++++++
>  sysdeps/unix/sysv/linux/sparc/bits/typesizes.h   | 6 ++++++
>  sysdeps/unix/sysv/linux/x86/bits/typesizes.h     | 3 +++
>  6 files changed, 31 insertions(+)
> 
> diff --git a/bits/typesizes.h b/bits/typesizes.h
> index 599408973e..8f16903a21 100644
> --- a/bits/typesizes.h
> +++ b/bits/typesizes.h
> @@ -76,10 +76,16 @@
>  
>  /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
>  # define __STATFS_MATCHES_STATFS64  1
> +
> +/* And for getitimer, setitimer and rusage  */
> +# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
>  #else
>  # define __RLIM_T_MATCHES_RLIM64_T	0
>  
>  # define __STATFS_MATCHES_STATFS64  0
> +
> +/* And for getitimer, setitimer and rusage  */
> +# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
>  #endif
>  
>  /* Number of descriptors that can fit in an `fd_set'.  */
> diff --git a/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h
> b/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h index
> 28ee3e5920..e5d7774468 100644 ---
> a/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h +++
> b/sysdeps/unix/sysv/linux/alpha/bits/typesizes.h @@ -73,6 +73,9 @@
>  /* Not for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
>  # define __STATFS_MATCHES_STATFS64  0
>  
> +/* And for getitimer, setitimer and rusage  */
> +#define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
> +
>  /* Number of descriptors that can fit in an `fd_set'.  */
>  #define	__FD_SETSIZE		1024
>  
> diff --git a/sysdeps/unix/sysv/linux/generic/bits/typesizes.h
> b/sysdeps/unix/sysv/linux/generic/bits/typesizes.h index
> 7c963e523e..48727c1da7 100644 ---
> a/sysdeps/unix/sysv/linux/generic/bits/typesizes.h +++
> b/sysdeps/unix/sysv/linux/generic/bits/typesizes.h @@ -77,11 +77,18 @@
>  
>  /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
>  # define __STATFS_MATCHES_STATFS64  1
> +
> +/* And for getitimer, setitimer and rusage  */
> +# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
>  #else
>  # define __RLIM_T_MATCHES_RLIM64_T	0
>  
>  # define __STATFS_MATCHES_STATFS64  0
> +
> +/* And for getitimer, setitimer and rusage  */
> +# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
>  #endif
> +
>  /* Number of descriptors that can fit in an `fd_set'.  */
>  #define	__FD_SETSIZE		1024
>  
> diff --git a/sysdeps/unix/sysv/linux/s390/bits/typesizes.h
> b/sysdeps/unix/sysv/linux/s390/bits/typesizes.h index
> e775e460bb..2bc87c1079 100644 ---
> a/sysdeps/unix/sysv/linux/s390/bits/typesizes.h +++
> b/sysdeps/unix/sysv/linux/s390/bits/typesizes.h @@ -82,10 +82,16 @@
>  
>  /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
>  # define __STATFS_MATCHES_STATFS64  1
> +
> +/* And for getitimer, setitimer and rusage  */
> +# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
>  #else
>  # define __RLIM_T_MATCHES_RLIM64_T	0
>  
>  # define __STATFS_MATCHES_STATFS64  0
> +
> +/* And for getitimer, setitimer and rusage  */
> +# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
>  #endif
>  
>  /* Number of descriptors that can fit in an `fd_set'.  */
> diff --git a/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h
> b/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h index
> ac48c23e37..288a902b5f 100644 ---
> a/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h +++
> b/sysdeps/unix/sysv/linux/sparc/bits/typesizes.h @@ -76,10 +76,16 @@
>  
>  /* And for fsblkcnt_t, fsblkcnt64_t, fsfilcnt_t and fsfilcnt64_t.  */
>  # define __STATFS_MATCHES_STATFS64  1
> +
> +/* And for getitimer, setitimer and rusage  */
> +# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
>  #else
>  # define __RLIM_T_MATCHES_RLIM64_T	0
>  
>  # define __STATFS_MATCHES_STATFS64  0
> +
> +/* And for getitimer, setitimer and rusage  */
> +# define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 0
>  #endif
>  
>  /* Number of descriptors that can fit in an `fd_set'.  */
> diff --git a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h
> b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h index
> 87c50a4f32..f68dfecc90 100644 ---
> a/sysdeps/unix/sysv/linux/x86/bits/typesizes.h +++
> b/sysdeps/unix/sysv/linux/x86/bits/typesizes.h @@ -94,6 +94,9 @@
>  # define __STATFS_MATCHES_STATFS64  0
>  #endif
>  
> +/* And for getitimer, setitimer and rusage  */
> +#define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 1
> +
>  /* Number of descriptors that can fit in an `fd_set'.  */
>  #define __FD_SETSIZE		1024
>  




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 5/8] linux: Use long time_t __getitimer/__setitimer
  2020-02-14 16:31 ` [PATCH v3 5/8] linux: Use long time_t __getitimer/__setitimer Alistair Francis
@ 2020-02-15 16:26   ` Lukasz Majewski
  2020-02-18 18:54     ` Alistair Francis
  0 siblings, 1 reply; 17+ messages in thread
From: Lukasz Majewski @ 2020-02-15 16:26 UTC (permalink / raw)
  To: Alistair Francis; +Cc: libc-alpha, alistair23

[-- Attachment #1: Type: text/plain, Size: 10475 bytes --]

Hi Alistair,

> The Linux kernel expects itimerval to use a 32-bit time_t, even on
> archs with a 64-bit time_t (like RV32). To address this let's convert
> itimerval to/from 32-bit and 64-bit to ensure the kernel always gets
> a 32-bit time_t.
> 
> While we are converting these functions let's also convert them to be
> the y2038 safe versions. This means there is a *64 function that is
> called by a backwards compatible wrapper.
> ---
>  include/time.h                        | 15 +++++
>  sysdeps/unix/sysv/linux/getitimer.c   | 61 +++++++++++++++++
>  sysdeps/unix/sysv/linux/setitimer.c   | 95
> +++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/tv32-compat.h |
> 35 ++++++++++ 4 files changed, 206 insertions(+)
>  create mode 100644 sysdeps/unix/sysv/linux/getitimer.c
>  create mode 100644 sysdeps/unix/sysv/linux/setitimer.c
>  create mode 100644 sysdeps/unix/sysv/linux/tv32-compat.h
> 
> diff --git a/include/time.h b/include/time.h
> index 34dffaf95f..cdaf461c3f 100644
> --- a/include/time.h
> +++ b/include/time.h
> @@ -6,6 +6,7 @@
>  # include <bits/types/locale_t.h>
>  # include <stdbool.h>
>  # include <time/mktime-internal.h>
> +# include <sys/time.h>
>  # include <endian.h>
>  # include <time-clockid.h>
>  # include <sys/time.h>
> @@ -119,6 +120,20 @@ struct __itimerval64
>  };
>  #endif
>  
> +#if __TIMESIZE == 64
> +# define __getitimer64 __getitimer
> +# define __setitimer64 __setitimer
> +#else
> +extern int __getitimer64 (enum __itimer_which __which,
> +                          struct __itimerval64 *__value);
> +
> +libc_hidden_proto (__getitimer64)
> +extern int __setitimer64 (enum __itimer_which __which,
> +                          const struct __itimerval64 *__restrict
> __new,
> +                          struct __itimerval64 *__restrict __old);
> +libc_hidden_proto (__setitimer64)
> +#endif
> +
>  #if __TIMESIZE == 64
>  # define __ctime64 ctime
>  #else
> diff --git a/sysdeps/unix/sysv/linux/getitimer.c
> b/sysdeps/unix/sysv/linux/getitimer.c new file mode 100644
> index 0000000000..62d58a7af5
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/getitimer.c
> @@ -0,0 +1,61 @@
> +/* getitimer -- Get the state of an interval timer.  Linux/tv32
> version.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <time.h>
> +#include <sys/time.h>
> +#include <sys/types.h>
> +#include <sysdep.h>
> +#include <tv32-compat.h>
> +
> +int
> +__getitimer64 (__itimer_which_t which, struct __itimerval64
> *curr_value) +{
> +

Minor - please remove this blank line.

> +#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> +  return INLINE_SYSCALL_CALL (getitimer, which, curr_value);
> +#else
> +  struct __itimerval32 curr_value_32;
> +  if (INLINE_SYSCALL_CALL (getitimer, which, &curr_value_32) == -1)
> +    return -1;
> +
> +  /* Write all fields of 'curr_value' regardless of overflow.  */
> +  curr_value->it_interval
> +    = valid_timeval32_to_timeval64 (curr_value_32.it_interval);
> +  curr_value->it_value
> +    = valid_timeval32_to_timeval64 (curr_value_32.it_value);
> +  return 0;
> +#endif
> +}
> +
> +

Minor - please remove one blank line.

> +#if __TIMESIZE != 64
> +libc_hidden_def (__getitimer64)
> +int
> +__getitimer (__itimer_which_t which, struct itimerval *curr_value)
> +{
> +  struct __itimerval64 val64;
> +
> +  val64.it_interval
> +    = valid_timeval_to_timeval64 (curr_value->it_interval);
> +  val64.it_value
> +    = valid_timeval_to_timeval64 (curr_value->it_value);
> +
> +  return __getitimer64 (which, &val64);
> +}
> +#endif
> +weak_alias (__getitimer, getitimer)
> diff --git a/sysdeps/unix/sysv/linux/setitimer.c
> b/sysdeps/unix/sysv/linux/setitimer.c new file mode 100644
> index 0000000000..238853dd33
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/setitimer.c
> @@ -0,0 +1,95 @@
> +/* setitimer -- Set the state of an interval timer.  Linux/tv32
> version.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <time.h>
> +#include <sys/time.h>
> +#include <sys/types.h>
> +#include <sysdep.h>
> +#include <tv32-compat.h>
> +
> +int
> +__setitimer64 (__itimer_which_t which,
> +               const struct __itimerval64 *restrict new_value,
> +               struct __itimerval64 *restrict old_value)
> +{
> +#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> +  return INLINE_SYSCALL_CALL (setitimer, which, new_value,
> old_value); +#else
> +  struct __itimerval32 new_value_32;
> +
> +  if (! in_time_t_range (new_value->it_interval.tv_sec))
> +  {
> +    __set_errno (EOVERFLOW);
> +    return -1;
> +  }
> +  new_value_32.it_interval
> +    = valid_timeval64_to_timeval32 (new_value->it_interval);
> +
> +  if (! in_time_t_range (new_value->it_value.tv_sec))
> +  {
> +    __set_errno (EOVERFLOW);
> +    return -1;
> +  }
> +  new_value_32.it_value
> +    = valid_timeval64_to_timeval32 (new_value->it_value);
> +
> +  if (old_value == NULL)
> +    return INLINE_SYSCALL_CALL (setitimer, which, &new_value_32,
> NULL); +
> +  struct __itimerval32 old_value_32;
> +  if (INLINE_SYSCALL_CALL (setitimer, which, &new_value_32,
> &old_value_32) == -1)
> +    return -1;
> +
> +  /* Write all fields of 'old_value' regardless of overflow.  */
> +  old_value->it_interval
> +     = valid_timeval32_to_timeval64 (old_value_32.it_interval);
> +  old_value->it_value
> +     = valid_timeval32_to_timeval64 (old_value_32.it_value);
> +  return 0;
> +#endif
> +}
> +
> +#if __TIMESIZE != 64
> +libc_hidden_def (__setitimer64)
> +int
> +__setitimer (__itimer_which_t which,
> +             const struct itimerval *restrict new_value,
> +             struct itimerval *restrict old_value)
> +{
> +  int ret;
> +  struct __itimerval64 new64, old64;
> +
> +  new64.it_interval
> +    = valid_timeval_to_timeval64 (new_value->it_interval);
> +  new64.it_value
> +    = valid_timeval_to_timeval64 (new_value->it_value);
> +
> +  ret = __setitimer64 (which, &new64, old_value ? &old64 : NULL);
> +
> +  if (ret == 0 && old_value)
> +    {
> +      old_value->it_interval
> +        = valid_timeval64_to_timeval (old64.it_interval);
> +      old_value->it_value
> +        = valid_timeval64_to_timeval (old64.it_value);
> +    }
> +
> +  return ret;
> +}
> +#endif
> +weak_alias (__setitimer, setitimer)

Tested-by: Lukasz Majewski <lukma@denx.de>

(ARM + qemu)

> diff --git a/sysdeps/unix/sysv/linux/tv32-compat.h
> b/sysdeps/unix/sysv/linux/tv32-compat.h new file mode 100644
> index 0000000000..4eb6f216ea
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tv32-compat.h
> @@ -0,0 +1,35 @@
> +/* Compatibility definitions for `struct timeval' with 32-bit time_t.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _TV32_COMPAT_H
> +#define _TV32_COMPAT_H 1
> +
> +#include <features.h>
> +
> +#include <bits/types.h>

I think that those two above headers are not necessary for this version
of struct __itimerval32 definition.

> +#include <bits/types/time_t.h>
> +#include <bits/types/struct_timeval.h>

As fair as I can see - the below code is not using struct timeval
anywhere, so this header is not necessary as well.

> +
> +/* Structures containing 'struct timeval' with 32-bit time_t.  */
> +struct __itimerval32
> +{
> +  struct __timeval32 it_interval;
> +  struct __timeval32 it_value;
> +};
> +
> +#endif /* tv32-compat.h */


And just a side note - as we provide new getitimer/setitimer/getrusage
implementations to /sysdeps/unix/sysv/linux/ , those entries in
./sysdeps/unix/syscalls.list could be removed (as we override them
here).

Anyway, this could be changed in a follow up patch and shall be
regarded as a cleanup patch (no functional changes).


Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 7/8] linux: Use long time_t for wait4/getrusage
  2020-02-14 16:31 ` [PATCH v3 7/8] linux: Use long time_t for wait4/getrusage Alistair Francis
@ 2020-02-15 16:27   ` Lukasz Majewski
  2020-02-16 16:30     ` Lukasz Majewski
  2020-02-18 23:04     ` Alistair Francis
  0 siblings, 2 replies; 17+ messages in thread
From: Lukasz Majewski @ 2020-02-15 16:27 UTC (permalink / raw)
  To: Alistair Francis; +Cc: libc-alpha, alistair23

[-- Attachment #1: Type: text/plain, Size: 9431 bytes --]

Hi Alistair,

> The Linux kernel expects rusage to use a 32-bit time_t, even on archs
> with a 64-bit time_t (like RV32). To address this let's convert
> rusage to/from 32-bit and 64-bit to ensure the kernel always gets
> a 32-bit time_t.
> 
> While we are converting these functions let's also convert them to be
> the y2038 safe versions. This means there is a *64 function that is
> called by a backwards compatible wrapper.
> ---
>  include/sys/resource.h                | 10 +++++
>  sysdeps/unix/sysv/linux/getrusage.c   | 58
> +++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/tv32-compat.h |
> 47 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/wait4.c       | 49
> +++++++++++++++++++++- 4 files changed, 162 insertions(+), 2
> deletions(-) create mode 100644 sysdeps/unix/sysv/linux/getrusage.c
> 
> diff --git a/include/sys/resource.h b/include/sys/resource.h
> index 9d604dfe3e..1a530fb62d 100644
> --- a/include/sys/resource.h
> +++ b/include/sys/resource.h
> @@ -134,5 +134,15 @@ extern int __getrusage (enum __rusage_who __who,
> struct rusage *__usage) extern int __setrlimit (enum
> __rlimit_resource __resource, const struct rlimit *__rlimits);
>  libc_hidden_proto (__setrlimit);
> +
> +#if __TIMESIZE == 64
> +# define __getrusage64 __getrusage
> +# define __wait4_time64 __wait4
> +#else
> +extern int __getrusage64 (enum __rusage_who who, struct __rusage64
> *usage); +libc_hidden_proto (__getrusage64)
> +pid_t __wait4_time64 (pid_t pid, int *stat_loc, int options, struct
> __rusage64 *usage); +libc_hidden_proto (__wait4_time64)

Please add extern on the beginning. Moreover, the declaration is longer
than 80 chars.

> +#endif
>  #endif
>  #endif
> diff --git a/sysdeps/unix/sysv/linux/getrusage.c
> b/sysdeps/unix/sysv/linux/getrusage.c new file mode 100644
> index 0000000000..a4e382ed53
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/getrusage.c
> @@ -0,0 +1,58 @@
> +/* getrusage -- get the rusage struct.  Linux version.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be
> useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <sys/time.h>
> +#include <sys/resource.h>
> +#include <sys/types.h>
> +#include <sysdep.h>
> +#include <tv32-compat.h>
> +
> +int
> +__getrusage64 (enum __rusage_who who, struct __rusage64 *usage)
> +{
> +#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> +  return INLINE_SYSCALL_CALL (getrusage, who, usage);
> +#else
> +  struct __rusage32 usage32;
> +  if (INLINE_SYSCALL_CALL (getrusage, who, &usage32) == -1)
> +    return -1;
> +
> +  rusage32_to_rusage64 (&usage32, usage);
> +  return 0;
> +#endif
> +}
> +
> +#if __TIMESIZE != 64
> +libc_hidden_def (__getrusage64)
> +int
> +__getrusage (enum __rusage_who who, struct rusage *usage)
> +{
> +  int ret ;
> +  struct __rusage64 usage64;
> +
> +  ret = __getrusage64 (who, &usage64);
> +
> +  if (ret != 0)
> +    return ret;
> +
> +  rusage64_to_rusage (&usage64, usage);
> +
> +  return ret;
> +}
> +#endif
> +weak_alias (__getrusage, getrusage)
> diff --git a/sysdeps/unix/sysv/linux/tv32-compat.h
> b/sysdeps/unix/sysv/linux/tv32-compat.h index 4eb6f216ea..c2231f042f
> 100644 --- a/sysdeps/unix/sysv/linux/tv32-compat.h
> +++ b/sysdeps/unix/sysv/linux/tv32-compat.h
> @@ -24,6 +24,7 @@
>  #include <bits/types.h>
>  #include <bits/types/time_t.h>
>  #include <bits/types/struct_timeval.h>
> +#include <sys/resource.h>
>  
>  /* Structures containing 'struct timeval' with 32-bit time_t.  */
>  struct __itimerval32
> @@ -32,4 +33,50 @@ struct __itimerval32
>    struct __timeval32 it_value;
>  };
>  
> +struct __rusage32
> +{
> +  struct __timeval32 ru_utime;	/* user time used */
> +  struct __timeval32 ru_stime;	/* system time used */
> +  long ru_maxrss;		/* maximum resident set size */
> +  long ru_ixrss;		/* integral shared memory size */
> +  long ru_idrss;		/* integral unshared data size */
> +  long ru_isrss;		/* integral unshared stack size */
> +  long ru_minflt;		/* page reclaims */
> +  long ru_majflt;		/* page faults */
> +  long ru_nswap;		/* swaps */
> +  long ru_inblock;		/* block input operations */
> +  long ru_oublock;		/* block output operations */
> +  long ru_msgsnd;		/* messages sent */
> +  long ru_msgrcv;		/* messages received */
> +  long ru_nsignals;		/* signals received */
> +  long ru_nvcsw;		/* voluntary context switches */
> +  long ru_nivcsw;		/* involuntary " */
> +};
> +
> +static inline void
> +rusage32_to_rusage64 (const struct __rusage32 *restrict r32,
> +                    struct __rusage64 *restrict r64)
> +{
> +  /* Make sure the entire output structure is cleared, including
> +     padding and reserved fields.  */
> +  memset (r64, 0, sizeof *r64);
> +
> +  r64->ru_utime    = valid_timeval32_to_timeval64 (r32->ru_utime);
> +  r64->ru_stime    = valid_timeval32_to_timeval64 (r32->ru_stime);
> +  r64->ru_maxrss   = r32->ru_maxrss;
> +  r64->ru_ixrss    = r32->ru_ixrss;
> +  r64->ru_idrss    = r32->ru_idrss;
> +  r64->ru_isrss    = r32->ru_isrss;
> +  r64->ru_minflt   = r32->ru_minflt;
> +  r64->ru_majflt   = r32->ru_majflt;
> +  r64->ru_nswap    = r32->ru_nswap;
> +  r64->ru_inblock  = r32->ru_inblock;
> +  r64->ru_oublock  = r32->ru_oublock;
> +  r64->ru_msgsnd   = r32->ru_msgsnd;
> +  r64->ru_msgrcv   = r32->ru_msgrcv;
> +  r64->ru_nsignals = r32->ru_nsignals;
> +  r64->ru_nvcsw    = r32->ru_nvcsw;
> +  r64->ru_nivcsw   = r32->ru_nivcsw;
> +}
> +
>  #endif /* tv32-compat.h */
> diff --git a/sysdeps/unix/sysv/linux/wait4.c
> b/sysdeps/unix/sysv/linux/wait4.c index 3a8bed1169..f4df1c3b99 100644
> --- a/sysdeps/unix/sysv/linux/wait4.c
> +++ b/sysdeps/unix/sysv/linux/wait4.c
> @@ -18,14 +18,30 @@
>  
>  #include <sys/wait.h>
>  #include <sys/resource.h>
> +#include <sys/types.h>
>  #include <sysdep-cancel.h>
> +#include <tv32-compat.h>
>  
>  pid_t
> -__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
> +__wait4_time64 (pid_t pid, int *stat_loc, int options, struct
> __rusage64 *usage) {
>  #ifdef __NR_wait4
> +# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
>    return SYSCALL_CANCEL (wait4, pid, stat_loc, options, usage);
> +# else
> +  struct __rusage32 usage32;
> +  pid_t ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options,
> &usage32); +
> +  if (ret != 0)
> +    return ret;
> +
> +  if (usage != NULL)
> +      rusage32_to_rusage64 (&usage32, usage);
> +
> +  return ret;
> +# endif
>  #elif defined (__ASSUME_WAITID_PID0_P_PGID)
> +  struct __rusage32 usage32;
>    idtype_t idtype = P_PID;
>  
>    if (pid < -1)
> @@ -41,7 +57,12 @@ __wait4 (pid_t pid, int *stat_loc, int options,
> struct rusage *usage) options |= WEXITED;
>  
>    siginfo_t infop;
> +
> +# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
>    if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, usage) <
> 0) +# else
> +  if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options,
> &usage32) < 0) +# endif
>      return -1;
>  
>    if (stat_loc)
> @@ -70,8 +91,13 @@ __wait4 (pid_t pid, int *stat_loc, int options,
> struct rusage *usage) }
>      }
>  
> +# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 == 0
> +  if (usage != NULL)
> +      rusage32_to_rusage64 (&usage32, usage);
> +# endif
> +
>    return infop.si_pid;
> -# else
> +#else
>  /* Linux waitid prior kernel 5.4 does not support waiting for the
> current process.  It is possible to emulate wait4 it by calling
> getpgid for PID 0, however, it would require an additional syscall
> and it is inherent @@ -81,5 +107,24 @@ __wait4 (pid_t pid, int
> *stat_loc, int options, struct rusage *usage) # error "The kernel ABI
> does not provide a way to implement wait4" #endif
>  }
> +libc_hidden_def (__wait4_time64)
> +
> +#if __TIMESIZE != 64

I think that the above libc_hidden_def (__wait4_time64) shall be moved
here (after #if __TIMESIZE != 64)

> +pid_t
> +__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
> +{
> +  pid_t ret ;
> +  struct __rusage64 usage64;
> +
> +  ret = __wait4_time64 (pid, stat_loc, options, &usage64);
> +
> +  if (ret != 0)
> +    return ret;
> +
> +  rusage64_to_rusage (&usage64, usage);
> +
> +  return ret;
> +}
>  libc_hidden_def (__wait4);
> +#endif

The above libc_hidden_def (__wait4); shall be moved here.

>  weak_alias (__wait4, wait4)




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 7/8] linux: Use long time_t for wait4/getrusage
  2020-02-15 16:27   ` Lukasz Majewski
@ 2020-02-16 16:30     ` Lukasz Majewski
  2020-02-18 23:04     ` Alistair Francis
  1 sibling, 0 replies; 17+ messages in thread
From: Lukasz Majewski @ 2020-02-16 16:30 UTC (permalink / raw)
  To: Alistair Francis; +Cc: libc-alpha, alistair23


[-- Attachment #1.1: Type: text/plain, Size: 10431 bytes --]

Hi Alistair,

> Hi Alistair,
> 
> > The Linux kernel expects rusage to use a 32-bit time_t, even on
> > archs with a 64-bit time_t (like RV32). To address this let's
> > convert rusage to/from 32-bit and 64-bit to ensure the kernel
> > always gets a 32-bit time_t.
> > 
> > While we are converting these functions let's also convert them to
> > be the y2038 safe versions. This means there is a *64 function that
> > is called by a backwards compatible wrapper.
> > ---
> >  include/sys/resource.h                | 10 +++++
> >  sysdeps/unix/sysv/linux/getrusage.c   | 58
> > +++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/tv32-compat.h |
> > 47 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/wait4.c       | 49
> > +++++++++++++++++++++- 4 files changed, 162 insertions(+), 2
> > deletions(-) create mode 100644 sysdeps/unix/sysv/linux/getrusage.c
> > 
> > diff --git a/include/sys/resource.h b/include/sys/resource.h
> > index 9d604dfe3e..1a530fb62d 100644
> > --- a/include/sys/resource.h
> > +++ b/include/sys/resource.h
> > @@ -134,5 +134,15 @@ extern int __getrusage (enum __rusage_who
> > __who, struct rusage *__usage) extern int __setrlimit (enum
> > __rlimit_resource __resource, const struct rlimit *__rlimits);
> >  libc_hidden_proto (__setrlimit);
> > +
> > +#if __TIMESIZE == 64
> > +# define __getrusage64 __getrusage
> > +# define __wait4_time64 __wait4
> > +#else
> > +extern int __getrusage64 (enum __rusage_who who, struct __rusage64
> > *usage); +libc_hidden_proto (__getrusage64)
> > +pid_t __wait4_time64 (pid_t pid, int *stat_loc, int options, struct
> > __rusage64 *usage); +libc_hidden_proto (__wait4_time64)  
> 
> Please add extern on the beginning. Moreover, the declaration is
> longer than 80 chars.
> 
> > +#endif
> >  #endif
> >  #endif
> > diff --git a/sysdeps/unix/sysv/linux/getrusage.c
> > b/sysdeps/unix/sysv/linux/getrusage.c new file mode 100644
> > index 0000000000..a4e382ed53
> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/getrusage.c
> > @@ -0,0 +1,58 @@
> > +/* getrusage -- get the rusage struct.  Linux version.
> > +   Copyright (C) 2020 Free Software Foundation, Inc.
> > +   This file is part of the GNU C Library.
> > +
> > +   The GNU C Library is free software; you can redistribute it
> > and/or
> > +   modify it under the terms of the GNU Lesser General Public
> > +   License as published by the Free Software Foundation; either
> > +   version 2.1 of the License, or (at your option) any later
> > version. +
> > +   The GNU C Library is distributed in the hope that it will be
> > useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > GNU
> > +   Lesser General Public License for more details.
> > +
> > +   You should have received a copy of the GNU Lesser General Public
> > +   License along with the GNU C Library; if not, see
> > +   <http://www.gnu.org/licenses/>.  */
> > +
> > +#include <sys/time.h>
> > +#include <sys/resource.h>
> > +#include <sys/types.h>
> > +#include <sysdep.h>
> > +#include <tv32-compat.h>
> > +
> > +int
> > +__getrusage64 (enum __rusage_who who, struct __rusage64 *usage)
> > +{
> > +#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> > +  return INLINE_SYSCALL_CALL (getrusage, who, usage);
> > +#else
> > +  struct __rusage32 usage32;
> > +  if (INLINE_SYSCALL_CALL (getrusage, who, &usage32) == -1)
> > +    return -1;
> > +
> > +  rusage32_to_rusage64 (&usage32, usage);
> > +  return 0;
> > +#endif
> > +}
> > +
> > +#if __TIMESIZE != 64
> > +libc_hidden_def (__getrusage64)
> > +int
> > +__getrusage (enum __rusage_who who, struct rusage *usage)
> > +{
> > +  int ret ;
> > +  struct __rusage64 usage64;
> > +
> > +  ret = __getrusage64 (who, &usage64);
> > +
> > +  if (ret != 0)
> > +    return ret;
> > +
> > +  rusage64_to_rusage (&usage64, usage);
> > +
> > +  return ret;
> > +}
> > +#endif
> > +weak_alias (__getrusage, getrusage)
> > diff --git a/sysdeps/unix/sysv/linux/tv32-compat.h
> > b/sysdeps/unix/sysv/linux/tv32-compat.h index 4eb6f216ea..c2231f042f
> > 100644 --- a/sysdeps/unix/sysv/linux/tv32-compat.h
> > +++ b/sysdeps/unix/sysv/linux/tv32-compat.h
> > @@ -24,6 +24,7 @@
> >  #include <bits/types.h>
> >  #include <bits/types/time_t.h>
> >  #include <bits/types/struct_timeval.h>
> > +#include <sys/resource.h>
> >  
> >  /* Structures containing 'struct timeval' with 32-bit time_t.  */
> >  struct __itimerval32
> > @@ -32,4 +33,50 @@ struct __itimerval32
> >    struct __timeval32 it_value;
> >  };
> >  
> > +struct __rusage32
> > +{
> > +  struct __timeval32 ru_utime;	/* user time used */
> > +  struct __timeval32 ru_stime;	/* system time used */
> > +  long ru_maxrss;		/* maximum resident set size */
> > +  long ru_ixrss;		/* integral shared memory size */
> > +  long ru_idrss;		/* integral unshared data size */
> > +  long ru_isrss;		/* integral unshared stack size */
> > +  long ru_minflt;		/* page reclaims */
> > +  long ru_majflt;		/* page faults */
> > +  long ru_nswap;		/* swaps */
> > +  long ru_inblock;		/* block input operations */
> > +  long ru_oublock;		/* block output operations */
> > +  long ru_msgsnd;		/* messages sent */
> > +  long ru_msgrcv;		/* messages received */
> > +  long ru_nsignals;		/* signals received */
> > +  long ru_nvcsw;		/* voluntary context switches */
> > +  long ru_nivcsw;		/* involuntary " */
> > +};
> > +
> > +static inline void
> > +rusage32_to_rusage64 (const struct __rusage32 *restrict r32,
> > +                    struct __rusage64 *restrict r64)
> > +{
> > +  /* Make sure the entire output structure is cleared, including
> > +     padding and reserved fields.  */
> > +  memset (r64, 0, sizeof *r64);
> > +
> > +  r64->ru_utime    = valid_timeval32_to_timeval64 (r32->ru_utime);
> > +  r64->ru_stime    = valid_timeval32_to_timeval64 (r32->ru_stime);
> > +  r64->ru_maxrss   = r32->ru_maxrss;
> > +  r64->ru_ixrss    = r32->ru_ixrss;
> > +  r64->ru_idrss    = r32->ru_idrss;
> > +  r64->ru_isrss    = r32->ru_isrss;
> > +  r64->ru_minflt   = r32->ru_minflt;
> > +  r64->ru_majflt   = r32->ru_majflt;
> > +  r64->ru_nswap    = r32->ru_nswap;
> > +  r64->ru_inblock  = r32->ru_inblock;
> > +  r64->ru_oublock  = r32->ru_oublock;
> > +  r64->ru_msgsnd   = r32->ru_msgsnd;
> > +  r64->ru_msgrcv   = r32->ru_msgrcv;
> > +  r64->ru_nsignals = r32->ru_nsignals;
> > +  r64->ru_nvcsw    = r32->ru_nvcsw;
> > +  r64->ru_nivcsw   = r32->ru_nivcsw;
> > +}
> > +
> >  #endif /* tv32-compat.h */
> > diff --git a/sysdeps/unix/sysv/linux/wait4.c
> > b/sysdeps/unix/sysv/linux/wait4.c index 3a8bed1169..f4df1c3b99
> > 100644 --- a/sysdeps/unix/sysv/linux/wait4.c
> > +++ b/sysdeps/unix/sysv/linux/wait4.c
> > @@ -18,14 +18,30 @@
> >  
> >  #include <sys/wait.h>
> >  #include <sys/resource.h>
> > +#include <sys/types.h>
> >  #include <sysdep-cancel.h>
> > +#include <tv32-compat.h>
> >  
> >  pid_t
> > -__wait4 (pid_t pid, int *stat_loc, int options, struct rusage
> > *usage) +__wait4_time64 (pid_t pid, int *stat_loc, int options,
> > struct __rusage64 *usage) {
> >  #ifdef __NR_wait4
> > +# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> >    return SYSCALL_CANCEL (wait4, pid, stat_loc, options, usage);
> > +# else
> > +  struct __rusage32 usage32;
> > +  pid_t ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options,
> > &usage32); +
> > +  if (ret != 0)
> > +    return ret;
> > +
> > +  if (usage != NULL)
> > +      rusage32_to_rusage64 (&usage32, usage);
> > +
> > +  return ret;
> > +# endif
> >  #elif defined (__ASSUME_WAITID_PID0_P_PGID)
> > +  struct __rusage32 usage32;
> >    idtype_t idtype = P_PID;
> >  
> >    if (pid < -1)
> > @@ -41,7 +57,12 @@ __wait4 (pid_t pid, int *stat_loc, int options,
> > struct rusage *usage) options |= WEXITED;
> >  
> >    siginfo_t infop;
> > +
> > +# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> >    if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, usage)
> > < 0) +# else
> > +  if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options,
> > &usage32) < 0) +# endif
> >      return -1;
> >  
> >    if (stat_loc)
> > @@ -70,8 +91,13 @@ __wait4 (pid_t pid, int *stat_loc, int options,
> > struct rusage *usage) }
> >      }
> >  
> > +# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 == 0
> > +  if (usage != NULL)
> > +      rusage32_to_rusage64 (&usage32, usage);
> > +# endif
> > +
> >    return infop.si_pid;
> > -# else
> > +#else
> >  /* Linux waitid prior kernel 5.4 does not support waiting for the
> > current process.  It is possible to emulate wait4 it by calling
> > getpgid for PID 0, however, it would require an additional syscall
> > and it is inherent @@ -81,5 +107,24 @@ __wait4 (pid_t pid, int
> > *stat_loc, int options, struct rusage *usage) # error "The kernel
> > ABI does not provide a way to implement wait4" #endif
> >  }
> > +libc_hidden_def (__wait4_time64)
> > +
> > +#if __TIMESIZE != 64  
> 
> I think that the above libc_hidden_def (__wait4_time64) shall be moved
> here (after #if __TIMESIZE != 64)
> 
> > +pid_t
> > +__wait4 (pid_t pid, int *stat_loc, int options, struct rusage
> > *usage) +{
> > +  pid_t ret ;
> > +  struct __rusage64 usage64;
> > +
> > +  ret = __wait4_time64 (pid, stat_loc, options, &usage64);
> > +
> > +  if (ret != 0)
> > +    return ret;
> > +
> > +  rusage64_to_rusage (&usage64, usage);
> > +
> > +  return ret;
> > +}
> >  libc_hidden_def (__wait4);
> > +#endif  
> 
> The above libc_hidden_def (__wait4); shall be moved here.

Please find proper fix patch attached (please squash it with this
patch - I've also tested it with Y2038 series and seems to be OK).

> 
> >  weak_alias (__wait4, wait4)  
> 
> 
> 
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email:
> lukma@denx.de




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-FIX-wait4-Conversion-to-64-bit-time-support.patch --]
[-- Type: text/x-patch, Size: 1153 bytes --]

From 4dda74fb309b16fc83b9d05a9a8696f6510f107c Mon Sep 17 00:00:00 2001
From: Lukasz Majewski <lukma@denx.de>
Date: Sat, 15 Feb 2020 16:42:00 +0100
Subject: [PATCH] FIX: wait4: Conversion to 64 bit time support

Signed-off-by: Lukasz Majewski <lukma@denx.de>
---
 sysdeps/unix/sysv/linux/wait4.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/wait4.c b/sysdeps/unix/sysv/linux/wait4.c
index f4df1c3b99..99254a76bc 100644
--- a/sysdeps/unix/sysv/linux/wait4.c
+++ b/sysdeps/unix/sysv/linux/wait4.c
@@ -107,9 +107,10 @@ __wait4_time64 (pid_t pid, int *stat_loc, int options, struct __rusage64 *usage)
 # error "The kernel ABI does not provide a way to implement wait4"
 #endif
 }
-libc_hidden_def (__wait4_time64)
 
 #if __TIMESIZE != 64
+libc_hidden_def (__wait4_time64)
+
 pid_t
 __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
 {
@@ -125,6 +126,6 @@ __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
 
   return ret;
 }
-libc_hidden_def (__wait4);
 #endif
+libc_hidden_def (__wait4)
 weak_alias (__wait4, wait4)
-- 
2.20.1


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 5/8] linux: Use long time_t __getitimer/__setitimer
  2020-02-15 16:26   ` Lukasz Majewski
@ 2020-02-18 18:54     ` Alistair Francis
  0 siblings, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-02-18 18:54 UTC (permalink / raw)
  To: Lukasz Majewski; +Cc: Alistair Francis, GNU C Library

On Sat, Feb 15, 2020 at 8:26 AM Lukasz Majewski <lukma@denx.de> wrote:
>
> Hi Alistair,
>
> > The Linux kernel expects itimerval to use a 32-bit time_t, even on
> > archs with a 64-bit time_t (like RV32). To address this let's convert
> > itimerval to/from 32-bit and 64-bit to ensure the kernel always gets
> > a 32-bit time_t.
> >
> > While we are converting these functions let's also convert them to be
> > the y2038 safe versions. This means there is a *64 function that is
> > called by a backwards compatible wrapper.
> > ---
> >  include/time.h                        | 15 +++++
> >  sysdeps/unix/sysv/linux/getitimer.c   | 61 +++++++++++++++++
> >  sysdeps/unix/sysv/linux/setitimer.c   | 95
> > +++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/tv32-compat.h |
> > 35 ++++++++++ 4 files changed, 206 insertions(+)
> >  create mode 100644 sysdeps/unix/sysv/linux/getitimer.c
> >  create mode 100644 sysdeps/unix/sysv/linux/setitimer.c
> >  create mode 100644 sysdeps/unix/sysv/linux/tv32-compat.h
> >
> > diff --git a/include/time.h b/include/time.h
> > index 34dffaf95f..cdaf461c3f 100644
> > --- a/include/time.h
> > +++ b/include/time.h
> > @@ -6,6 +6,7 @@
> >  # include <bits/types/locale_t.h>
> >  # include <stdbool.h>
> >  # include <time/mktime-internal.h>
> > +# include <sys/time.h>
> >  # include <endian.h>
> >  # include <time-clockid.h>
> >  # include <sys/time.h>
> > @@ -119,6 +120,20 @@ struct __itimerval64
> >  };
> >  #endif
> >
> > +#if __TIMESIZE == 64
> > +# define __getitimer64 __getitimer
> > +# define __setitimer64 __setitimer
> > +#else
> > +extern int __getitimer64 (enum __itimer_which __which,
> > +                          struct __itimerval64 *__value);
> > +
> > +libc_hidden_proto (__getitimer64)
> > +extern int __setitimer64 (enum __itimer_which __which,
> > +                          const struct __itimerval64 *__restrict
> > __new,
> > +                          struct __itimerval64 *__restrict __old);
> > +libc_hidden_proto (__setitimer64)
> > +#endif
> > +
> >  #if __TIMESIZE == 64
> >  # define __ctime64 ctime
> >  #else
> > diff --git a/sysdeps/unix/sysv/linux/getitimer.c
> > b/sysdeps/unix/sysv/linux/getitimer.c new file mode 100644
> > index 0000000000..62d58a7af5
> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/getitimer.c
> > @@ -0,0 +1,61 @@
> > +/* getitimer -- Get the state of an interval timer.  Linux/tv32
> > version.
> > +   Copyright (C) 2020 Free Software Foundation, Inc.
> > +   This file is part of the GNU C Library.
> > +
> > +   The GNU C Library is free software; you can redistribute it and/or
> > +   modify it under the terms of the GNU Lesser General Public
> > +   License as published by the Free Software Foundation; either
> > +   version 2.1 of the License, or (at your option) any later version.
> > +
> > +   The GNU C Library is distributed in the hope that it will be
> > useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > +   Lesser General Public License for more details.
> > +
> > +   You should have received a copy of the GNU Lesser General Public
> > +   License along with the GNU C Library; if not, see
> > +   <http://www.gnu.org/licenses/>.  */
> > +
> > +#include <time.h>
> > +#include <sys/time.h>
> > +#include <sys/types.h>
> > +#include <sysdep.h>
> > +#include <tv32-compat.h>
> > +
> > +int
> > +__getitimer64 (__itimer_which_t which, struct __itimerval64
> > *curr_value) +{
> > +
>
> Minor - please remove this blank line.
>
> > +#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> > +  return INLINE_SYSCALL_CALL (getitimer, which, curr_value);
> > +#else
> > +  struct __itimerval32 curr_value_32;
> > +  if (INLINE_SYSCALL_CALL (getitimer, which, &curr_value_32) == -1)
> > +    return -1;
> > +
> > +  /* Write all fields of 'curr_value' regardless of overflow.  */
> > +  curr_value->it_interval
> > +    = valid_timeval32_to_timeval64 (curr_value_32.it_interval);
> > +  curr_value->it_value
> > +    = valid_timeval32_to_timeval64 (curr_value_32.it_value);
> > +  return 0;
> > +#endif
> > +}
> > +
> > +
>
> Minor - please remove one blank line.

Good catch, I have removed both of these.

>
> > +#if __TIMESIZE != 64
> > +libc_hidden_def (__getitimer64)
> > +int
> > +__getitimer (__itimer_which_t which, struct itimerval *curr_value)
> > +{
> > +  struct __itimerval64 val64;
> > +
> > +  val64.it_interval
> > +    = valid_timeval_to_timeval64 (curr_value->it_interval);
> > +  val64.it_value
> > +    = valid_timeval_to_timeval64 (curr_value->it_value);
> > +
> > +  return __getitimer64 (which, &val64);
> > +}
> > +#endif
> > +weak_alias (__getitimer, getitimer)
> > diff --git a/sysdeps/unix/sysv/linux/setitimer.c
> > b/sysdeps/unix/sysv/linux/setitimer.c new file mode 100644
> > index 0000000000..238853dd33
> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/setitimer.c
> > @@ -0,0 +1,95 @@
> > +/* setitimer -- Set the state of an interval timer.  Linux/tv32
> > version.
> > +   Copyright (C) 2020 Free Software Foundation, Inc.
> > +   This file is part of the GNU C Library.
> > +
> > +   The GNU C Library is free software; you can redistribute it and/or
> > +   modify it under the terms of the GNU Lesser General Public
> > +   License as published by the Free Software Foundation; either
> > +   version 2.1 of the License, or (at your option) any later version.
> > +
> > +   The GNU C Library is distributed in the hope that it will be
> > useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > +   Lesser General Public License for more details.
> > +
> > +   You should have received a copy of the GNU Lesser General Public
> > +   License along with the GNU C Library; if not, see
> > +   <http://www.gnu.org/licenses/>.  */
> > +
> > +#include <time.h>
> > +#include <sys/time.h>
> > +#include <sys/types.h>
> > +#include <sysdep.h>
> > +#include <tv32-compat.h>
> > +
> > +int
> > +__setitimer64 (__itimer_which_t which,
> > +               const struct __itimerval64 *restrict new_value,
> > +               struct __itimerval64 *restrict old_value)
> > +{
> > +#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> > +  return INLINE_SYSCALL_CALL (setitimer, which, new_value,
> > old_value); +#else
> > +  struct __itimerval32 new_value_32;
> > +
> > +  if (! in_time_t_range (new_value->it_interval.tv_sec))
> > +  {
> > +    __set_errno (EOVERFLOW);
> > +    return -1;
> > +  }
> > +  new_value_32.it_interval
> > +    = valid_timeval64_to_timeval32 (new_value->it_interval);
> > +
> > +  if (! in_time_t_range (new_value->it_value.tv_sec))
> > +  {
> > +    __set_errno (EOVERFLOW);
> > +    return -1;
> > +  }
> > +  new_value_32.it_value
> > +    = valid_timeval64_to_timeval32 (new_value->it_value);
> > +
> > +  if (old_value == NULL)
> > +    return INLINE_SYSCALL_CALL (setitimer, which, &new_value_32,
> > NULL); +
> > +  struct __itimerval32 old_value_32;
> > +  if (INLINE_SYSCALL_CALL (setitimer, which, &new_value_32,
> > &old_value_32) == -1)
> > +    return -1;
> > +
> > +  /* Write all fields of 'old_value' regardless of overflow.  */
> > +  old_value->it_interval
> > +     = valid_timeval32_to_timeval64 (old_value_32.it_interval);
> > +  old_value->it_value
> > +     = valid_timeval32_to_timeval64 (old_value_32.it_value);
> > +  return 0;
> > +#endif
> > +}
> > +
> > +#if __TIMESIZE != 64
> > +libc_hidden_def (__setitimer64)
> > +int
> > +__setitimer (__itimer_which_t which,
> > +             const struct itimerval *restrict new_value,
> > +             struct itimerval *restrict old_value)
> > +{
> > +  int ret;
> > +  struct __itimerval64 new64, old64;
> > +
> > +  new64.it_interval
> > +    = valid_timeval_to_timeval64 (new_value->it_interval);
> > +  new64.it_value
> > +    = valid_timeval_to_timeval64 (new_value->it_value);
> > +
> > +  ret = __setitimer64 (which, &new64, old_value ? &old64 : NULL);
> > +
> > +  if (ret == 0 && old_value)
> > +    {
> > +      old_value->it_interval
> > +        = valid_timeval64_to_timeval (old64.it_interval);
> > +      old_value->it_value
> > +        = valid_timeval64_to_timeval (old64.it_value);
> > +    }
> > +
> > +  return ret;
> > +}
> > +#endif
> > +weak_alias (__setitimer, setitimer)
>
> Tested-by: Lukasz Majewski <lukma@denx.de>
>
> (ARM + qemu)

Thanks!

>
> > diff --git a/sysdeps/unix/sysv/linux/tv32-compat.h
> > b/sysdeps/unix/sysv/linux/tv32-compat.h new file mode 100644
> > index 0000000000..4eb6f216ea
> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/tv32-compat.h
> > @@ -0,0 +1,35 @@
> > +/* Compatibility definitions for `struct timeval' with 32-bit time_t.
> > +   Copyright (C) 2020 Free Software Foundation, Inc.
> > +   This file is part of the GNU C Library.
> > +
> > +   The GNU C Library is free software; you can redistribute it and/or
> > +   modify it under the terms of the GNU Lesser General Public
> > +   License as published by the Free Software Foundation; either
> > +   version 2.1 of the License, or (at your option) any later version.
> > +
> > +   The GNU C Library is distributed in the hope that it will be
> > useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > +   Lesser General Public License for more details.
> > +
> > +   You should have received a copy of the GNU Lesser General Public
> > +   License along with the GNU C Library; if not, see
> > +   <http://www.gnu.org/licenses/>.  */
> > +
> > +#ifndef _TV32_COMPAT_H
> > +#define _TV32_COMPAT_H 1
> > +
> > +#include <features.h>
> > +
> > +#include <bits/types.h>
>
> I think that those two above headers are not necessary for this version
> of struct __itimerval32 definition.

I think you are right.

>
> > +#include <bits/types/time_t.h>
> > +#include <bits/types/struct_timeval.h>
>
> As fair as I can see - the below code is not using struct timeval
> anywhere, so this header is not necessary as well.

I think you are right here as well. I'm running the tests again if I
don't see any issues I will remove all of these.

>
> > +
> > +/* Structures containing 'struct timeval' with 32-bit time_t.  */
> > +struct __itimerval32
> > +{
> > +  struct __timeval32 it_interval;
> > +  struct __timeval32 it_value;
> > +};
> > +
> > +#endif /* tv32-compat.h */
>
>
> And just a side note - as we provide new getitimer/setitimer/getrusage
> implementations to /sysdeps/unix/sysv/linux/ , those entries in
> ./sysdeps/unix/syscalls.list could be removed (as we override them
> here).

Good point, I have removed those.

Thanks fro reviewing my series.

Alistair

>
> Anyway, this could be changed in a follow up patch and shall be
> regarded as a cleanup patch (no functional changes).
>
>
> Best regards,
>
> Lukasz Majewski
>
> --
>
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v3 7/8] linux: Use long time_t for wait4/getrusage
  2020-02-15 16:27   ` Lukasz Majewski
  2020-02-16 16:30     ` Lukasz Majewski
@ 2020-02-18 23:04     ` Alistair Francis
  1 sibling, 0 replies; 17+ messages in thread
From: Alistair Francis @ 2020-02-18 23:04 UTC (permalink / raw)
  To: Lukasz Majewski; +Cc: Alistair Francis, GNU C Library

On Sat, Feb 15, 2020 at 8:27 AM Lukasz Majewski <lukma@denx.de> wrote:
>
> Hi Alistair,
>
> > The Linux kernel expects rusage to use a 32-bit time_t, even on archs
> > with a 64-bit time_t (like RV32). To address this let's convert
> > rusage to/from 32-bit and 64-bit to ensure the kernel always gets
> > a 32-bit time_t.
> >
> > While we are converting these functions let's also convert them to be
> > the y2038 safe versions. This means there is a *64 function that is
> > called by a backwards compatible wrapper.
> > ---
> >  include/sys/resource.h                | 10 +++++
> >  sysdeps/unix/sysv/linux/getrusage.c   | 58
> > +++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/tv32-compat.h |
> > 47 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/wait4.c       | 49
> > +++++++++++++++++++++- 4 files changed, 162 insertions(+), 2
> > deletions(-) create mode 100644 sysdeps/unix/sysv/linux/getrusage.c
> >
> > diff --git a/include/sys/resource.h b/include/sys/resource.h
> > index 9d604dfe3e..1a530fb62d 100644
> > --- a/include/sys/resource.h
> > +++ b/include/sys/resource.h
> > @@ -134,5 +134,15 @@ extern int __getrusage (enum __rusage_who __who,
> > struct rusage *__usage) extern int __setrlimit (enum
> > __rlimit_resource __resource, const struct rlimit *__rlimits);
> >  libc_hidden_proto (__setrlimit);
> > +
> > +#if __TIMESIZE == 64
> > +# define __getrusage64 __getrusage
> > +# define __wait4_time64 __wait4
> > +#else
> > +extern int __getrusage64 (enum __rusage_who who, struct __rusage64
> > *usage); +libc_hidden_proto (__getrusage64)
> > +pid_t __wait4_time64 (pid_t pid, int *stat_loc, int options, struct
> > __rusage64 *usage); +libc_hidden_proto (__wait4_time64)
>
> Please add extern on the beginning. Moreover, the declaration is longer
> than 80 chars.
>
> > +#endif
> >  #endif
> >  #endif
> > diff --git a/sysdeps/unix/sysv/linux/getrusage.c
> > b/sysdeps/unix/sysv/linux/getrusage.c new file mode 100644
> > index 0000000000..a4e382ed53
> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/getrusage.c
> > @@ -0,0 +1,58 @@
> > +/* getrusage -- get the rusage struct.  Linux version.
> > +   Copyright (C) 2020 Free Software Foundation, Inc.
> > +   This file is part of the GNU C Library.
> > +
> > +   The GNU C Library is free software; you can redistribute it and/or
> > +   modify it under the terms of the GNU Lesser General Public
> > +   License as published by the Free Software Foundation; either
> > +   version 2.1 of the License, or (at your option) any later version.
> > +
> > +   The GNU C Library is distributed in the hope that it will be
> > useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > +   Lesser General Public License for more details.
> > +
> > +   You should have received a copy of the GNU Lesser General Public
> > +   License along with the GNU C Library; if not, see
> > +   <http://www.gnu.org/licenses/>.  */
> > +
> > +#include <sys/time.h>
> > +#include <sys/resource.h>
> > +#include <sys/types.h>
> > +#include <sysdep.h>
> > +#include <tv32-compat.h>
> > +
> > +int
> > +__getrusage64 (enum __rusage_who who, struct __rusage64 *usage)
> > +{
> > +#if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> > +  return INLINE_SYSCALL_CALL (getrusage, who, usage);
> > +#else
> > +  struct __rusage32 usage32;
> > +  if (INLINE_SYSCALL_CALL (getrusage, who, &usage32) == -1)
> > +    return -1;
> > +
> > +  rusage32_to_rusage64 (&usage32, usage);
> > +  return 0;
> > +#endif
> > +}
> > +
> > +#if __TIMESIZE != 64
> > +libc_hidden_def (__getrusage64)
> > +int
> > +__getrusage (enum __rusage_who who, struct rusage *usage)
> > +{
> > +  int ret ;
> > +  struct __rusage64 usage64;
> > +
> > +  ret = __getrusage64 (who, &usage64);
> > +
> > +  if (ret != 0)
> > +    return ret;
> > +
> > +  rusage64_to_rusage (&usage64, usage);
> > +
> > +  return ret;
> > +}
> > +#endif
> > +weak_alias (__getrusage, getrusage)
> > diff --git a/sysdeps/unix/sysv/linux/tv32-compat.h
> > b/sysdeps/unix/sysv/linux/tv32-compat.h index 4eb6f216ea..c2231f042f
> > 100644 --- a/sysdeps/unix/sysv/linux/tv32-compat.h
> > +++ b/sysdeps/unix/sysv/linux/tv32-compat.h
> > @@ -24,6 +24,7 @@
> >  #include <bits/types.h>
> >  #include <bits/types/time_t.h>
> >  #include <bits/types/struct_timeval.h>
> > +#include <sys/resource.h>
> >
> >  /* Structures containing 'struct timeval' with 32-bit time_t.  */
> >  struct __itimerval32
> > @@ -32,4 +33,50 @@ struct __itimerval32
> >    struct __timeval32 it_value;
> >  };
> >
> > +struct __rusage32
> > +{
> > +  struct __timeval32 ru_utime;       /* user time used */
> > +  struct __timeval32 ru_stime;       /* system time used */
> > +  long ru_maxrss;            /* maximum resident set size */
> > +  long ru_ixrss;             /* integral shared memory size */
> > +  long ru_idrss;             /* integral unshared data size */
> > +  long ru_isrss;             /* integral unshared stack size */
> > +  long ru_minflt;            /* page reclaims */
> > +  long ru_majflt;            /* page faults */
> > +  long ru_nswap;             /* swaps */
> > +  long ru_inblock;           /* block input operations */
> > +  long ru_oublock;           /* block output operations */
> > +  long ru_msgsnd;            /* messages sent */
> > +  long ru_msgrcv;            /* messages received */
> > +  long ru_nsignals;          /* signals received */
> > +  long ru_nvcsw;             /* voluntary context switches */
> > +  long ru_nivcsw;            /* involuntary " */
> > +};
> > +
> > +static inline void
> > +rusage32_to_rusage64 (const struct __rusage32 *restrict r32,
> > +                    struct __rusage64 *restrict r64)
> > +{
> > +  /* Make sure the entire output structure is cleared, including
> > +     padding and reserved fields.  */
> > +  memset (r64, 0, sizeof *r64);
> > +
> > +  r64->ru_utime    = valid_timeval32_to_timeval64 (r32->ru_utime);
> > +  r64->ru_stime    = valid_timeval32_to_timeval64 (r32->ru_stime);
> > +  r64->ru_maxrss   = r32->ru_maxrss;
> > +  r64->ru_ixrss    = r32->ru_ixrss;
> > +  r64->ru_idrss    = r32->ru_idrss;
> > +  r64->ru_isrss    = r32->ru_isrss;
> > +  r64->ru_minflt   = r32->ru_minflt;
> > +  r64->ru_majflt   = r32->ru_majflt;
> > +  r64->ru_nswap    = r32->ru_nswap;
> > +  r64->ru_inblock  = r32->ru_inblock;
> > +  r64->ru_oublock  = r32->ru_oublock;
> > +  r64->ru_msgsnd   = r32->ru_msgsnd;
> > +  r64->ru_msgrcv   = r32->ru_msgrcv;
> > +  r64->ru_nsignals = r32->ru_nsignals;
> > +  r64->ru_nvcsw    = r32->ru_nvcsw;
> > +  r64->ru_nivcsw   = r32->ru_nivcsw;
> > +}
> > +
> >  #endif /* tv32-compat.h */
> > diff --git a/sysdeps/unix/sysv/linux/wait4.c
> > b/sysdeps/unix/sysv/linux/wait4.c index 3a8bed1169..f4df1c3b99 100644
> > --- a/sysdeps/unix/sysv/linux/wait4.c
> > +++ b/sysdeps/unix/sysv/linux/wait4.c
> > @@ -18,14 +18,30 @@
> >
> >  #include <sys/wait.h>
> >  #include <sys/resource.h>
> > +#include <sys/types.h>
> >  #include <sysdep-cancel.h>
> > +#include <tv32-compat.h>
> >
> >  pid_t
> > -__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
> > +__wait4_time64 (pid_t pid, int *stat_loc, int options, struct
> > __rusage64 *usage) {
> >  #ifdef __NR_wait4
> > +# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> >    return SYSCALL_CANCEL (wait4, pid, stat_loc, options, usage);
> > +# else
> > +  struct __rusage32 usage32;
> > +  pid_t ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options,
> > &usage32); +
> > +  if (ret != 0)
> > +    return ret;
> > +
> > +  if (usage != NULL)
> > +      rusage32_to_rusage64 (&usage32, usage);
> > +
> > +  return ret;
> > +# endif
> >  #elif defined (__ASSUME_WAITID_PID0_P_PGID)
> > +  struct __rusage32 usage32;
> >    idtype_t idtype = P_PID;
> >
> >    if (pid < -1)
> > @@ -41,7 +57,12 @@ __wait4 (pid_t pid, int *stat_loc, int options,
> > struct rusage *usage) options |= WEXITED;
> >
> >    siginfo_t infop;
> > +
> > +# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
> >    if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, usage) <
> > 0) +# else
> > +  if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options,
> > &usage32) < 0) +# endif
> >      return -1;
> >
> >    if (stat_loc)
> > @@ -70,8 +91,13 @@ __wait4 (pid_t pid, int *stat_loc, int options,
> > struct rusage *usage) }
> >      }
> >
> > +# if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 == 0
> > +  if (usage != NULL)
> > +      rusage32_to_rusage64 (&usage32, usage);
> > +# endif
> > +
> >    return infop.si_pid;
> > -# else
> > +#else
> >  /* Linux waitid prior kernel 5.4 does not support waiting for the
> > current process.  It is possible to emulate wait4 it by calling
> > getpgid for PID 0, however, it would require an additional syscall
> > and it is inherent @@ -81,5 +107,24 @@ __wait4 (pid_t pid, int
> > *stat_loc, int options, struct rusage *usage) # error "The kernel ABI
> > does not provide a way to implement wait4" #endif
> >  }
> > +libc_hidden_def (__wait4_time64)
> > +
> > +#if __TIMESIZE != 64
>
> I think that the above libc_hidden_def (__wait4_time64) shall be moved
> here (after #if __TIMESIZE != 64)
>
> > +pid_t
> > +__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
> > +{
> > +  pid_t ret ;
> > +  struct __rusage64 usage64;
> > +
> > +  ret = __wait4_time64 (pid, stat_loc, options, &usage64);
> > +
> > +  if (ret != 0)
> > +    return ret;
> > +
> > +  rusage64_to_rusage (&usage64, usage);
> > +
> > +  return ret;
> > +}
> >  libc_hidden_def (__wait4);
> > +#endif
>
> The above libc_hidden_def (__wait4); shall be moved here.
>
> >  weak_alias (__wait4, wait4)

Thanks for the review. I have made all of the requested changes.

Alistair

>
>
>
>
> Best regards,
>
> Lukasz Majewski
>
> --
>
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-02-18 23:11 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-14 16:31 [PATCH v3 0/8] Always use 32-bit time_t for certain syscalls Alistair Francis
2020-02-14 16:31 ` [PATCH v3 1/8] sysv/linux: Rename alpha functions to be alpha specific Alistair Francis
2020-02-15 13:54   ` Lukasz Majewski
2020-02-14 16:31 ` [PATCH v3 2/8] time: Add a timeval with a 32-bit tv_sec and tv_usec Alistair Francis
2020-02-15 13:57   ` Lukasz Majewski
2020-02-14 16:31 ` [PATCH v3 3/8] time: Add a __itimerval64 struct Alistair Francis
2020-02-14 16:31 ` [PATCH v3 4/8] sysv: Define __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64 Alistair Francis
2020-02-15 14:03   ` Lukasz Majewski
2020-02-14 16:31 ` [PATCH v3 5/8] linux: Use long time_t __getitimer/__setitimer Alistair Francis
2020-02-15 16:26   ` Lukasz Majewski
2020-02-18 18:54     ` Alistair Francis
2020-02-14 16:31 ` [PATCH v3 6/8] resource: Add a __rusage64 struct Alistair Francis
2020-02-14 16:31 ` [PATCH v3 7/8] linux: Use long time_t for wait4/getrusage Alistair Francis
2020-02-15 16:27   ` Lukasz Majewski
2020-02-16 16:30     ` Lukasz Majewski
2020-02-18 23:04     ` Alistair Francis
2020-02-14 16:31 ` [PATCH v3 8/8] sysv/alpha: Use generic __timeval32 and helpers Alistair Francis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).