Add unshare system call

Adds a C function for the unshare system call supported by Linux since
2.6.16.

Change-Id: I32df4075d875e9f5b5ed716cd7b02cdf82c64526
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index d72d129..f3dedb3 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -252,6 +252,7 @@
 int     klogctl:syslog(int, char *, int)   103
 int     sysinfo(struct sysinfo *)  116
 int     personality(unsigned long)  136
+int     unshare(int)                337,310
 
 # futex
 int	futex(void *, int, int, void *, void *, int) 240
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index 861cabf..466e529 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -170,6 +170,7 @@
 syscall_src += arch-arm/syscalls/klogctl.S
 syscall_src += arch-arm/syscalls/sysinfo.S
 syscall_src += arch-arm/syscalls/personality.S
+syscall_src += arch-arm/syscalls/unshare.S
 syscall_src += arch-arm/syscalls/futex.S
 syscall_src += arch-arm/syscalls/epoll_create.S
 syscall_src += arch-arm/syscalls/epoll_ctl.S
diff --git a/libc/arch-arm/syscalls/unshare.S b/libc/arch-arm/syscalls/unshare.S
new file mode 100644
index 0000000..0a92b21
--- /dev/null
+++ b/libc/arch-arm/syscalls/unshare.S
@@ -0,0 +1,14 @@
+/* autogenerated by gensyscalls.py */
+#include <machine/asm.h>
+#include <sys/linux-syscalls.h>
+
+ENTRY(unshare)
+    .save   {r4, r7}
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =__NR_unshare
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+    bxpl    lr
+    b       __set_syscall_errno
+END(unshare)
diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk
index 6666431..22c7f9f 100644
--- a/libc/arch-sh/syscalls.mk
+++ b/libc/arch-sh/syscalls.mk
@@ -159,6 +159,7 @@
 syscall_src += arch-sh/syscalls/klogctl.S
 syscall_src += arch-sh/syscalls/sysinfo.S
 syscall_src += arch-sh/syscalls/personality.S
+syscall_src += arch-sh/syscalls/unshare.S
 syscall_src += arch-sh/syscalls/futex.S
 syscall_src += arch-sh/syscalls/epoll_create.S
 syscall_src += arch-sh/syscalls/epoll_ctl.S
diff --git a/libc/arch-sh/syscalls/unshare.S b/libc/arch-sh/syscalls/unshare.S
new file mode 100644
index 0000000..59c1e7a
--- /dev/null
+++ b/libc/arch-sh/syscalls/unshare.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type unshare, @function
+    .globl unshare
+    .align 4
+
+unshare:
+
+    /* invoke trap */
+    mov.l   0f, r3  /* trap num */
+    trapa   #(1 + 0x10)
+
+    /* check return value */
+    cmp/pz  r0
+    bt      __NR_unshare_end
+
+    /* keep error number */
+    sts.l   pr, @-r15
+    mov.l   1f, r1
+    jsr     @r1
+    mov     r0, r4
+    lds.l   @r15+, pr
+
+__NR_unshare_end:
+    rts
+    nop
+
+    .align  2
+0:  .long   __NR_unshare
+1:  .long   __set_syscall_errno
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index ba85907..2c324da 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -173,6 +173,7 @@
 syscall_src += arch-x86/syscalls/klogctl.S
 syscall_src += arch-x86/syscalls/sysinfo.S
 syscall_src += arch-x86/syscalls/personality.S
+syscall_src += arch-x86/syscalls/unshare.S
 syscall_src += arch-x86/syscalls/futex.S
 syscall_src += arch-x86/syscalls/epoll_create.S
 syscall_src += arch-x86/syscalls/epoll_ctl.S
diff --git a/libc/arch-x86/syscalls/unshare.S b/libc/arch-x86/syscalls/unshare.S
new file mode 100644
index 0000000..ef31a35
--- /dev/null
+++ b/libc/arch-x86/syscalls/unshare.S
@@ -0,0 +1,23 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type unshare, @function
+    .globl unshare
+    .align 4
+
+unshare:
+    pushl   %ebx
+    mov     8(%esp), %ebx
+    movl    $__NR_unshare, %eax
+    int     $0x80
+    cmpl    $-129, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %ebx
+    ret
diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index 2243ced..f3ff06c 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -183,6 +183,7 @@
 #define __NR_getcpu                       (__NR_SYSCALL_BASE + 345)
 #define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 314)
 #define __NR_ioprio_get                   (__NR_SYSCALL_BASE + 315)
+#define __NR_unshare                      (__NR_SYSCALL_BASE + 337)
 #define __NR_epoll_create                 (__NR_SYSCALL_BASE + 250)
 #define __NR_epoll_ctl                    (__NR_SYSCALL_BASE + 251)
 #define __NR_epoll_wait                   (__NR_SYSCALL_BASE + 252)
@@ -229,6 +230,7 @@
 #define __NR_getcpu                       (__NR_SYSCALL_BASE + 318)
 #define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 289)
 #define __NR_ioprio_get                   (__NR_SYSCALL_BASE + 290)
+#define __NR_unshare                      (__NR_SYSCALL_BASE + 310)
 #define __NR_epoll_create                 (__NR_SYSCALL_BASE + 254)
 #define __NR_epoll_ctl                    (__NR_SYSCALL_BASE + 255)
 #define __NR_epoll_wait                   (__NR_SYSCALL_BASE + 256)
@@ -289,6 +291,7 @@
 #define __NR_getcpu                       (__NR_SYSCALL_BASE + 318)
 #define __NR_ioprio_set                   (__NR_SYSCALL_BASE + 288)
 #define __NR_ioprio_get                   (__NR_SYSCALL_BASE + 289)
+#define __NR_unshare                      (__NR_SYSCALL_BASE + 310)
 #define __NR_epoll_create                 (__NR_SYSCALL_BASE + 254)
 #define __NR_epoll_ctl                    (__NR_SYSCALL_BASE + 255)
 #define __NR_epoll_wait                   (__NR_SYSCALL_BASE + 256)
diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h
index da57f55..0bee499 100644
--- a/libc/include/sys/linux-unistd.h
+++ b/libc/include/sys/linux-unistd.h
@@ -200,6 +200,7 @@
 int              klogctl (int, char *, int);
 int              sysinfo (struct sysinfo *);
 int              personality (unsigned long);
+int              unshare (int);
 int              futex (void *, int, int, void *, void *, int);
 int              epoll_create (int size);
 int              epoll_ctl (int epfd, int op, int fd, struct epoll_event *event);