Add support for the utimensat(2) syscall to bionic.

The kernel has supported this syscall for quite some time now,
but bionic did not.  Now that there is a need for it, let's
add it to bionic.

Change-Id: Ifcef3e46f1438d79435b600c4e6063857ab16903
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index bd3e4d4..d698133 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -174,6 +174,7 @@
 int           __timer_getoverrun:timer_getoverrun(timer_t)                                              260,262
 int           __timer_delete:timer_delete(timer_t)                                                      261,263
 int           utimes(const char*, const struct timeval tvp[2])                          269, 271
+int           utimensat(int, const char *, const struct timespec times[2], int)         348, 320, 320
 
 # signals
 int     sigaction(int, const struct sigaction *, struct sigaction *)  67
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index 5210d6c..e6c84f6 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -124,6 +124,7 @@
 syscall_src += arch-arm/syscalls/__timer_getoverrun.S
 syscall_src += arch-arm/syscalls/__timer_delete.S
 syscall_src += arch-arm/syscalls/utimes.S
+syscall_src += arch-arm/syscalls/utimensat.S
 syscall_src += arch-arm/syscalls/sigaction.S
 syscall_src += arch-arm/syscalls/sigprocmask.S
 syscall_src += arch-arm/syscalls/__sigsuspend.S
diff --git a/libc/arch-arm/syscalls/utimensat.S b/libc/arch-arm/syscalls/utimensat.S
new file mode 100644
index 0000000..ceae7fa
--- /dev/null
+++ b/libc/arch-arm/syscalls/utimensat.S
@@ -0,0 +1,14 @@
+/* autogenerated by gensyscalls.py */
+#include <machine/asm.h>
+#include <sys/linux-syscalls.h>
+
+ENTRY(utimensat)
+    .save   {r4, r7}
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =__NR_utimensat
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+    bxpl    lr
+    b       __set_syscall_errno
+END(utimensat)
diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk
index 9575905..1d87600 100644
--- a/libc/arch-sh/syscalls.mk
+++ b/libc/arch-sh/syscalls.mk
@@ -127,6 +127,7 @@
 syscall_src += arch-sh/syscalls/__timer_getoverrun.S
 syscall_src += arch-sh/syscalls/__timer_delete.S
 syscall_src += arch-sh/syscalls/utimes.S
+syscall_src += arch-sh/syscalls/utimensat.S
 syscall_src += arch-sh/syscalls/sigaction.S
 syscall_src += arch-sh/syscalls/sigprocmask.S
 syscall_src += arch-sh/syscalls/__sigsuspend.S
diff --git a/libc/arch-sh/syscalls/utimensat.S b/libc/arch-sh/syscalls/utimensat.S
new file mode 100644
index 0000000..28e7ec6
--- /dev/null
+++ b/libc/arch-sh/syscalls/utimensat.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type utimensat, @function
+    .globl utimensat
+    .align 4
+
+utimensat:
+
+    /* invoke trap */
+    mov.l   0f, r3  /* trap num */
+    trapa   #(4 + 0x10)
+
+    /* check return value */
+    cmp/pz  r0
+    bt      __NR_utimensat_end
+
+    /* keep error number */
+    sts.l   pr, @-r15
+    mov.l   1f, r1
+    jsr     @r1
+    mov     r0, r4
+    lds.l   @r15+, pr
+
+__NR_utimensat_end:
+    rts
+    nop
+
+    .align  2
+0:  .long   __NR_utimensat
+1:  .long   __set_syscall_errno
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index e8c6a77..3b85025 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -127,6 +127,7 @@
 syscall_src += arch-x86/syscalls/__timer_getoverrun.S
 syscall_src += arch-x86/syscalls/__timer_delete.S
 syscall_src += arch-x86/syscalls/utimes.S
+syscall_src += arch-x86/syscalls/utimensat.S
 syscall_src += arch-x86/syscalls/sigaction.S
 syscall_src += arch-x86/syscalls/sigprocmask.S
 syscall_src += arch-x86/syscalls/__sigsuspend.S
diff --git a/libc/arch-x86/syscalls/utimensat.S b/libc/arch-x86/syscalls/utimensat.S
new file mode 100644
index 0000000..e2032b5
--- /dev/null
+++ b/libc/arch-x86/syscalls/utimensat.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type utimensat, @function
+    .globl utimensat
+    .align 4
+
+utimensat:
+    pushl   %ebx
+    pushl   %ecx
+    pushl   %edx
+    pushl   %esi
+    mov     20(%esp), %ebx
+    mov     24(%esp), %ecx
+    mov     28(%esp), %edx
+    mov     32(%esp), %esi
+    movl    $__NR_utimensat, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %esi
+    popl    %edx
+    popl    %ecx
+    popl    %ebx
+    ret
diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index 5b8e2b4..7b74a4b 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -162,6 +162,7 @@
 #define __NR_timer_getoverrun             (__NR_SYSCALL_BASE + 260)
 #define __NR_timer_delete                 (__NR_SYSCALL_BASE + 261)
 #define __NR_utimes                       (__NR_SYSCALL_BASE + 269)
+#define __NR_utimensat                    (__NR_SYSCALL_BASE + 348)
 #define __NR_socket                       (__NR_SYSCALL_BASE + 281)
 #define __NR_socketpair                   (__NR_SYSCALL_BASE + 288)
 #define __NR_bind                         (__NR_SYSCALL_BASE + 282)
@@ -221,6 +222,7 @@
 #define __NR_timer_getoverrun             (__NR_SYSCALL_BASE + 262)
 #define __NR_timer_delete                 (__NR_SYSCALL_BASE + 263)
 #define __NR_utimes                       (__NR_SYSCALL_BASE + 271)
+#define __NR_utimensat                    (__NR_SYSCALL_BASE + 320)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR_getcpu                       (__NR_SYSCALL_BASE + 318)
 #define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 289)
@@ -265,6 +267,7 @@
 #define __NR_timer_getoverrun             (__NR_SYSCALL_BASE + 262)
 #define __NR_timer_delete                 (__NR_SYSCALL_BASE + 263)
 #define __NR_utimes                       (__NR_SYSCALL_BASE + 271)
+#define __NR_utimensat                    (__NR_SYSCALL_BASE + 320)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
 #define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h
index f706d00c..ae9077f 100644
--- a/libc/include/sys/linux-unistd.h
+++ b/libc/include/sys/linux-unistd.h
@@ -138,6 +138,7 @@
 int              __timer_getoverrun (timer_t);
 int              __timer_delete (timer_t);
 int              utimes (const char*, const struct timeval tvp[2]);
+int              utimensat (int, const char *, const struct timespec times[2], int);
 int              sigaction (int, const struct sigaction *, struct sigaction *);
 int              sigprocmask (int, const sigset_t *, sigset_t *);
 int              __sigsuspend (int unused1, int unused2, unsigned mask);
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 091ee6d..87fcfd0 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -103,6 +103,10 @@
 extern int fchmodat(int dirfd, const char *path, mode_t mode, int flags);
 extern int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
 
+# define UTIME_NOW      ((1l << 30) - 1l)
+# define UTIME_OMIT     ((1l << 30) - 2l)
+extern int utimensat (int fd, const char *path, const struct timespec times[2], int flags);
+
 __END_DECLS
 
 #endif /* _SYS_STAT_H_ */