Add clock_settime and clock_nanosleep.

Add the missing prototypes, fix the existing prototypes to use clockid_t
rather than int, fix clock_nanosleep's failure behavior, and add simple
tests.

Bug: 17644443
Bug: https://code.google.com/p/android/issues/detail?id=77372
Change-Id: I03fba369939403918abcabae9551a7123953d780
Signed-off-by: Haruki Hasegawa <h6a.h4i.0@gmail.com>
diff --git a/libc/Android.mk b/libc/Android.mk
index 078e8c3..1839d3d 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -98,6 +98,7 @@
     bionic/chown.cpp \
     bionic/clearenv.cpp \
     bionic/clock.cpp \
+    bionic/clock_nanosleep.cpp \
     bionic/clone.cpp \
     bionic/__cmsg_nxthdr.cpp \
     bionic/connect.cpp \
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 47b7ef8..866671d 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -202,9 +202,9 @@
 int           settimeofday(const struct timeval*, const struct timezone*)   all
 clock_t       times(struct tms*)       all
 int           nanosleep(const struct timespec*, struct timespec*)   all
-int           clock_settime(clockid_t clk_id, const struct timespec* tp)  all
-int           clock_getres(clockid_t clk_id, struct timespec* res)   all
-int           clock_nanosleep(clockid_t clock_id, int flags, const struct timespec* req, struct timespec* rem)  all
+int           clock_settime(clockid_t, const struct timespec*)  all
+int           clock_getres(clockid_t, struct timespec*)   all
+int           __clock_nanosleep:clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*)  all
 int           getitimer(int, const struct itimerval*)   all
 int           setitimer(int, const struct itimerval*, struct itimerval*)  all
 int           __timer_create:timer_create(clockid_t clockid, struct sigevent* evp, __kernel_timer_t* timerid)    all
diff --git a/libc/arch-arm/syscalls/clock_nanosleep.S b/libc/arch-arm/syscalls/__clock_nanosleep.S
similarity index 85%
rename from libc/arch-arm/syscalls/clock_nanosleep.S
rename to libc/arch-arm/syscalls/__clock_nanosleep.S
index 80295bb..ba7ffc4 100644
--- a/libc/arch-arm/syscalls/clock_nanosleep.S
+++ b/libc/arch-arm/syscalls/__clock_nanosleep.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(clock_nanosleep)
+ENTRY(__clock_nanosleep)
     mov     ip, r7
     ldr     r7, =__NR_clock_nanosleep
     swi     #0
@@ -11,4 +11,4 @@
     bxls    lr
     neg     r0, r0
     b       __set_errno_internal
-END(clock_nanosleep)
+END(__clock_nanosleep)
diff --git a/libc/arch-arm64/syscalls/clock_nanosleep.S b/libc/arch-arm64/syscalls/__clock_nanosleep.S
similarity index 76%
rename from libc/arch-arm64/syscalls/clock_nanosleep.S
rename to libc/arch-arm64/syscalls/__clock_nanosleep.S
index 349c5cc..1df15d6 100644
--- a/libc/arch-arm64/syscalls/clock_nanosleep.S
+++ b/libc/arch-arm64/syscalls/__clock_nanosleep.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(clock_nanosleep)
+ENTRY(__clock_nanosleep)
     mov     x8, __NR_clock_nanosleep
     svc     #0
 
@@ -11,4 +11,5 @@
     b.hi    __set_errno_internal
 
     ret
-END(clock_nanosleep)
+END(__clock_nanosleep)
+.hidden __clock_nanosleep
diff --git a/libc/arch-mips/syscalls/clock_nanosleep.S b/libc/arch-mips/syscalls/__clock_nanosleep.S
similarity index 85%
rename from libc/arch-mips/syscalls/clock_nanosleep.S
rename to libc/arch-mips/syscalls/__clock_nanosleep.S
index 6002ab4..97bfa27 100644
--- a/libc/arch-mips/syscalls/clock_nanosleep.S
+++ b/libc/arch-mips/syscalls/__clock_nanosleep.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(clock_nanosleep)
+ENTRY(__clock_nanosleep)
     .set noreorder
     .cpload t9
     li v0, __NR_clock_nanosleep
@@ -16,4 +16,4 @@
     j t9
     nop
     .set reorder
-END(clock_nanosleep)
+END(__clock_nanosleep)
diff --git a/libc/arch-mips64/syscalls/clock_nanosleep.S b/libc/arch-mips64/syscalls/__clock_nanosleep.S
similarity index 83%
rename from libc/arch-mips64/syscalls/clock_nanosleep.S
rename to libc/arch-mips64/syscalls/__clock_nanosleep.S
index c958a10..204675f 100644
--- a/libc/arch-mips64/syscalls/clock_nanosleep.S
+++ b/libc/arch-mips64/syscalls/__clock_nanosleep.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(clock_nanosleep)
+ENTRY(__clock_nanosleep)
     .set push
     .set noreorder
     li v0, __NR_clock_nanosleep
@@ -22,4 +22,5 @@
     j t9
     move ra, t0
     .set pop
-END(clock_nanosleep)
+END(__clock_nanosleep)
+.hidden __clock_nanosleep
diff --git a/libc/arch-x86/syscalls/clock_nanosleep.S b/libc/arch-x86/syscalls/__clock_nanosleep.S
similarity index 93%
rename from libc/arch-x86/syscalls/clock_nanosleep.S
rename to libc/arch-x86/syscalls/__clock_nanosleep.S
index 5e2cc03..75a54d1 100644
--- a/libc/arch-x86/syscalls/clock_nanosleep.S
+++ b/libc/arch-x86/syscalls/__clock_nanosleep.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(clock_nanosleep)
+ENTRY(__clock_nanosleep)
     pushl   %ebx
     .cfi_def_cfa_offset 8
     .cfi_rel_offset ebx, 0
@@ -33,4 +33,4 @@
     popl    %ecx
     popl    %ebx
     ret
-END(clock_nanosleep)
+END(__clock_nanosleep)
diff --git a/libc/arch-x86_64/syscalls/clock_nanosleep.S b/libc/arch-x86_64/syscalls/__clock_nanosleep.S
similarity index 79%
rename from libc/arch-x86_64/syscalls/clock_nanosleep.S
rename to libc/arch-x86_64/syscalls/__clock_nanosleep.S
index 2a79bdd..37726c0 100644
--- a/libc/arch-x86_64/syscalls/clock_nanosleep.S
+++ b/libc/arch-x86_64/syscalls/__clock_nanosleep.S
@@ -2,7 +2,7 @@
 
 #include <private/bionic_asm.h>
 
-ENTRY(clock_nanosleep)
+ENTRY(__clock_nanosleep)
     movq    %rcx, %r10
     movl    $__NR_clock_nanosleep, %eax
     syscall
@@ -13,4 +13,5 @@
     call    __set_errno_internal
 1:
     ret
-END(clock_nanosleep)
+END(__clock_nanosleep)
+.hidden __clock_nanosleep
diff --git a/libc/bionic/clock_nanosleep.cpp b/libc/bionic/clock_nanosleep.cpp
new file mode 100644
index 0000000..15b8fe7
--- /dev/null
+++ b/libc/bionic/clock_nanosleep.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <time.h>
+
+#include "private/ErrnoRestorer.h"
+
+extern "C" int __clock_nanosleep(clockid_t, int, const timespec*, timespec*);
+
+int clock_nanosleep(clockid_t clock_id, int flags, const timespec* in, timespec* out) {
+  ErrnoRestorer errno_restorer;
+  return (__clock_nanosleep(clock_id, flags, in, out) == 0) ? 0 : errno;
+}
diff --git a/libc/include/time.h b/libc/include/time.h
index 34a53b2..e34eb34 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -85,8 +85,10 @@
 
 extern clock_t clock(void) __LIBC_ABI_PUBLIC__;
 
-extern int clock_getres(int, struct timespec*) __LIBC_ABI_PUBLIC__;
-extern int clock_gettime(int, struct timespec*) __LIBC_ABI_PUBLIC__;
+extern int clock_getres(clockid_t, struct timespec*) __LIBC_ABI_PUBLIC__;
+extern int clock_gettime(clockid_t, struct timespec*) __LIBC_ABI_PUBLIC__;
+extern int clock_nanosleep(clockid_t, int, const struct timespec*, struct timespec*) __LIBC_ABI_PUBLIC__;
+extern int clock_settime(clockid_t, const struct timespec*) __LIBC_ABI_PUBLIC__;
 
 extern int timer_create(int, struct sigevent*, timer_t*) __LIBC_ABI_PUBLIC__;
 extern int timer_delete(timer_t) __LIBC_ABI_PUBLIC__;
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index d2fec9a..26c6993 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -406,9 +406,22 @@
 }
 
 TEST(time, clock) {
-   // clock(3) is hard to test, but a 1s sleep should cost less than 1ms.
-   clock_t t0 = clock();
-   sleep(1);
-   clock_t t1 = clock();
-   ASSERT_LT(t1 - t0, CLOCKS_PER_SEC / 1000);
+  // clock(3) is hard to test, but a 1s sleep should cost less than 1ms.
+  clock_t t0 = clock();
+  sleep(1);
+  clock_t t1 = clock();
+  ASSERT_LT(t1 - t0, CLOCKS_PER_SEC / 1000);
+}
+
+TEST(time, clock_settime) {
+  errno = 0;
+  timespec ts;
+  ASSERT_EQ(-1, clock_settime(-1, &ts));
+  ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(time, clock_nanosleep) {
+  timespec in;
+  timespec out;
+  ASSERT_EQ(EINVAL, clock_nanosleep(-1, 0, &in, &out));
 }