[RFC,29/52] Y2038: add function __stime_t64

Message ID 20170907224219.12483-30-albert.aribaud@3adev.fr
State New
Headers show
Series
  • Make GLIBC Y2038-proof
Related show

Commit Message

Albert ARIBAUD Sept. 7, 2017, 10:41 p.m.
These implementations use only 32-bit time kernel syscalls.

Therefore, stime() will always set errno to EOVERFLOW and return -1 for dates beyond Y2038.

Signed-off-by: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
---
 sysdeps/unix/sysv/linux/stime.c | 70 +++++++++++++++++++++++++++++++++++++++++
 time/Versions                   |  1 +
 time/stime.c                    | 17 ++++++++++
 3 files changed, 88 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/stime.c

Patch

diff --git a/sysdeps/unix/sysv/linux/stime.c b/sysdeps/unix/sysv/linux/stime.c
new file mode 100644
index 0000000000..177c9334ef
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/stime.c
@@ -0,0 +1,70 @@ 
+/* Copyright (C) 1992-2017 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 <stddef.h>		/* For NULL.  */
+#include <sys/time.h>
+#include <time.h>
+
+/* Set the system clock to *WHEN.  */
+
+int
+stime (const time_t *when)
+{
+  struct timeval tv;
+
+  if (when == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  tv.tv_sec = *when;
+  tv.tv_usec = 0;
+  return __settimeofday (&tv, (struct timezone *) 0);
+}
+
+/* 64-bit time version */
+
+extern int __y2038_linux_support;
+
+int
+__stime_t64 (const __time64_t *when)
+{
+  struct timeval tv32;
+
+  if (when == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  if (__y2038_linux_support)
+  {
+    /* TODO: implement 64-bit-time syscall case */
+  }
+
+  if (*when > INT_MAX)
+    {
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
+
+  tv32.tv_sec = *when;
+  tv32.tv_usec = 0;
+  return __settimeofday (&tv32, (struct timezone *) 0);
+}
diff --git a/time/Versions b/time/Versions
index 02dc8d6146..3dca51abcb 100644
--- a/time/Versions
+++ b/time/Versions
@@ -72,5 +72,6 @@  libc {
   GLIBC_Y2038 {
     __timespec_get64;
     __time_t64;
+    __stime_t64;
   }
 }
diff --git a/time/stime.c b/time/stime.c
index 723eedacf1..c1c7c4c9b5 100644
--- a/time/stime.c
+++ b/time/stime.c
@@ -35,3 +35,20 @@  stime (const time_t *when)
 }
 
 stub_warning (stime)
+
+/* 64-bit time version */
+
+int
+__stime_t64 (const __time64_t *when)
+{
+  if (when == NULL)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+stub_warning (__stime_t64)