[trusty-libc] Better time support

Bug: 141189390
Change-Id: I23b74886f7ca2c073e08c66a248a87e318e6b677
diff --git a/lib/libc-trusty/rules.mk b/lib/libc-trusty/rules.mk
index 49f9ee2..35d9cdc 100644
--- a/lib/libc-trusty/rules.mk
+++ b/lib/libc-trusty/rules.mk
@@ -329,7 +329,12 @@
 	$(MUSL_DIR)/src/time/gettimeofday.c \
 	$(MUSL_DIR)/src/time/localtime.c \
 	$(MUSL_DIR)/src/time/localtime_r.c \
+	$(MUSL_DIR)/src/time/gmtime.c \
+	$(MUSL_DIR)/src/time/gmtime_r.c \
+	$(MUSL_DIR)/src/time/time.c \
 	$(MUSL_DIR)/src/time/__secs_to_tm.c \
+	$(MUSL_DIR)/src/unistd/sleep.c \
+	$(MUSL_DIR)/src/unistd/usleep.c \
 
 # Math
 MODULE_SRCS += \
diff --git a/lib/libc-trusty/time.c b/lib/libc-trusty/time.c
index 5eb9792..d0d108e 100644
--- a/lib/libc-trusty/time.c
+++ b/lib/libc-trusty/time.c
@@ -16,20 +16,71 @@
 
 #include <time.h>
 
+#include <assert.h>
 #include <errno.h>
 #include <trusty_syscalls.h>
 
+#define NS_PER_SEC 1000000000
+
 int trusty_nanosleep(clockid_t clock_id, uint32_t flags, uint64_t sleep_time) {
+    /* TODO validate clock_ids. */
+    /* No flags, yet. */
+    assert(flags == 0);
     return _trusty_nanosleep(clock_id, flags, sleep_time);
 }
 
+int clock_nanosleep(clockid_t clock_id,
+                    int flags,
+                    const struct timespec* req,
+                    struct timespec* rem) {
+    /* Validate inputs. */
+    if (!req) {
+        errno = EFAULT;
+        return -1;
+    }
+    if (req->tv_sec < 0) {
+        errno = EINVAL;
+        return -1;
+    }
+    if (req->tv_nsec >= NS_PER_SEC || req->tv_nsec < 0) {
+        errno = EINVAL;
+        return -1;
+    }
+    /* Convert timespec to nanoseconds. */
+    uint64_t sleep_time;
+    if (__builtin_mul_overflow(req->tv_sec, NS_PER_SEC, &sleep_time)) {
+        errno = EINVAL;
+        return -1;
+    }
+    if (__builtin_add_overflow(sleep_time, req->tv_nsec, &sleep_time)) {
+        errno = EINVAL;
+        return -1;
+    }
+    /* Actually sleep. */
+    int ret = trusty_nanosleep(clock_id, flags, sleep_time);
+    /* Handle the result. */
+    if (rem) {
+        /* Trusty should not wake up early, except for clock rounding. */
+        rem->tv_sec = 0;
+        rem->tv_nsec = 0;
+    }
+    if (ret) {
+        /* clock_id was invalid? */
+        errno = EINVAL;
+        return -1;
+    }
+    return 0;
+}
+
+int nanosleep(const struct timespec* req, struct timespec* rem) {
+    return clock_nanosleep(CLOCK_BOOTTIME, 0, req, rem);
+}
+
 int trusty_gettime(clockid_t clock_id, int64_t* time) {
     return _trusty_gettime(clock_id, 0, time);
 }
 
-#define NS_PER_SEC 1000000000
-
-int clock_gettime(clockid_t clock_id, struct timespec* ts) {
+int __clock_gettime(clockid_t clock_id, struct timespec* ts) {
     if (ts == NULL) {
         errno = EFAULT;
         return -1;
@@ -45,3 +96,10 @@
     ts->tv_nsec = (long)(time % NS_PER_SEC);
     return 0;
 }
+
+/*
+ * Internally, Musl references __clock_gettime, and then provides an alias for
+ * external users. Since we're providing the function, we need to provide the
+ * internal name for Musl and the external name for the user.
+ */
+weak_alias(__clock_gettime, clock_gettime);
diff --git a/lib/libc-trusty/time_stubs.c b/lib/libc-trusty/time_stubs.c
index b2c124c..af667fc 100644
--- a/lib/libc-trusty/time_stubs.c
+++ b/lib/libc-trusty/time_stubs.c
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
+#include <errno.h>
+#include <sys/time.h>
 #include <time.h>
 
+/* Needed by Musl internals. Normally provided by Musl's __tz.c file. */
+const char __utc[] = "UTC";
+
 /*
  * strftime ends up depending on time zone data files. Stub this function rather
  * than stubbing out data loading.
@@ -52,3 +57,9 @@
         *oppoff = 0;
     *zonename = "UTC";
 }
+
+/* sys/time.h is not quite right for ALL_SOURCE, so declare the last argument as
+ * void* */
+int settimeofday(const struct timeval* tv, const void* tz) {
+    return EPERM;
+}
diff --git a/lib/openssl-stubs/rules.mk b/lib/openssl-stubs/rules.mk
index d98512e..5947b62 100644
--- a/lib/openssl-stubs/rules.mk
+++ b/lib/openssl-stubs/rules.mk
@@ -6,7 +6,6 @@
 MODULE_SRCS := \
 	$(LOCAL_DIR)/bio.c \
 	$(LOCAL_DIR)/rand.c \
-	$(LOCAL_DIR)/time.c \
 
 MODULE_DEPS := \
 	trusty/user/base/lib/rng
diff --git a/lib/openssl-stubs/time.c b/lib/openssl-stubs/time.c
deleted file mode 100644
index 683f71e..0000000
--- a/lib/openssl-stubs/time.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <time.h>
-
-#include <string.h>
-
-struct tm* OPENSSL_gmtime(const time_t* timer, struct tm* result) {
-    memset(result, 0, sizeof(*result));
-    /* the tm_mday valid range is [1,31], cannot return a zero */
-    result->tm_mday = 1;
-    return result;
-}
-
-int OPENSSL_gmtime_adj(struct tm* tm, int offset_day, long offset_sec) {
-    return 0;
-}