From 05309d87a681e9045d923269bf7e733d4555efb9 Mon Sep 17 00:00:00 2001
From: Peter S. Mazinger <ps.m@gmx.net>
Date: Sat, 16 Apr 2011 11:55:10 +0200
Subject: [PATCH 283/396] provide stime and settimeofday functions if at least one of the syscalls is available

Add hidden stime for possible use in settimeofday.
Add stubs for both functions if none of the syscalls is present.
Avoid circular dependency.

Signed-off-by: Peter S. Mazinger <ps.m@gmx.net>
---
 include/time.h                           |    1 +
 libc/sysdeps/linux/common/settimeofday.c |   30 +++++++++++++++++++++++++++---
 libc/sysdeps/linux/common/stime.c        |   19 ++++++++++++-------
 libc/sysdeps/linux/common/stubs.c        |    5 +++++
 4 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/include/time.h b/include/time.h
index bea5623..50a412d 100644
--- a/include/time.h
+++ b/include/time.h
@@ -318,6 +318,7 @@ extern long int timezone;
 /* Set the system time to *WHEN.
    This call is restricted to the superuser.  */
 extern int stime (__const time_t *__when) __THROW;
+libc_hidden_proto(stime)
 # endif
 
 
diff --git a/libc/sysdeps/linux/common/settimeofday.c b/libc/sysdeps/linux/common/settimeofday.c
index 7e508ae..e6b396e 100644
--- a/libc/sysdeps/linux/common/settimeofday.c
+++ b/libc/sysdeps/linux/common/settimeofday.c
@@ -8,12 +8,36 @@
  */
 
 #include <sys/syscall.h>
-#include <sys/time.h>
 
 #ifdef __USE_BSD
+# include <sys/time.h>
+# ifdef __NR_settimeofday
+_syscall2(int, settimeofday, const struct timeval *, tv,
+	  const struct timezone *, tz)
+# elif defined __USE_SVID && defined __NR_stime
+#  define __need_NULL
+#  include <stddef.h>
+#  include <errno.h>
+#  include <time.h>
+int settimeofday(const struct timeval *tv, const struct timezone *tz)
+{
+	time_t when;
 
+	if (tv == NULL) {
+		__set_errno(EINVAL);
+		return -1;
+	}
 
-_syscall2(int, settimeofday, const struct timeval *, tv,
-		  const struct timezone *, tz)
+	if (tz != NULL || tv->tv_usec % 1000000 != 0) {
+		__set_errno(ENOSYS);
+		return -1;
+	}
+
+	when = tv->tv_sec + (tv->tv_usec / 1000000);
+	return stime(&when);
+}
+# endif
+# if defined __NR_settimeofday || (defined __USE_SVID && defined __NR_stime)
 libc_hidden_def(settimeofday)
+# endif
 #endif
diff --git a/libc/sysdeps/linux/common/stime.c b/libc/sysdeps/linux/common/stime.c
index cb7e804..b30884d 100644
--- a/libc/sysdeps/linux/common/stime.c
+++ b/libc/sysdeps/linux/common/stime.c
@@ -8,15 +8,17 @@
  */
 
 #include <sys/syscall.h>
-#include <time.h>
-#include <sys/time.h>
 
 #ifdef __USE_SVID
-#ifdef __NR_stime
+# include <time.h>
+# ifdef __NR_stime
 _syscall1(int, stime, const time_t *, t)
-#else
-
-int stime(const time_t * when)
+# elif defined __USE_BSD && defined __NR_settimeofday
+#  define __need_NULL
+#  include <stddef.h>
+#  include <errno.h>
+#  include <sys/time.h>
+int stime(const time_t *when)
 {
 	struct timeval tv;
 
@@ -28,5 +30,8 @@ int stime(const time_t * when)
 	tv.tv_usec = 0;
 	return settimeofday(&tv, (struct timezone *) 0);
 }
-#endif
+# endif
+# if defined __NR_stime || (defined __USE_BSD && defined __NR_settimeofday)
+libc_hidden_def(stime)
+# endif
 #endif
diff --git a/libc/sysdeps/linux/common/stubs.c b/libc/sysdeps/linux/common/stubs.c
index 31d420f..0e24ac9 100644
--- a/libc/sysdeps/linux/common/stubs.c
+++ b/libc/sysdeps/linux/common/stubs.c
@@ -441,6 +441,11 @@ make_stub(vmsplice)
 make_stub(renameat)
 #endif
 
+#if !defined __NR_stime && !defined __NR_settimeofday
+make_stub(stime)
+make_stub(settimeofday)
+#endif
+
 #ifndef __NR_fadvise64
 make_ret_stub(posix_fadvise)
 #endif
-- 
1.7.0.4

