From patchwork Tue Aug 20 13:21:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Zack Weinberg X-Patchwork-Id: 34192 Received: (qmail 9685 invoked by alias); 20 Aug 2019 13:37:03 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 9605 invoked by uid 89); 20 Aug 2019 13:37:03 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.1 spammy=aid, formerly X-HELO: l2mail1.panix.com From: Zack Weinberg To: libc-alpha@sourceware.org Cc: Joseph Myers , Florian Weimer , Lukasz Majewski , Alistair Francis , Stepan Golosunov , Arnd Bergmann Subject: [PATCH 11/12] =?UTF-8?q?Linux/Alpha:=20don=E2=80=99t=20use=20time?= =?UTF-8?q?val32=20system=20calls.?= Date: Tue, 20 Aug 2019 09:21:51 -0400 Message-Id: <20190820132152.24100-12-zackw@panix.com> In-Reply-To: <20190820132152.24100-1-zackw@panix.com> References: <20190820132152.24100-1-zackw@panix.com> MIME-Version: 1.0 Linux/Alpha has two versions of several system call wrappers that take or return data of type ‘struct timeval’ (possibly nested inside a larger structure). The GLIBC_2.0 version is a compat symbol that calls __NR_osf_foo or __NR_old_foo and uses a struct timeval with a 32-bit tv_sec field. The GLIBC_2.1 version is used for current code, calls __NR_foo, and uses a struct timeval with a 64-bit tv_sec field. This patch changes all of the remaining compat symbols of this type to be wrappers around their GLIBC_2.1 counterparts. (gettimeofday already received this treatment in an earlier patch in this series.) The compat symbols that copy out a 32-bit struct timeval all check for overflow. After the Y2038 deadline, they will fail with errno set to EOVERFLOW, but only after copying out as much as they can, and filling in the overflowed ‘struct timeval’(s) with tv_sec set to INT32_MAX and tv_nsec set to zero. The new header file tv32-compat.h is currently Alpha-specific but I don’t know any reason why it couldn’t be reused to aid in writing wrappers for all affected architectures. * sysdeps/unix/sysv/linux/alpha/tv32-compat.h: New file declaring types and helper functions for 32/64-bit time_t conversion. * sysdeps/unix/sysv/linux/alpha/syscalls.list: Remove entries for osf_getitimer, osf_setitimer, osf_utimes, osf_getrusage, and osf_wait4. * sysdeps/unix/sysv/linux/alpha/osf_getitimer.c * sysdeps/unix/sysv/linux/alpha/osf_getrusage.c * sysdeps/unix/sysv/linux/alpha/osf_setitimer.c * sysdeps/unix/sysv/linux/alpha/osf_utimes.c * sysdeps/unix/sysv/linux/alpha/osf_wait4.c: New files defining compatibility symbols formerly defined by alpha/syscalls.list. * sysdeps/unix/sysv/linux/alpha/adjtime.c: Split the compat code to... * sysdeps/unix/sysv/linux/alpha/osf_adjtime.c: ...this new file. * sysdeps/unix/sysv/linux/alpha/Makefile (sysdep_routines): Add osf_adjtime. * sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c * sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c: Use tv32-compat.h helpers. --- sysdeps/unix/sysv/linux/alpha/Makefile | 2 +- sysdeps/unix/sysv/linux/alpha/adjtime.c | 70 +------- sysdeps/unix/sysv/linux/alpha/osf_adjtime.c | 135 ++++++++++++++++ sysdeps/unix/sysv/linux/alpha/osf_getitimer.c | 48 ++++++ sysdeps/unix/sysv/linux/alpha/osf_getrusage.c | 44 +++++ .../unix/sysv/linux/alpha/osf_gettimeofday.c | 27 +--- sysdeps/unix/sysv/linux/alpha/osf_setitimer.c | 55 +++++++ .../unix/sysv/linux/alpha/osf_settimeofday.c | 12 +- sysdeps/unix/sysv/linux/alpha/osf_utimes.c | 36 +++++ sysdeps/unix/sysv/linux/alpha/osf_wait4.c | 47 ++++++ sysdeps/unix/sysv/linux/alpha/syscalls.list | 9 +- sysdeps/unix/sysv/linux/alpha/tv32-compat.h | 151 ++++++++++++++++++ 12 files changed, 536 insertions(+), 100 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_adjtime.c create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_getitimer.c create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_getrusage.c create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_setitimer.c create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_utimes.c create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_wait4.c create mode 100644 sysdeps/unix/sysv/linux/alpha/tv32-compat.h diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile index fdd089af71..2e132e474b 100644 --- a/sysdeps/unix/sysv/linux/alpha/Makefile +++ b/sysdeps/unix/sysv/linux/alpha/Makefile @@ -9,7 +9,7 @@ sysdep_routines += ieee_get_fp_control ieee_set_fp_control \ ioperm # Support old timeval32 entry points -sysdep_routines += osf_gettimeofday osf_settimeofday \ +sysdep_routines += osf_adjtime osf_gettimeofday osf_settimeofday \ osf_getitimer osf_setitimer osf_utimes \ osf_getrusage osf_wait4 diff --git a/sysdeps/unix/sysv/linux/alpha/adjtime.c b/sysdeps/unix/sysv/linux/alpha/adjtime.c index 65641e9c4d..f67f522300 100644 --- a/sysdeps/unix/sysv/linux/alpha/adjtime.c +++ b/sysdeps/unix/sysv/linux/alpha/adjtime.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1998-2019 Free Software Foundation, Inc. +/* adjtime -- adjust the system clock. Linux/Alpha/tv64 version. + Copyright (C) 1998-2019 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 @@ -15,76 +16,19 @@ License along with the GNU C Library. If not, see . */ -#include #include #include +#include - -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -struct timeval32 -{ - int tv_sec, tv_usec; -}; - -struct timex32 { - unsigned int modes; /* mode selector */ - long offset; /* time offset (usec) */ - long freq; /* frequency offset (scaled ppm) */ - long maxerror; /* maximum error (usec) */ - long esterror; /* estimated error (usec) */ - int status; /* clock command/status */ - long constant; /* pll time constant */ - long precision; /* clock precision (usec) (read only) */ - long tolerance; /* clock frequency tolerance (ppm) - * (read only) - */ - struct timeval32 time; /* (read only) */ - long tick; /* (modified) usecs between clock ticks */ - - long ppsfreq; /* pps frequency (scaled ppm) (ro) */ - long jitter; /* pps jitter (us) (ro) */ - int shift; /* interval duration (s) (shift) (ro) */ - long stabil; /* pps stability (scaled ppm) (ro) */ - long jitcnt; /* jitter limit exceeded (ro) */ - long calcnt; /* calibration intervals (ro) */ - long errcnt; /* calibration errors (ro) */ - long stbcnt; /* stability limit exceeded (ro) */ - - int :32; int :32; int :32; int :32; - int :32; int :32; int :32; int :32; - int :32; int :32; int :32; int :32; -}; - -#define TIMEVAL timeval32 -#define TIMEX timex32 -#define ADJTIME attribute_compat_text_section __adjtime_tv32 -#define ADJTIMEX(x) INLINE_SYSCALL (old_adjtimex, 1, x) -#define ADJTIMEX32(x) INLINE_SYSCALL (old_adjtimex, 1, x) - -#include - -int attribute_compat_text_section -__adjtimex_tv32 (struct timex32 *tx) { return ADJTIMEX (tx); } - -strong_alias (__adjtimex_tv32, __adjtimex_tv32_1); -strong_alias (__adjtimex_tv32, __adjtimex_tv32_2); -compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0); -compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0); -compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0); -#endif /* SHLIB_COMPAT */ - -#undef TIMEVAL -#undef TIMEX -#undef ADJTIME -#undef ADJTIMEX -#define TIMEVAL timeval -#define TIMEX timex #define ADJTIMEX(x) INLINE_SYSCALL (adjtimex, 1, x) #include int -__adjtimex_tv64 (struct timex *tx) { return ADJTIMEX (tx); } +__adjtimex_tv64 (struct timex *tx) +{ + return ADJTIMEX (tx); +} libc_hidden_ver (__adjtimex_tv64, __adjtimex) strong_alias (__adjtimex_tv64, __adjtimex_tv64p); diff --git a/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c new file mode 100644 index 0000000000..57c77c3072 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/osf_adjtime.c @@ -0,0 +1,135 @@ +/* adjtime -- adjust the system clock. Linux/Alpha/tv32 version. + Copyright (C) 2019 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 + . */ + +#include +#include +#include + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#include +#include + +struct timex32 { + unsigned int modes; /* mode selector */ + long offset; /* time offset (usec) */ + long freq; /* frequency offset (scaled ppm) */ + long maxerror; /* maximum error (usec) */ + long esterror; /* estimated error (usec) */ + int status; /* clock command/status */ + long constant; /* pll time constant */ + long precision; /* clock precision (usec) (read only) */ + long tolerance; /* clock frequency tolerance (ppm) + * (read only) + */ + struct timeval32 time; /* (read only) */ + long tick; /* (modified) usecs between clock ticks */ + + long ppsfreq; /* pps frequency (scaled ppm) (ro) */ + long jitter; /* pps jitter (us) (ro) */ + int shift; /* interval duration (s) (shift) (ro) */ + long stabil; /* pps stability (scaled ppm) (ro) */ + long jitcnt; /* jitter limit exceeded (ro) */ + long calcnt; /* calibration intervals (ro) */ + long errcnt; /* calibration errors (ro) */ + long stbcnt; /* stability limit exceeded (ro) */ + + int :32; int :32; int :32; int :32; + int :32; int :32; int :32; int :32; + int :32; int :32; int :32; int :32; +}; + +int attribute_compat_text_section +__adjtime_tv32 (const struct timeval32 *itv, struct timeval32 *otv) +{ + struct timeval itv64, otv64; + TV32_TO_TV64 (&itv64, itv); + if (__adjtime (&itv64, &otv64)) + return -1; + if (TV64_TO_TV32 (otv, &itv64)) + { + __set_errno (EOVERFLOW); + return -1; + } + return 0; +} + +int attribute_compat_text_section +__adjtimex_tv32 (struct timex32 *tx) +{ + struct timex tx64; + memset (&tx64, 0, sizeof tx64); + tx64.modes = tx->modes; + tx64.offset = tx->offset; + tx64.freq = tx->freq; + tx64.maxerror = tx->maxerror; + tx64.esterror = tx->esterror; + tx64.status = tx->status; + tx64.constant = tx->constant; + tx64.precision = tx->precision; + tx64.tolerance = tx->tolerance; + tx64.tick = tx->tick; + tx64.ppsfreq = tx->ppsfreq; + tx64.jitter = tx->jitter; + tx64.shift = tx->shift; + tx64.stabil = tx->stabil; + tx64.jitcnt = tx->jitcnt; + tx64.calcnt = tx->calcnt; + tx64.errcnt = tx->errcnt; + tx64.stbcnt = tx->stbcnt; + TV32_TO_TV64 (&tx64.time, &tx->time); + + int status = __adjtimex (&tx64); + if (status < 0) + return status; + + memset (tx, 0, sizeof *tx); + tx->modes = tx64.modes; + tx->offset = tx64.offset; + tx->freq = tx64.freq; + tx->maxerror = tx64.maxerror; + tx->esterror = tx64.esterror; + tx->status = tx64.status; + tx->constant = tx64.constant; + tx->precision = tx64.precision; + tx->tolerance = tx64.tolerance; + tx->tick = tx64.tick; + tx->ppsfreq = tx64.ppsfreq; + tx->jitter = tx64.jitter; + tx->shift = tx64.shift; + tx->stabil = tx64.stabil; + tx->jitcnt = tx64.jitcnt; + tx->calcnt = tx64.calcnt; + tx->errcnt = tx64.errcnt; + tx->stbcnt = tx64.stbcnt; + if (TV64_TO_TV32 (&tx->time, &tx64.time)) + { + __set_errno (EOVERFLOW); + return -1; + } + + return status; +} + +strong_alias (__adjtimex_tv32, __adjtimex_tv32_1); +strong_alias (__adjtimex_tv32, __adjtimex_tv32_2); +compat_symbol (libc, __adjtimex_tv32_1, __adjtimex, GLIBC_2_0); +compat_symbol (libc, __adjtimex_tv32_2, adjtimex, GLIBC_2_0); +compat_symbol (libc, __adjtime_tv32, adjtime, GLIBC_2_0); + +#endif /* SHLIB_COMPAT */ diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c new file mode 100644 index 0000000000..d15d8f5be4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/osf_getitimer.c @@ -0,0 +1,48 @@ +/* getitimer -- Get the state of an interval timer. Linux/Alpha/tv32 version. + Copyright (C) 2019 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 + . */ + +#include +#include + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#include +#include + +int +__getitimer_tv32 (int which, struct itimerval32 *curr_value) +{ + struct itimerval curr_value_64; + if (__getitimer (which, &curr_value_64)) + return -1; + + /* Make sure both fields of the output are filled in, even if one of them + overflows. */ + int e; + e = TV64_TO_TV32 (&curr_value->it_interval, &curr_value_64.it_interval); + e |= TV64_TO_TV32 (&curr_value->it_value, &curr_value_64.it_value); + if (e) + { + __set_errno (EOVERFLOW); + return -1; + } + return 0; +} + +compat_symbol (libc, __getitimer_tv32, getitimer, GLIBC_2_0); +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c new file mode 100644 index 0000000000..ac094dddbf --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/osf_getrusage.c @@ -0,0 +1,44 @@ +/* utimes -- change file timestamps. Linux/Alpha/tv32 version. + Copyright (C) 2019 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 + . */ + +#include +#include +#include + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#include +#include + +int +__getrusage_tv32 (int who, struct rusage32 *usage32) +{ + struct rusage usage64; + if (__getrusage (who, &usage64)) + return -1; + + if (RUSAGE64_TO_RUSAGE32 (usage32, &usage64)) + { + __set_errno (EOVERFLOW); + return -1; + } + return 0; +} + +compat_symbol (libc, __getrusage_tv32, getrusage, GLIBC_2_0); +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c index 9868dfd9c9..cc4c4eebdf 100644 --- a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c +++ b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c @@ -16,19 +16,15 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include -#include #include #include #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -struct timeval32 -{ - int tv_sec, tv_usec; -}; +#include +#include +#include +#include /* Get the current time of day, putting it into *TV. If *TZ is not NULL, clear it. @@ -36,29 +32,20 @@ struct timeval32 int attribute_compat_text_section -__gettimeofday_tv32 (struct timeval32 *tv32, - struct timezone *tz) +__gettimeofday_tv32 (struct timeval32 *restrict tv32, void *restrict tz) { if (__glibc_unlikely (tz != 0)) - memset (tz, 0, sizeof *tz); + memset (tz, 0, sizeof (struct timezone)); struct timespec ts; if (__clock_gettime (CLOCK_REALTIME, &ts)) return -1; - if (__glibc_unlikely (ts.tv_sec > (time_t)INT_MAX)) + if (TS64_TO_TV32 (tv32, &ts)) { - /* The clock has advanced past the time representable in a 32-bit - time_t. Fail, but write a saturated value to the output first, - because callers don't typically expect gettimeofday to fail. */ __set_errno (EOVERFLOW); - tv32->tv_sec = INT_MAX; - tv32->tv_usec = 0; return -1; } - - tv32->tv_sec = ts.tv_sec; - tv32->tv_usec = ts.tv_nsec / 1000; return 0; } diff --git a/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c new file mode 100644 index 0000000000..48d5bbcd75 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/osf_setitimer.c @@ -0,0 +1,55 @@ +/* getitimer -- Get the state of an interval timer. Linux/Alpha/tv32 version. + Copyright (C) 2019 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 + . */ + +#include +#include + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#include +#include + +int +__setitimer_tv32 (int which, const struct itimerval32 *restrict new_value, + struct itimerval32 *restrict old_value) +{ + struct itimerval new_value_64; + TV32_TO_TV64 (&new_value_64.it_interval, &new_value->it_interval); + TV32_TO_TV64 (&new_value_64.it_value, &new_value->it_value); + + if (!old_value) + return __setitimer (which, &new_value_64, 0); + + struct itimerval old_value_64; + if (__setitimer (which, &new_value_64, &old_value_64)) + return -1; + + /* Write all fields of 'old_value' even on error. */ + int e = 0; + e |= TV64_TO_TV32 (&old_value->it_interval, &old_value_64.it_interval); + e |= TV64_TO_TV32 (&old_value->it_value, &old_value_64.it_value); + if (e) + { + __set_errno (EOVERFLOW); + return -1; + } + return 0; +} + +compat_symbol (libc, __setitimer_tv32, setitimer, GLIBC_2_0); +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c index a61fcab482..d793b24dbf 100644 --- a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c +++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c @@ -16,17 +16,14 @@ License along with the GNU C Library; if not, see . */ -#include -#include #include #include #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -struct timeval32 -{ - int tv_sec, tv_usec; -}; +#include +#include +#include /* Set the current time of day and timezone information. This call is restricted to the super-user. */ @@ -46,8 +43,7 @@ __settimeofday_tv32 (const struct timeval32 *tv32, } struct timespec ts; - ts.tv_sec = tv32->tv_sec; - ts.tv_nsec = tv32->tv_usec * 1000; + TV32_TO_TS64 (&ts, 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 new file mode 100644 index 0000000000..7ed483ffb8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/osf_utimes.c @@ -0,0 +1,36 @@ +/* utimes -- change file timestamps. Linux/Alpha/tv32 version. + Copyright (C) 2019 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 + . */ + +#include +#include + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#include + +int +__utimes_tv32 (const char *filename, const struct timeval32 times32[2]) +{ + struct timeval times[2]; + TV32_TO_TV64 (×[0], ×32[0]); + TV32_TO_TV64 (×[1], ×32[1]); + return __utimes (filename, times); +} + +compat_symbol (libc, __utimes_tv32, utimes, GLIBC_2_0); +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/osf_wait4.c b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c new file mode 100644 index 0000000000..6ad3f1d510 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/osf_wait4.c @@ -0,0 +1,47 @@ +/* wait4 -- wait for process to change state. Linux/Alpha/tv32 version. + Copyright (C) 2019 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 + . */ + +#include +#include +#include +#include + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#include +#include +#include + +pid_t +__wait4_tv32 (pid_t pid, int *status, int options, struct rusage32 *usage32) +{ + struct rusage usage64; + pid_t child = __wait4 (pid, status, options, &usage64); + if (child < 0) + return child; + + if (RUSAGE64_TO_RUSAGE32 (usage32, &usage64)) + { + __set_errno (EOVERFLOW); + return -1; + } + return child; +} + +compat_symbol (libc, __wait4_tv32, wait4, GLIBC_2_0); +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list index 9ceed78c8d..0e472b4542 100644 --- a/sysdeps/unix/sysv/linux/alpha/syscalls.list +++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list @@ -22,14 +22,7 @@ pciconfig_read EXTRA pciconfig_read 5 pciconfig_read pciconfig_write EXTRA pciconfig_write 5 pciconfig_write pciconfig_iobase EXTRA pciconfig_iobase 3 __pciconfig_iobase pciconfig_iobase -# support old timeval32 entry points -osf_getitimer - osf_getitimer 2 __getitimer_tv32 getitimer@GLIBC_2.0 -osf_setitimer - osf_setitimer 3 __setitimer_tv32 setitimer@GLIBC_2.0 -osf_utimes - osf_utimes 2 __utimes_tv32 utimes@GLIBC_2.0 -osf_getrusage - osf_getrusage 2 __getrusage_tv32 getrusage@GLIBC_2.0 -osf_wait4 - osf_wait4 4 __wait4_tv32 wait4@GLIBC_2.0 - -# support new timeval64 entry points +# new timeval64 entry points (see osf_* for the GLIBC_2.0 versions) getitimer - getitimer 2 __getitimer getitimer@@GLIBC_2.1 setitimer - setitimer 3 __setitimer setitimer@@GLIBC_2.1 utimes - utimes 2 __utimes utimes@@GLIBC_2.1 diff --git a/sysdeps/unix/sysv/linux/alpha/tv32-compat.h b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h new file mode 100644 index 0000000000..926e8ce017 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/tv32-compat.h @@ -0,0 +1,151 @@ +/* Compatibility definitions for `struct timeval' with 32-bit time_t. + Copyright (C) 2019 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 + . */ + +#ifndef _TV32_COMPAT_H +#define _TV32_COMPAT_H 1 + +#include + +#include +#include +#include +#include +#include + +#include // for INT32_MAX +#include // for memset + +/* 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, 0 } to the output and return -1; + otherwise they return 0. */ + +__extern_always_inline void +TV32_TO_TV64 (struct timeval *restrict tv64, + const struct timeval32 *restrict tv32) +{ + tv64->tv_sec = tv32->tv_sec; + tv64->tv_usec = tv32->tv_usec; +} + +__extern_always_inline void +TV32_TO_TS64 (struct timespec *restrict ts64, + const struct timeval32 *restrict tv32) +{ + ts64->tv_sec = tv32->tv_sec; + ts64->tv_nsec = tv32->tv_usec * 1000; +} + +__extern_always_inline int +TV64_TO_TV32 (struct timeval32 *restrict tv32, + const struct timeval *restrict tv64) +{ + if (__glibc_unlikely (tv64->tv_sec > (time_t) INT32_MAX)) + { + tv32->tv_sec = INT32_MAX; + tv32->tv_usec = 0; + return -1; + } + else + { + tv32->tv_sec = tv64->tv_sec; + tv32->tv_usec = tv64->tv_usec; + return 0; + } +} + +__extern_always_inline int +TS64_TO_TV32 (struct timeval32 *restrict tv32, + const struct timespec *restrict ts64) +{ + if (__glibc_unlikely (ts64->tv_sec > (time_t) INT32_MAX)) + { + tv32->tv_sec = INT32_MAX; + tv32->tv_usec = 0; + return -1; + } + else + { + tv32->tv_sec = ts64->tv_sec; + tv32->tv_usec = ts64->tv_nsec / 1000; + return 0; + } +} + +__extern_always_inline int +RUSAGE64_TO_RUSAGE32 (struct rusage32 *restrict r32, + const struct rusage *restrict r64) +{ + /* Fill out the entire structure even on failure. */ + memset (r32, 0, sizeof *r32); + + int e = 0; + e |= TV64_TO_TV32 (&r32->ru_utime, &r64->ru_utime); + e |= TV64_TO_TV32 (&r32->ru_stime, &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; + + return e; +} + +#endif /* tv32-compat.h */