This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On Fri, 25 Oct 2019 09:08:25 -0300 Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote: > From: Zack Weinberg <zackw@panix.com> > > Use clock_settime to implement settimeofday. > > Changes from previous version: > > - Added a NEWS entry. > > -- > > Unconditionally, on all ports, use clock_settime to implement > settimeofday. Remove sysdeps/unix/clock_settime.c, which implemented > clock_settime by calling settimeofday; new OS ports must henceforth > provide a real implementation of clock_settime. > > Hurd had a real implementation of settimeofday but not of > clock_settime; this patch converts it into an implementation of > clock_settime. It only supports CLOCK_REALTIME and microsecond > resolution; Hurd/Mach does not appear to have any support for > finer-resolution clocks. > > The vestigial "set time zone" feature of settimeofday complicates the > generic settimeofday implementation a little. The only remaining uses > of this feature that aren't just bugs, are using it to inform the > Linux kernel of the offset between the hardware clock and UTC, on > systems where the hardware clock doesn't run in UTC (usually because > of dual-booting with Windows). There currently isn't any other way to > do this. However, the callers that do this call settimeofday with > _only_ the timezone argument non-NULL. Therefore, glibc's new > behavior is: callers of settimeofday must supply one and only one of > the two arguments. If both arguments are non-NULL, or both arguments > are NULL, the call fails and sets errno to EINVAL. > > When only the timeval argument is supplied, settimeofday calls > __clock_settime(CLOCK_REALTIME), same as stime. > > When only the timezone argument is supplied, settimeofday calls a new > internal function called __settimezone. On Linux, only, this function > will pass the timezone structure to the settimeofday system call. On > all other operating systems, and on Linux architectures that don't > define __NR_settimeofday, __settimezone is a stub that always sets > errno to ENOSYS and returns -1. > > The settimeoday syscall is enabled on Linux by the flag > COMPAT_32BIT_TIME, which is an option to either 32-bits ABIs or COMPAT > builds (defined usually by 64-bit kernels that want to support 32-bit > ABIs, such as x86). The idea to future 64-bit time_t only ABIs > is to not provide settimeofday syscall. > > The same semantics are implemented for Linux/Alpha's GLIBC_2.0 compat > symbol for settimeofday. > > There are no longer any internal callers of __settimeofday, so the > internal prototype is removed. > > Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu, > powerpc64-linux-gnu, powerpc-linux-gnu, and aarch64-linux-gnu. > > Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > --- > NEWS | 24 +++++++++ > include/sys/time.h | 3 +- > sysdeps/{unix => mach/hurd}/clock_settime.c | 51 > ++++++++----------- sysdeps/unix/syscalls.list | > 1 - .../unix/sysv/linux/alpha/osf_settimeofday.c | 16 ++++-- > sysdeps/unix/sysv/linux/alpha/settimeofday.c | 22 ++++++++ > sysdeps/unix/sysv/linux/alpha/syscalls.list | 1 - > sysdeps/unix/sysv/linux/settimezone.c | 36 +++++++++++++ > time/Makefile | 8 +-- > time/settimeofday.c | 24 +++++++-- > .../hurd/settimeofday.c => time/settimezone.c | 34 ++----------- > 11 files changed, 147 insertions(+), 73 deletions(-) > rename sysdeps/{unix => mach/hurd}/clock_settime.c (65%) > create mode 100644 sysdeps/unix/sysv/linux/alpha/settimeofday.c > create mode 100644 sysdeps/unix/sysv/linux/settimezone.c > rename sysdeps/mach/hurd/settimeofday.c => time/settimezone.c (52%) > > diff --git a/NEWS b/NEWS > index 8727b5e7f0..0b1476e745 100644 > --- a/NEWS > +++ b/NEWS > @@ -34,6 +34,30 @@ Deprecated and removed features, and other changes > affecting compatibility: binaries and it has been removed from > <time.h> header. This function has been deprecated in favor of > clock_settime. > +* The settimeofday function can still be used to set a system-wide > time > + zone when the operating system supports it. This is because the > Linux > + kernel reused the API, on some architectures, to describe a > system-wide > + time-zone-like offset between the software clock maintained by the > kernel, > + and the “RTC” clock that keeps time when the system is shut down. > + > + However, to reduce the odds of this offset being set by accident, > + settimeofday can no longer be used to set the time and the offset > + simultaneously. If both of its two arguments are non-null, the > call > + will fail (setting errno to EINVAL). > + > + Callers attempting to set this offset should also be prepared for > the call > + to fail and set errno to ENOSYS; this already happens on the Hurd > and on > + some Linux architectures. The Linux kernel maintainers are > discussing a > + more principled replacement for the reused API. After a > replacement > + becomes available, we will change settimeofday to fail with ENOSYS > on all > + platforms when its ‘tzp’ argument is not a null pointer. > + > + Note that settimeofday itself is obsolescent according to POSIX. > + Programs that set the system time should use clock_settime and/or > + the adjtime family of functions instead. We may also cease to make > + settimeofday available to newly linked binaries after there is a > + replacement for Linux’s time-zone-like offset API. > + > Changes to build and runtime requirements: > > [Add changes to build and runtime requirements here] > diff --git a/include/sys/time.h b/include/sys/time.h > index 57208afa82..c0e30e70fb 100644 > --- a/include/sys/time.h > +++ b/include/sys/time.h > @@ -24,8 +24,7 @@ extern int __gettimeofday (struct timeval *__tv, > struct timezone *__tz); > libc_hidden_proto (__gettimeofday) > libc_hidden_proto (gettimeofday) > -extern int __settimeofday (const struct timeval *__tv, > - const struct timezone *__tz) > +extern int __settimezone (const struct timezone *__tz) > attribute_hidden; > extern int __adjtime (const struct timeval *__delta, > struct timeval *__olddelta); > diff --git a/sysdeps/unix/clock_settime.c > b/sysdeps/mach/hurd/clock_settime.c similarity index 65% > rename from sysdeps/unix/clock_settime.c > rename to sysdeps/mach/hurd/clock_settime.c > index 18d7c99864..02239c097a 100644 > --- a/sysdeps/unix/clock_settime.c > +++ b/sysdeps/mach/hurd/clock_settime.c > @@ -1,4 +1,4 @@ > -/* Copyright (C) 1999-2019 Free Software Foundation, Inc. > +/* Copyright (C) 1991-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 > @@ -17,38 +17,31 @@ > > #include <errno.h> > #include <time.h> > -#include <sys/time.h> > +#include <hurd.h> > +#include <hurd/port.h> > #include <shlib-compat.h> > > -/* Set CLOCK to value TP. */ > +/* Set the current time of day. > + This call is restricted to the super-user. */ > int > -__clock_settime (clockid_t clock_id, const struct timespec *tp) > +__clock_settime (clockid_t clock_id, const struct timespec *ts) > { > - int retval = -1; > - > - /* Make sure the time cvalue is OK. */ > - if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000) > - { > - __set_errno (EINVAL); > - return -1; > - } > - > - switch (clock_id) > - { > - case CLOCK_REALTIME: > - { > - struct timeval tv; > - TIMESPEC_TO_TIMEVAL (&tv, tp); > - retval = __settimeofday (&tv, NULL); > - } > - break; > - > - default: > - __set_errno (EINVAL); > - break; > - } > - > - return retval; > + error_t err; > + mach_port_t hostpriv; > + time_value_t tv; > + > + if (clock_id != CLOCK_REALTIME) > + return __hurd_fail (EINVAL); > + > + err = __get_privileged_ports (&hostpriv, NULL); > + if (err) > + return __hurd_fail (EPERM); > + > + TIMESPEC_TO_TIME_VALUE (&tv, ts); > + err = __host_set_time (hostpriv, tv); > + __mach_port_deallocate (__mach_task_self (), hostpriv); > + > + return __hurd_fail (err); > } > libc_hidden_def (__clock_settime) > > diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list > index 61e5360b4d..5fedd5733d 100644 > --- a/sysdeps/unix/syscalls.list > +++ b/sysdeps/unix/syscalls.list > @@ -76,7 +76,6 @@ setreuid - setreuid > i:ii __setreuid setreuid setrlimit - > setrlimit i:ip __setrlimit setrlimit setsid > - setsid i: __setsid > setsid setsockopt - setsockopt i:iiibn > setsockopt __setsockopt -settimeofday - > settimeofday i:PP __settimeofday settimeofday > setuid - setuid i:i > __setuid setuid shutdown - shutdown > i:ii shutdown sigaction - sigaction > i:ipp __sigaction sigaction diff --git > a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c > b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c index > fb2a36df19..914f5ac57b 100644 --- > a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c +++ > b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c @@ -32,9 +32,19 @@ > attribute_compat_text_section __settimeofday_tv32 (const struct > timeval32 *tv32, const struct timezone *tz) { > - struct timeval tv; > - tv32_to_tv64 (&tv, tv32); > - return __settimeofday (&tv, tz); > + if (__glibc_unlikely (tz != 0)) > + { > + if (tv32 != 0) > + { > + __set_errno (EINVAL); > + return -1; > + } > + return __settimezone (tz); > + } > + > + struct timespec ts; > + tv32_to_ts64 (&ts, tv32); This can be replaced with valid_timeval_to_timespec64() from include/time.h > + return __clock_settime (CLOCK_REALTIME, &ts); > } > > compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0); > diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c > b/sysdeps/unix/sysv/linux/alpha/settimeofday.c new file mode 100644 > index 0000000000..36a6901e4e > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/alpha/settimeofday.c > @@ -0,0 +1,22 @@ > +/* settimeofday -- Set the current time of day. Linux/Alpha/tv64 > 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 > + <http://www.gnu.org/licenses/>. */ > + > +/* We can use the generic implementation, but we have to override its > + default symbol version. */ > +#define VERSION_settimeofday GLIBC_2.1 > +#include <time/settimeofday.c> > diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list > b/sysdeps/unix/sysv/linux/alpha/syscalls.list index > c786aa751e..95a27e18e8 100644 --- > a/sysdeps/unix/sysv/linux/alpha/syscalls.list +++ > b/sysdeps/unix/sysv/linux/alpha/syscalls.list @@ -24,7 +24,6 @@ > pciconfig_iobase EXTRA pciconfig_iobase 3 > __pciconfig_iobase pciconfig_iobase # timeval64 entry points (see > osf_*.c for GLIBC_2.0 timeval32 equivalents) gettimeofday > - gettimeofday i:pP __GI___gettimeofday > gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1 > -settimeofday - settimeofday i:PP > __settimeofday settimeofday@@GLIBC_2.1 getitimer > - getitimer i:ip __getitimer > getitimer@@GLIBC_2.1 setitimer - setitimer > i:ipP __setitimer setitimer@@GLIBC_2.1 utimes > - utimes i:sp __utimes > utimes@@GLIBC_2.1 diff --git a/sysdeps/unix/sysv/linux/settimezone.c > b/sysdeps/unix/sysv/linux/settimezone.c new file mode 100644 index > 0000000000..90b38307c6 --- /dev/null +++ > b/sysdeps/unix/sysv/linux/settimezone.c @@ -0,0 +1,36 @@ +/* Obsolete > set system time. Linux 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 > + <http://www.gnu.org/licenses/>. */ > + > +#include <errno.h> > +#include <sys/time.h> > +#include <sysdep.h> > + > +/* Set the system-wide timezone. > + This call is restricted to the super-user. > + This operation is considered obsolete, kernel support may not be > + available on all architectures. */ > +int > +__settimezone (const struct timezone *tz) > +{ > +#ifdef __NR_settimeofday > + return INLINE_SYSCALL_CALL (settimeofday, NULL, tz); > +#else > + __set_errno (ENOSYS); > + return -1 > +#endif > +} > diff --git a/time/Makefile b/time/Makefile > index ad8844ea34..6de4e418d9 100644 > --- a/time/Makefile > +++ b/time/Makefile > @@ -31,13 +31,13 @@ headers := time.h sys/time.h sys/timeb.h > bits/time.h \ > routines := offtime asctime clock ctime ctime_r difftime \ > gmtime localtime mktime time \ > - gettimeofday settimeofday adjtime tzset \ > - tzfile getitimer setitimer \ > + gettimeofday settimeofday settimezone \ > + adjtime tzset tzfile getitimer setitimer \ > stime dysize timegm ftime \ > getdate strptime strptime_l \ > strftime wcsftime strftime_l wcsftime_l \ > - timespec_get \ > - clock_getcpuclockid clock_getres \ > + timespec_get \ > + clock_getcpuclockid clock_getres \ > clock_gettime clock_settime clock_nanosleep > > aux := era alt_digit lc-time-cleanup > diff --git a/time/settimeofday.c b/time/settimeofday.c > index 6aa4832d65..ad57ad41a1 100644 > --- a/time/settimeofday.c > +++ b/time/settimeofday.c > @@ -16,6 +16,7 @@ > <https://www.gnu.org/licenses/>. */ > > #include <errno.h> > +#include <time.h> > #include <sys/time.h> > > /* Set the current time of day and timezone information. > @@ -23,9 +24,24 @@ > int > __settimeofday (const struct timeval *tv, const struct timezone *tz) > { > - __set_errno (ENOSYS); > - return -1; > + if (__glibc_unlikely (tz != 0)) > + { > + if (tv != 0) > + { > + __set_errno (EINVAL); > + return -1; > + } > + return __settimezone (tz); > + } > + > + struct timespec ts; > + TIMEVAL_TO_TIMESPEC (tv, &ts); > + return __clock_settime (CLOCK_REALTIME, &ts); > } > -stub_warning (settimeofday) > > -weak_alias (__settimeofday, settimeofday) > +#ifdef VERSION_settimeofday > +weak_alias (__settimeofday, __settimeofday_w); > +default_symbol_version (__settimeofday_w, settimeofday, > VERSION_settimeofday); +#else > +weak_alias (__settimeofday, settimeofday); > +#endif > diff --git a/sysdeps/mach/hurd/settimeofday.c b/time/settimezone.c > similarity index 52% > rename from sysdeps/mach/hurd/settimeofday.c > rename to time/settimezone.c > index 31bffcad9d..b9969c9dd5 100644 > --- a/sysdeps/mach/hurd/settimeofday.c > +++ b/time/settimezone.c > @@ -1,4 +1,4 @@ > -/* Copyright (C) 1991-2019 Free Software Foundation, Inc. > +/* 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 > @@ -17,36 +17,12 @@ > > #include <errno.h> > #include <sys/time.h> > -#include <hurd.h> > -#include <hurd/port.h> > > -/* Set the current time of day and timezone information. > +/* Set the system-wide timezone. > This call is restricted to the super-user. */ > int > -__settimeofday (const struct timeval *tv, const struct timezone *tz) > +__settimezone (const struct timezone *tz) > { > - error_t err; > - mach_port_t hostpriv; > - > - if (tz != NULL) > - { > - errno = ENOSYS; > - return -1; > - } > - > - err = __get_privileged_ports (&hostpriv, NULL); > - if (err) > - return __hurd_fail (EPERM); > - > - /* `time_value_t' and `struct timeval' are in fact identical with > the > - names changed. */ > - err = __host_set_time (hostpriv, *(time_value_t *) tv); > - __mach_port_deallocate (__mach_task_self (), hostpriv); > - > - if (err) > - return __hurd_fail (err); > - > - return 0; > + __set_errno (ENOSYS); > + return -1; > } > - > -weak_alias (__settimeofday, settimeofday) Reviewed-by: Lukasz Majewski <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
Attachment:
pgpoVA5UOUUe7.pgp
Description: OpenPGP digital signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |