public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/zack/y2038-preliminaries] Use clock_settime to implement settimeofday.
@ 2019-08-20 12:07 Zack Weinberg
  0 siblings, 0 replies; 7+ messages in thread
From: Zack Weinberg @ 2019-08-20 12:07 UTC (permalink / raw)
  To: glibc-cvs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii", Size: 13578 bytes --]

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=f66ff8e42db3f23324c9d214c06cde468b3382b2

commit f66ff8e42db3f23324c9d214c06cde468b3382b2
Author: Zack Weinberg <zackw@panix.com>
Date:   Fri Aug 16 16:21:13 2019 -0400

    Use clock_settime to implement settimeofday.
    
    Unconditionally, on all ports, use clock_settime to implement
    settimeofday.  This is a little different from using clock_settime to
    implement stime, because the vestigial “set time zone” feature of
    settimeofday complicates matters.
    
    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).  They 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.
    
    Another complication is that the alpha-linux-gnu configuration has two
    versions of settimeofday, GLIBC_2.0 and GLIBC_2.1, with the older
    symbol using 32-bit time_t (yes, really).  The older symbol is
    reimplemented from scratch (with the same semantics); the newer symbol
    uses the generic implementation with some #ifdeffage to get the
    versioning right.  Henceforth, __NR_osf_settimeofday will never be
    used, and __NR_settimeofday only for the timezone feature.
    
    There are no longer any internal callers of __settimeofday, so the
    internal prototype is removed.
    
    	* time/settimeofday.c (settimeofday): No longer a stub
    	implementation.  Call __clock_settime or __settimezone depending
    	on arguments.  Optionally override the default symbol version for
    	settimeofday.
    	* include/sys/time.h: Remove prototype for __settimeofday.
    	Add prototype for __settimezone.
    	* sysdeps/unix/syscalls.list: Remove entry for settimeofday.
    
    	* time/settimezone.c: New file.
    	(__settimezone): New stub implementation.
    	* sysdeps/unix/sysv/linux/settimezone.c: New file.
    	(__settimezone): Implement using settimeofday system call,
    	if available.
    	* time/Makefile (routines): Add settimezone.
    
    	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
    	Remove entries for settimeofday and osf_settimeofday.
    	* sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
    	New file, defines settimeofday@GLIBC_2.0.
    	* sysdeps/unix/sysv/linux/alpha/settimeofday.c:
    	New file, defines settimeofday@@GLIBC_2.1.

Diff:
---
 include/sys/time.h                               |  3 +-
 sysdeps/unix/syscalls.list                       |  1 -
 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c | 55 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/settimeofday.c     | 22 ++++++++++
 sysdeps/unix/sysv/linux/alpha/syscalls.list      |  2 -
 sysdeps/unix/sysv/linux/settimezone.c            | 39 +++++++++++++++++
 time/Makefile                                    |  2 +-
 time/settimeofday.c                              | 24 +++++++++--
 time/settimezone.c                               | 28 ++++++++++++
 9 files changed, 166 insertions(+), 10 deletions(-)

diff --git a/include/sys/time.h b/include/sys/time.h
index 7ba0ca7..a57752e 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/syscalls.list b/sysdeps/unix/syscalls.list
index 61e5360..5fedd57 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
new file mode 100644
index 0000000..a61fcab
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -0,0 +1,55 @@
+/* settimeofday -- Set the current time of day.  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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+struct timeval32
+{
+    int tv_sec, tv_usec;
+};
+
+/* 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,
+                     const struct timezone *tz)
+{
+  if (__glibc_unlikely (tz != 0))
+    {
+      if (tv32 != 0)
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+      return __settimezone (tz);
+    }
+
+  struct timespec ts;
+  ts.tv_sec = tv32->tv_sec;
+  ts.tv_nsec = tv32->tv_usec * 1000;
+  return __clock_settime (CLOCK_REALTIME, &ts);
+}
+
+compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
new file mode 100644
index 0000000..36a6901
--- /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 12cd021..f5a534e 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
 
 # support old timeval32 entry points
 osf_gettimeofday -	osf_gettimeofday 2	__gettimeofday_tv32  __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0
-osf_settimeofday -	osf_settimeofday 2	__settimeofday_tv32  settimeofday@GLIBC_2.0
 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
@@ -33,7 +32,6 @@ osf_wait4	-	osf_wait4	4	__wait4_tv32  wait4@GLIBC_2.0
 
 # support new timeval64 entry points
 gettimeofday	-	gettimeofday	2	__GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
-settimeofday	-	settimeofday	2	__settimeofday settimeofday@@GLIBC_2.1
 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/settimezone.c b/sysdeps/unix/sysv/linux/settimezone.c
new file mode 100644
index 0000000..823f4fe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/settimezone.c
@@ -0,0 +1,39 @@
+/* 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.  */
+
+#ifdef __NR_settimeofday
+
+int
+__settimezone (const struct timezone *tz)
+{
+  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
+}
+
+#else
+
+#include <time/settimezone.c>
+
+#endif
diff --git a/time/Makefile b/time/Makefile
index a428f55..d78bff8 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -36,7 +36,7 @@ routines := offtime asctime clock ctime ctime_r difftime \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
 	    strftime wcsftime strftime_l wcsftime_l	 \
-	    timespec_get
+	    timespec_get settimezone
 aux :=	    era alt_digit lc-time-cleanup
 
 tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
diff --git a/time/settimeofday.c b/time/settimeofday.c
index 4620559..78f666e 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -16,6 +16,7 @@
    <http://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/time/settimezone.c b/time/settimezone.c
new file mode 100644
index 0000000..eb005da
--- /dev/null
+++ b/time/settimezone.c
@@ -0,0 +1,28 @@
+/* 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>
+
+/* Set the system-wide timezone.
+   This call is restricted to the super-user.  */
+int
+__settimezone (const struct timezone *tz)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}


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

* [glibc/zack/y2038-preliminaries] Use clock_settime to implement settimeofday.
@ 2019-08-28 13:04 Zack Weinberg
  0 siblings, 0 replies; 7+ messages in thread
From: Zack Weinberg @ 2019-08-28 13:04 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=36843c029fe57e561abfcc7af81445e404c5671d

commit 36843c029fe57e561abfcc7af81445e404c5671d
Author: Zack Weinberg <zackw@panix.com>
Date:   Wed Aug 28 08:25:49 2019 -0400

    Use clock_settime to implement settimeofday.
    
    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 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.
    
    	* time/settimeofday.c (settimeofday): No longer a stub
    	implementation.  Call __clock_settime or __settimezone depending
    	on arguments.  Optionally override the default symbol version for
    	settimeofday.
    	* include/sys/time.h: Remove prototype for __settimeofday.
    	Add prototype for __settimezone.
    	* sysdeps/unix/syscalls.list: Remove entry for settimeofday.
    
    	* time/settimezone.c: New file.
    	(__settimezone): New stub implementation.
    	* sysdeps/unix/sysv/linux/settimezone.c: New file.
    	(__settimezone): Implement using settimeofday system call,
    	if available.
    	* time/Makefile (routines): Add settimezone.
    
    	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
    	Remove entries for settimeofday and osf_settimeofday.
    	* sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
    	New file, defines settimeofday@GLIBC_2.0.
    	* sysdeps/unix/sysv/linux/alpha/settimeofday.c:
    	New file, defines settimeofday@@GLIBC_2.1.
    
    	* sysdeps/unix/clock_gettime.c: Delete file.
    	* sysdeps/mach/hurd/settimeofday.c: Rename to
    	sysdeps/mach/hurd/clock_settime.c and convert into an
    	implementation of clock_settime.

Diff:
---
 include/sys/time.h                                 |  3 +-
 sysdeps/{unix => mach/hurd}/clock_settime.c        | 51 ++++++++++------------
 sysdeps/unix/syscalls.list                         |  1 -
 sysdeps/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              | 39 +++++++++++++++++
 time/Makefile                                      |  8 ++--
 time/settimeofday.c                                | 24 ++++++++--
 .../mach/hurd/settimeofday.c => time/settimezone.c | 34 +++------------
 10 files changed, 126 insertions(+), 73 deletions(-)

diff --git a/include/sys/time.h b/include/sys/time.h
index 7ba0ca7..a57752e 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 5b39849..0a32f8d 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 61e5360..5fedd57 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 475e0fd..9221deb 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);
+  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 0000000..36a6901
--- /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 c786aa7..95a27e1 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 0000000..823f4fe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/settimezone.c
@@ -0,0 +1,39 @@
+/* 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.  */
+
+#ifdef __NR_settimeofday
+
+int
+__settimezone (const struct timezone *tz)
+{
+  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
+}
+
+#else
+
+#include <time/settimezone.c>
+
+#endif
diff --git a/time/Makefile b/time/Makefile
index 85a62c0..791db1c 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 4620559..78f666e 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -16,6 +16,7 @@
    <http://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 bd0ffd6..eb005da 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)


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

* [glibc/zack/y2038-preliminaries] Use clock_settime to implement settimeofday.
@ 2019-08-22 23:04 Zack Weinberg
  0 siblings, 0 replies; 7+ messages in thread
From: Zack Weinberg @ 2019-08-22 23:04 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=cc1f7d7d359085fb10e3c7d99a3a3f950b4c8c0c

commit cc1f7d7d359085fb10e3c7d99a3a3f950b4c8c0c
Author: Zack Weinberg <zackw@panix.com>
Date:   Fri Aug 16 16:21:13 2019 -0400

    Use clock_settime to implement settimeofday.
    
    Unconditionally, on all ports, use clock_settime to implement
    settimeofday.  This is a little different from using clock_settime to
    implement stime, because the vestigial "set time zone" feature of
    settimeofday complicates matters.
    
    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 same semantics are implemented for Linux/Alpha's GLIBC_2.0 compat
    symbol for gettimeofday.
    
    There are no longer any internal callers of __settimeofday, so the
    internal prototype is removed.
    
    	* time/settimeofday.c (settimeofday): No longer a stub
    	implementation.  Call __clock_settime or __settimezone depending
    	on arguments.  Optionally override the default symbol version for
    	settimeofday.
    	* include/sys/time.h: Remove prototype for __settimeofday.
    	Add prototype for __settimezone.
    	* sysdeps/unix/syscalls.list: Remove entry for settimeofday.
    
    	* time/settimezone.c: New file.
    	(__settimezone): New stub implementation.
    	* sysdeps/unix/sysv/linux/settimezone.c: New file.
    	(__settimezone): Implement using settimeofday system call,
    	if available.
    	* time/Makefile (routines): Add settimezone.
    
    	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
    	Remove entries for settimeofday and osf_settimeofday.
    	* sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
    	New file, defines settimeofday@GLIBC_2.0.
    	* sysdeps/unix/sysv/linux/alpha/settimeofday.c:
    	New file, defines settimeofday@@GLIBC_2.1.

Diff:
---
 include/sys/time.h                               |  3 +-
 sysdeps/unix/syscalls.list                       |  1 -
 sysdeps/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            | 39 ++++++++++++++++++++++++
 time/Makefile                                    |  8 ++---
 time/settimeofday.c                              | 24 ++++++++++++---
 time/settimezone.c                               | 28 +++++++++++++++++
 9 files changed, 127 insertions(+), 15 deletions(-)

diff --git a/include/sys/time.h b/include/sys/time.h
index 7ba0ca7..a57752e 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/syscalls.list b/sysdeps/unix/syscalls.list
index 61e5360..5fedd57 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 406f620..5e9a11c 100644
--- a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -30,9 +30,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);
+  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 0000000..36a6901
--- /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 a4763d3..65dc8b1 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 0000000..823f4fe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/settimezone.c
@@ -0,0 +1,39 @@
+/* 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.  */
+
+#ifdef __NR_settimeofday
+
+int
+__settimezone (const struct timezone *tz)
+{
+  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
+}
+
+#else
+
+#include <time/settimezone.c>
+
+#endif
diff --git a/time/Makefile b/time/Makefile
index 8fa7b52..93c7cc2 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -31,13 +31,13 @@ headers := time.h sys/time.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 4620559..78f666e 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -16,6 +16,7 @@
    <http://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/time/settimezone.c b/time/settimezone.c
new file mode 100644
index 0000000..eb005da
--- /dev/null
+++ b/time/settimezone.c
@@ -0,0 +1,28 @@
+/* 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>
+
+/* Set the system-wide timezone.
+   This call is restricted to the super-user.  */
+int
+__settimezone (const struct timezone *tz)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}


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

* [glibc/zack/y2038-preliminaries] Use clock_settime to implement settimeofday.
@ 2019-08-21 12:28 Zack Weinberg
  0 siblings, 0 replies; 7+ messages in thread
From: Zack Weinberg @ 2019-08-21 12:28 UTC (permalink / raw)
  To: glibc-cvs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii", Size: 13578 bytes --]

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=dc6c34fbdafa4e30a73390b641489921e075abed

commit dc6c34fbdafa4e30a73390b641489921e075abed
Author: Zack Weinberg <zackw@panix.com>
Date:   Fri Aug 16 16:21:13 2019 -0400

    Use clock_settime to implement settimeofday.
    
    Unconditionally, on all ports, use clock_settime to implement
    settimeofday.  This is a little different from using clock_settime to
    implement stime, because the vestigial “set time zone” feature of
    settimeofday complicates matters.
    
    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).  They 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.
    
    Another complication is that the alpha-linux-gnu configuration has two
    versions of settimeofday, GLIBC_2.0 and GLIBC_2.1, with the older
    symbol using 32-bit time_t (yes, really).  The older symbol is
    reimplemented from scratch (with the same semantics); the newer symbol
    uses the generic implementation with some #ifdeffage to get the
    versioning right.  Henceforth, __NR_osf_settimeofday will never be
    used, and __NR_settimeofday only for the timezone feature.
    
    There are no longer any internal callers of __settimeofday, so the
    internal prototype is removed.
    
    	* time/settimeofday.c (settimeofday): No longer a stub
    	implementation.  Call __clock_settime or __settimezone depending
    	on arguments.  Optionally override the default symbol version for
    	settimeofday.
    	* include/sys/time.h: Remove prototype for __settimeofday.
    	Add prototype for __settimezone.
    	* sysdeps/unix/syscalls.list: Remove entry for settimeofday.
    
    	* time/settimezone.c: New file.
    	(__settimezone): New stub implementation.
    	* sysdeps/unix/sysv/linux/settimezone.c: New file.
    	(__settimezone): Implement using settimeofday system call,
    	if available.
    	* time/Makefile (routines): Add settimezone.
    
    	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
    	Remove entries for settimeofday and osf_settimeofday.
    	* sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
    	New file, defines settimeofday@GLIBC_2.0.
    	* sysdeps/unix/sysv/linux/alpha/settimeofday.c:
    	New file, defines settimeofday@@GLIBC_2.1.

Diff:
---
 include/sys/time.h                               |  3 +-
 sysdeps/unix/syscalls.list                       |  1 -
 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c | 55 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/settimeofday.c     | 22 ++++++++++
 sysdeps/unix/sysv/linux/alpha/syscalls.list      |  2 -
 sysdeps/unix/sysv/linux/settimezone.c            | 39 +++++++++++++++++
 time/Makefile                                    |  2 +-
 time/settimeofday.c                              | 24 +++++++++--
 time/settimezone.c                               | 28 ++++++++++++
 9 files changed, 166 insertions(+), 10 deletions(-)

diff --git a/include/sys/time.h b/include/sys/time.h
index 7ba0ca7..a57752e 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/syscalls.list b/sysdeps/unix/syscalls.list
index 61e5360..5fedd57 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
new file mode 100644
index 0000000..a61fcab
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -0,0 +1,55 @@
+/* settimeofday -- Set the current time of day.  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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+struct timeval32
+{
+    int tv_sec, tv_usec;
+};
+
+/* 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,
+                     const struct timezone *tz)
+{
+  if (__glibc_unlikely (tz != 0))
+    {
+      if (tv32 != 0)
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+      return __settimezone (tz);
+    }
+
+  struct timespec ts;
+  ts.tv_sec = tv32->tv_sec;
+  ts.tv_nsec = tv32->tv_usec * 1000;
+  return __clock_settime (CLOCK_REALTIME, &ts);
+}
+
+compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
new file mode 100644
index 0000000..36a6901
--- /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 12cd021..f5a534e 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
 
 # support old timeval32 entry points
 osf_gettimeofday -	osf_gettimeofday 2	__gettimeofday_tv32  __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0
-osf_settimeofday -	osf_settimeofday 2	__settimeofday_tv32  settimeofday@GLIBC_2.0
 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
@@ -33,7 +32,6 @@ osf_wait4	-	osf_wait4	4	__wait4_tv32  wait4@GLIBC_2.0
 
 # support new timeval64 entry points
 gettimeofday	-	gettimeofday	2	__GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
-settimeofday	-	settimeofday	2	__settimeofday settimeofday@@GLIBC_2.1
 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/settimezone.c b/sysdeps/unix/sysv/linux/settimezone.c
new file mode 100644
index 0000000..823f4fe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/settimezone.c
@@ -0,0 +1,39 @@
+/* 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.  */
+
+#ifdef __NR_settimeofday
+
+int
+__settimezone (const struct timezone *tz)
+{
+  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
+}
+
+#else
+
+#include <time/settimezone.c>
+
+#endif
diff --git a/time/Makefile b/time/Makefile
index a428f55..d78bff8 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -36,7 +36,7 @@ routines := offtime asctime clock ctime ctime_r difftime \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
 	    strftime wcsftime strftime_l wcsftime_l	 \
-	    timespec_get
+	    timespec_get settimezone
 aux :=	    era alt_digit lc-time-cleanup
 
 tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
diff --git a/time/settimeofday.c b/time/settimeofday.c
index 4620559..78f666e 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -16,6 +16,7 @@
    <http://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/time/settimezone.c b/time/settimezone.c
new file mode 100644
index 0000000..eb005da
--- /dev/null
+++ b/time/settimezone.c
@@ -0,0 +1,28 @@
+/* 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>
+
+/* Set the system-wide timezone.
+   This call is restricted to the super-user.  */
+int
+__settimezone (const struct timezone *tz)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}


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

* [glibc/zack/y2038-preliminaries] Use clock_settime to implement settimeofday.
@ 2019-08-20 13:24 Zack Weinberg
  0 siblings, 0 replies; 7+ messages in thread
From: Zack Weinberg @ 2019-08-20 13:24 UTC (permalink / raw)
  To: glibc-cvs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii", Size: 13578 bytes --]

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=458e752a5d89931459eedd8a19da11737ca2f64d

commit 458e752a5d89931459eedd8a19da11737ca2f64d
Author: Zack Weinberg <zackw@panix.com>
Date:   Fri Aug 16 16:21:13 2019 -0400

    Use clock_settime to implement settimeofday.
    
    Unconditionally, on all ports, use clock_settime to implement
    settimeofday.  This is a little different from using clock_settime to
    implement stime, because the vestigial “set time zone” feature of
    settimeofday complicates matters.
    
    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).  They 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.
    
    Another complication is that the alpha-linux-gnu configuration has two
    versions of settimeofday, GLIBC_2.0 and GLIBC_2.1, with the older
    symbol using 32-bit time_t (yes, really).  The older symbol is
    reimplemented from scratch (with the same semantics); the newer symbol
    uses the generic implementation with some #ifdeffage to get the
    versioning right.  Henceforth, __NR_osf_settimeofday will never be
    used, and __NR_settimeofday only for the timezone feature.
    
    There are no longer any internal callers of __settimeofday, so the
    internal prototype is removed.
    
    	* time/settimeofday.c (settimeofday): No longer a stub
    	implementation.  Call __clock_settime or __settimezone depending
    	on arguments.  Optionally override the default symbol version for
    	settimeofday.
    	* include/sys/time.h: Remove prototype for __settimeofday.
    	Add prototype for __settimezone.
    	* sysdeps/unix/syscalls.list: Remove entry for settimeofday.
    
    	* time/settimezone.c: New file.
    	(__settimezone): New stub implementation.
    	* sysdeps/unix/sysv/linux/settimezone.c: New file.
    	(__settimezone): Implement using settimeofday system call,
    	if available.
    	* time/Makefile (routines): Add settimezone.
    
    	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
    	Remove entries for settimeofday and osf_settimeofday.
    	* sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
    	New file, defines settimeofday@GLIBC_2.0.
    	* sysdeps/unix/sysv/linux/alpha/settimeofday.c:
    	New file, defines settimeofday@@GLIBC_2.1.

Diff:
---
 include/sys/time.h                               |  3 +-
 sysdeps/unix/syscalls.list                       |  1 -
 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c | 55 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/settimeofday.c     | 22 ++++++++++
 sysdeps/unix/sysv/linux/alpha/syscalls.list      |  2 -
 sysdeps/unix/sysv/linux/settimezone.c            | 39 +++++++++++++++++
 time/Makefile                                    |  2 +-
 time/settimeofday.c                              | 24 +++++++++--
 time/settimezone.c                               | 28 ++++++++++++
 9 files changed, 166 insertions(+), 10 deletions(-)

diff --git a/include/sys/time.h b/include/sys/time.h
index 7ba0ca7..a57752e 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/syscalls.list b/sysdeps/unix/syscalls.list
index 61e5360..5fedd57 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
new file mode 100644
index 0000000..a61fcab
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -0,0 +1,55 @@
+/* settimeofday -- Set the current time of day.  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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+struct timeval32
+{
+    int tv_sec, tv_usec;
+};
+
+/* 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,
+                     const struct timezone *tz)
+{
+  if (__glibc_unlikely (tz != 0))
+    {
+      if (tv32 != 0)
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+      return __settimezone (tz);
+    }
+
+  struct timespec ts;
+  ts.tv_sec = tv32->tv_sec;
+  ts.tv_nsec = tv32->tv_usec * 1000;
+  return __clock_settime (CLOCK_REALTIME, &ts);
+}
+
+compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
new file mode 100644
index 0000000..36a6901
--- /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 12cd021..f5a534e 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
 
 # support old timeval32 entry points
 osf_gettimeofday -	osf_gettimeofday 2	__gettimeofday_tv32  __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0
-osf_settimeofday -	osf_settimeofday 2	__settimeofday_tv32  settimeofday@GLIBC_2.0
 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
@@ -33,7 +32,6 @@ osf_wait4	-	osf_wait4	4	__wait4_tv32  wait4@GLIBC_2.0
 
 # support new timeval64 entry points
 gettimeofday	-	gettimeofday	2	__GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
-settimeofday	-	settimeofday	2	__settimeofday settimeofday@@GLIBC_2.1
 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/settimezone.c b/sysdeps/unix/sysv/linux/settimezone.c
new file mode 100644
index 0000000..823f4fe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/settimezone.c
@@ -0,0 +1,39 @@
+/* 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.  */
+
+#ifdef __NR_settimeofday
+
+int
+__settimezone (const struct timezone *tz)
+{
+  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
+}
+
+#else
+
+#include <time/settimezone.c>
+
+#endif
diff --git a/time/Makefile b/time/Makefile
index a428f55..d78bff8 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -36,7 +36,7 @@ routines := offtime asctime clock ctime ctime_r difftime \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
 	    strftime wcsftime strftime_l wcsftime_l	 \
-	    timespec_get
+	    timespec_get settimezone
 aux :=	    era alt_digit lc-time-cleanup
 
 tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
diff --git a/time/settimeofday.c b/time/settimeofday.c
index 4620559..78f666e 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -16,6 +16,7 @@
    <http://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/time/settimezone.c b/time/settimezone.c
new file mode 100644
index 0000000..eb005da
--- /dev/null
+++ b/time/settimezone.c
@@ -0,0 +1,28 @@
+/* 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>
+
+/* Set the system-wide timezone.
+   This call is restricted to the super-user.  */
+int
+__settimezone (const struct timezone *tz)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}


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

* [glibc/zack/y2038-preliminaries] Use clock_settime to implement settimeofday.
@ 2019-08-19 18:31 Zack Weinberg
  0 siblings, 0 replies; 7+ messages in thread
From: Zack Weinberg @ 2019-08-19 18:31 UTC (permalink / raw)
  To: glibc-cvs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii", Size: 13578 bytes --]

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=79d24b6ef17002982a36c18a455a66e2840cb23a

commit 79d24b6ef17002982a36c18a455a66e2840cb23a
Author: Zack Weinberg <zackw@panix.com>
Date:   Fri Aug 16 16:21:13 2019 -0400

    Use clock_settime to implement settimeofday.
    
    Unconditionally, on all ports, use clock_settime to implement
    settimeofday.  This is a little different from using clock_settime to
    implement stime, because the vestigial “set time zone” feature of
    settimeofday complicates matters.
    
    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).  They 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.
    
    Another complication is that the alpha-linux-gnu configuration has two
    versions of settimeofday, GLIBC_2.0 and GLIBC_2.1, with the older
    symbol using 32-bit time_t (yes, really).  The older symbol is
    reimplemented from scratch (with the same semantics); the newer symbol
    uses the generic implementation with some #ifdeffage to get the
    versioning right.  Henceforth, __NR_osf_settimeofday will never be
    used, and __NR_settimeofday only for the timezone feature.
    
    There are no longer any internal callers of __settimeofday, so the
    internal prototype is removed.
    
    	* time/settimeofday.c (settimeofday): No longer a stub
    	implementation.  Call __clock_settime or __settimezone depending
    	on arguments.  Optionally override the default symbol version for
    	settimeofday.
    	* include/sys/time.h: Remove prototype for __settimeofday.
    	Add prototype for __settimezone.
    	* sysdeps/unix/syscalls.list: Remove entry for settimeofday.
    
    	* time/settimezone.c: New file.
    	(__settimezone): New stub implementation.
    	* sysdeps/unix/sysv/linux/settimezone.c: New file.
    	(__settimezone): Implement using settimeofday system call,
    	if available.
    	* time/Makefile (routines): Add settimezone.
    
    	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
    	Remove entries for settimeofday and osf_settimeofday.
    	* sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
    	New file, defines settimeofday@GLIBC_2.0.
    	* sysdeps/unix/sysv/linux/alpha/settimeofday.c:
    	New file, defines settimeofday@@GLIBC_2.1.

Diff:
---
 include/sys/time.h                               |  3 +-
 sysdeps/unix/syscalls.list                       |  1 -
 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c | 55 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/settimeofday.c     | 22 ++++++++++
 sysdeps/unix/sysv/linux/alpha/syscalls.list      |  2 -
 sysdeps/unix/sysv/linux/settimezone.c            | 39 +++++++++++++++++
 time/Makefile                                    |  2 +-
 time/settimeofday.c                              | 24 +++++++++--
 time/settimezone.c                               | 28 ++++++++++++
 9 files changed, 166 insertions(+), 10 deletions(-)

diff --git a/include/sys/time.h b/include/sys/time.h
index 7ba0ca7..a57752e 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/syscalls.list b/sysdeps/unix/syscalls.list
index 61e5360..5fedd57 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
new file mode 100644
index 0000000..a61fcab
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -0,0 +1,55 @@
+/* settimeofday -- Set the current time of day.  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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+struct timeval32
+{
+    int tv_sec, tv_usec;
+};
+
+/* 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,
+                     const struct timezone *tz)
+{
+  if (__glibc_unlikely (tz != 0))
+    {
+      if (tv32 != 0)
+	{
+	  __set_errno (EINVAL);
+	  return -1;
+	}
+      return __settimezone (tz);
+    }
+
+  struct timespec ts;
+  ts.tv_sec = tv32->tv_sec;
+  ts.tv_nsec = tv32->tv_usec * 1000;
+  return __clock_settime (CLOCK_REALTIME, &ts);
+}
+
+compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
new file mode 100644
index 0000000..36a6901
--- /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 12cd021..f5a534e 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
 
 # support old timeval32 entry points
 osf_gettimeofday -	osf_gettimeofday 2	__gettimeofday_tv32  __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0
-osf_settimeofday -	osf_settimeofday 2	__settimeofday_tv32  settimeofday@GLIBC_2.0
 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
@@ -33,7 +32,6 @@ osf_wait4	-	osf_wait4	4	__wait4_tv32  wait4@GLIBC_2.0
 
 # support new timeval64 entry points
 gettimeofday	-	gettimeofday	2	__GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
-settimeofday	-	settimeofday	2	__settimeofday settimeofday@@GLIBC_2.1
 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/settimezone.c b/sysdeps/unix/sysv/linux/settimezone.c
new file mode 100644
index 0000000..823f4fe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/settimezone.c
@@ -0,0 +1,39 @@
+/* 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.  */
+
+#ifdef __NR_settimeofday
+
+int
+__settimezone (const struct timezone *tz)
+{
+  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
+}
+
+#else
+
+#include <time/settimezone.c>
+
+#endif
diff --git a/time/Makefile b/time/Makefile
index a428f55..d78bff8 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -36,7 +36,7 @@ routines := offtime asctime clock ctime ctime_r difftime \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
 	    strftime wcsftime strftime_l wcsftime_l	 \
-	    timespec_get
+	    timespec_get settimezone
 aux :=	    era alt_digit lc-time-cleanup
 
 tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
diff --git a/time/settimeofday.c b/time/settimeofday.c
index 4620559..78f666e 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -16,6 +16,7 @@
    <http://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/time/settimezone.c b/time/settimezone.c
new file mode 100644
index 0000000..eb005da
--- /dev/null
+++ b/time/settimezone.c
@@ -0,0 +1,28 @@
+/* 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>
+
+/* Set the system-wide timezone.
+   This call is restricted to the super-user.  */
+int
+__settimezone (const struct timezone *tz)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}


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

* [glibc/zack/y2038-preliminaries] Use clock_settime to implement settimeofday.
@ 2019-08-17  1:17 Zack Weinberg
  0 siblings, 0 replies; 7+ messages in thread
From: Zack Weinberg @ 2019-08-17  1:17 UTC (permalink / raw)
  To: glibc-cvs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii", Size: 13557 bytes --]

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=fa807550b0952e2e6ad899437433dc923586a61d

commit fa807550b0952e2e6ad899437433dc923586a61d
Author: Zack Weinberg <zackw@panix.com>
Date:   Fri Aug 16 16:21:13 2019 -0400

    Use clock_settime to implement settimeofday.
    
    Abstractly, this is the same change as using clock_settime to
    implement stime, but the vestigial “set time zone” feature of
    settimeofday complicates matters 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).  They 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.
    
    Another complication is that the alpha-linux-gnu configuration has two
    versions of settimeofday, GLIBC_2.0 and GLIBC_2.1, with the older
    symbol using 32-bit time_t (yes, really).  The older symbol is
    reimplemented from scratch (with the same semantics); the newer symbol
    uses the generic implementation with some #ifdeffage to get the
    versioning right.  Henceforth, __NR_osf_settimeofday will never be
    used, and __NR_settimeofday only for the timezone feature.
    
    There are no longer any internal callers of __settimeofday, so the
    internal prototype is removed.
    
    	* time/settimeofday.c (settimeofday): No longer a stub
    	implementation.  Call __clock_settime or __settimezone depending
    	on arguments.  Optionally override the default symbol version for
    	settimeofday.
    	* include/sys/time.h: Remove prototype for __settimeofday.
    	Add prototype for __settimezone.
    	* sysdeps/unix/syscalls.list: Remove entry for settimeofday.
    
    	* time/settimezone.c: New file.
    	(__settimezone): New stub implementation.
    	* sysdeps/unix/sysv/linux/settimezone.c: New file.
    	(__settimezone): Implement using settimeofday system call,
    	if available.
    	* time/Makefile (routines): Add settimezone.
    
    	* sysdeps/unix/sysv/linux/alpha/syscalls.list:
    	Remove entries for settimeofday and osf_settimeofday.
    	* sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
    	New file, defines settimeofday@GLIBC_2.0.
    	* sysdeps/unix/sysv/linux/alpha/settimeofday.c:
    	New file, defines settimeofday@@GLIBC_2.1.

Diff:
---
 include/sys/time.h                               |  3 +-
 sysdeps/unix/syscalls.list                       |  1 -
 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c | 55 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/settimeofday.c     | 22 ++++++++++
 sysdeps/unix/sysv/linux/alpha/syscalls.list      |  2 -
 sysdeps/unix/sysv/linux/settimezone.c            | 39 +++++++++++++++++
 time/Makefile                                    |  2 +-
 time/settimeofday.c                              | 24 +++++++++--
 time/settimezone.c                               | 28 ++++++++++++
 9 files changed, 166 insertions(+), 10 deletions(-)

diff --git a/include/sys/time.h b/include/sys/time.h
index 7ba0ca7..a57752e 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/syscalls.list b/sysdeps/unix/syscalls.list
index 61e5360..5fedd57 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
new file mode 100644
index 0000000..fca20b7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c
@@ -0,0 +1,55 @@
+/* settimeofday -- Set the current time of day.  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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+
+struct timeval32
+{
+    int tv_sec, tv_usec;
+};
+
+/* 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,
+                     const struct timezone *tz)
+{
+  if ((tv && tz) || (!tv && !tz))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+  else if (tv)
+    {
+      struct timespec ts;
+      ts.tv_sec = tv32.tv_sec;
+      ts.tv_nsec = tv32.tv_usec * 1000;
+      return __clock_settime (CLOCK_REALTIME, &ts);
+    }
+  else
+    return __settimezone (tz);
+}
+
+compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0);
+#endif
diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c b/sysdeps/unix/sysv/linux/alpha/settimeofday.c
new file mode 100644
index 0000000..36a6901
--- /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 12cd021..f5a534e 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
 
 # support old timeval32 entry points
 osf_gettimeofday -	osf_gettimeofday 2	__gettimeofday_tv32  __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0
-osf_settimeofday -	osf_settimeofday 2	__settimeofday_tv32  settimeofday@GLIBC_2.0
 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
@@ -33,7 +32,6 @@ osf_wait4	-	osf_wait4	4	__wait4_tv32  wait4@GLIBC_2.0
 
 # support new timeval64 entry points
 gettimeofday	-	gettimeofday	2	__GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1
-settimeofday	-	settimeofday	2	__settimeofday settimeofday@@GLIBC_2.1
 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/settimezone.c b/sysdeps/unix/sysv/linux/settimezone.c
new file mode 100644
index 0000000..823f4fe
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/settimezone.c
@@ -0,0 +1,39 @@
+/* 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.  */
+
+#ifdef __NR_settimeofday
+
+int
+__settimezone (const struct timezone *tz)
+{
+  return INLINE_SYSCALL_CALL (settimeofday, NULL, tz);
+}
+
+#else
+
+#include <time/settimezone.c>
+
+#endif
diff --git a/time/Makefile b/time/Makefile
index a428f55..d78bff8 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -36,7 +36,7 @@ routines := offtime asctime clock ctime ctime_r difftime \
 	    stime dysize timegm ftime			 \
 	    getdate strptime strptime_l			 \
 	    strftime wcsftime strftime_l wcsftime_l	 \
-	    timespec_get
+	    timespec_get settimezone
 aux :=	    era alt_digit lc-time-cleanup
 
 tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
diff --git a/time/settimeofday.c b/time/settimeofday.c
index 4620559..75c7694 100644
--- a/time/settimeofday.c
+++ b/time/settimeofday.c
@@ -16,6 +16,7 @@
    <http://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 ((tv && tz) || (!tv && !tz))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+  else if (tv)
+    {
+      struct timespec ts;
+      TIMEVAL_TO_TIMESPEC (tv, &ts);
+      return __clock_settime (CLOCK_REALTIME, &ts);
+    }
+  else
+    return __settimezone (tz);
 }
-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/time/settimezone.c b/time/settimezone.c
new file mode 100644
index 0000000..eb005da
--- /dev/null
+++ b/time/settimezone.c
@@ -0,0 +1,28 @@
+/* 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>
+
+/* Set the system-wide timezone.
+   This call is restricted to the super-user.  */
+int
+__settimezone (const struct timezone *tz)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}


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

end of thread, other threads:[~2019-08-28 13:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-20 12:07 [glibc/zack/y2038-preliminaries] Use clock_settime to implement settimeofday Zack Weinberg
  -- strict thread matches above, loose matches on Subject: below --
2019-08-28 13:04 Zack Weinberg
2019-08-22 23:04 Zack Weinberg
2019-08-21 12:28 Zack Weinberg
2019-08-20 13:24 Zack Weinberg
2019-08-19 18:31 Zack Weinberg
2019-08-17  1:17 Zack Weinberg

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).