summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/unistd
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libc-top-half/musl/src/unistd/_exit.c7
-rw-r--r--libc-top-half/musl/src/unistd/access.c12
-rw-r--r--libc-top-half/musl/src/unistd/acct.c8
-rw-r--r--libc-top-half/musl/src/unistd/alarm.c10
-rw-r--r--libc-top-half/musl/src/unistd/chdir.c7
-rw-r--r--libc-top-half/musl/src/unistd/chown.c12
-rw-r--r--libc-top-half/musl/src/unistd/close.c19
-rw-r--r--libc-top-half/musl/src/unistd/ctermid.c7
-rw-r--r--libc-top-half/musl/src/unistd/dup.c7
-rw-r--r--libc-top-half/musl/src/unistd/dup2.c20
-rw-r--r--libc-top-half/musl/src/unistd/dup3.c24
-rw-r--r--libc-top-half/musl/src/unistd/faccessat.c61
-rw-r--r--libc-top-half/musl/src/unistd/fchdir.c15
-rw-r--r--libc-top-half/musl/src/unistd/fchown.c20
-rw-r--r--libc-top-half/musl/src/unistd/fchownat.c7
-rw-r--r--libc-top-half/musl/src/unistd/fdatasync.c7
-rw-r--r--libc-top-half/musl/src/unistd/fsync.c7
-rw-r--r--libc-top-half/musl/src/unistd/ftruncate.c9
-rw-r--r--libc-top-half/musl/src/unistd/getcwd.c25
-rw-r--r--libc-top-half/musl/src/unistd/getegid.c7
-rw-r--r--libc-top-half/musl/src/unistd/geteuid.c7
-rw-r--r--libc-top-half/musl/src/unistd/getgid.c7
-rw-r--r--libc-top-half/musl/src/unistd/getgroups.c7
-rw-r--r--libc-top-half/musl/src/unistd/gethostname.c13
-rw-r--r--libc-top-half/musl/src/unistd/getlogin.c7
-rw-r--r--libc-top-half/musl/src/unistd/getlogin_r.c12
-rw-r--r--libc-top-half/musl/src/unistd/getpgid.c7
-rw-r--r--libc-top-half/musl/src/unistd/getpgrp.c7
-rw-r--r--libc-top-half/musl/src/unistd/getpid.c7
-rw-r--r--libc-top-half/musl/src/unistd/getppid.c7
-rw-r--r--libc-top-half/musl/src/unistd/getsid.c7
-rw-r--r--libc-top-half/musl/src/unistd/getuid.c7
-rw-r--r--libc-top-half/musl/src/unistd/isatty.c13
-rw-r--r--libc-top-half/musl/src/unistd/lchown.c12
-rw-r--r--libc-top-half/musl/src/unistd/link.c12
-rw-r--r--libc-top-half/musl/src/unistd/linkat.c7
-rw-r--r--libc-top-half/musl/src/unistd/lseek.c23
-rw-r--r--libc-top-half/musl/src/unistd/mips/pipe.s20
-rw-r--r--libc-top-half/musl/src/unistd/mips64/pipe.s19
-rw-r--r--libc-top-half/musl/src/unistd/mipsn32/lseek.c20
-rw-r--r--libc-top-half/musl/src/unistd/mipsn32/pipe.s19
-rw-r--r--libc-top-half/musl/src/unistd/nice.c23
-rw-r--r--libc-top-half/musl/src/unistd/pause.c11
-rw-r--r--libc-top-half/musl/src/unistd/pipe.c11
-rw-r--r--libc-top-half/musl/src/unistd/pipe2.c22
-rw-r--r--libc-top-half/musl/src/unistd/posix_close.c6
-rw-r--r--libc-top-half/musl/src/unistd/pread.c9
-rw-r--r--libc-top-half/musl/src/unistd/preadv.c12
-rw-r--r--libc-top-half/musl/src/unistd/pwrite.c9
-rw-r--r--libc-top-half/musl/src/unistd/pwritev.c12
-rw-r--r--libc-top-half/musl/src/unistd/read.c7
-rw-r--r--libc-top-half/musl/src/unistd/readlink.c19
-rw-r--r--libc-top-half/musl/src/unistd/readlinkat.c14
-rw-r--r--libc-top-half/musl/src/unistd/readv.c7
-rw-r--r--libc-top-half/musl/src/unistd/renameat.c11
-rw-r--r--libc-top-half/musl/src/unistd/rmdir.c12
-rw-r--r--libc-top-half/musl/src/unistd/setegid.c8
-rw-r--r--libc-top-half/musl/src/unistd/seteuid.c8
-rw-r--r--libc-top-half/musl/src/unistd/setgid.c8
-rw-r--r--libc-top-half/musl/src/unistd/setpgid.c7
-rw-r--r--libc-top-half/musl/src/unistd/setpgrp.c6
-rw-r--r--libc-top-half/musl/src/unistd/setregid.c8
-rw-r--r--libc-top-half/musl/src/unistd/setresgid.c9
-rw-r--r--libc-top-half/musl/src/unistd/setresuid.c9
-rw-r--r--libc-top-half/musl/src/unistd/setreuid.c8
-rw-r--r--libc-top-half/musl/src/unistd/setsid.c7
-rw-r--r--libc-top-half/musl/src/unistd/setuid.c8
-rw-r--r--libc-top-half/musl/src/unistd/setxid.c34
-rw-r--r--libc-top-half/musl/src/unistd/sh/pipe.s27
-rw-r--r--libc-top-half/musl/src/unistd/sleep.c10
-rw-r--r--libc-top-half/musl/src/unistd/symlink.c12
-rw-r--r--libc-top-half/musl/src/unistd/symlinkat.c7
-rw-r--r--libc-top-half/musl/src/unistd/sync.c7
-rw-r--r--libc-top-half/musl/src/unistd/tcgetpgrp.c11
-rw-r--r--libc-top-half/musl/src/unistd/tcsetpgrp.c9
-rw-r--r--libc-top-half/musl/src/unistd/truncate.c9
-rw-r--r--libc-top-half/musl/src/unistd/ttyname.c14
-rw-r--r--libc-top-half/musl/src/unistd/ttyname_r.c28
-rw-r--r--libc-top-half/musl/src/unistd/ualarm.c13
-rw-r--r--libc-top-half/musl/src/unistd/unlink.c12
-rw-r--r--libc-top-half/musl/src/unistd/unlinkat.c7
-rw-r--r--libc-top-half/musl/src/unistd/usleep.c12
-rw-r--r--libc-top-half/musl/src/unistd/write.c7
-rw-r--r--libc-top-half/musl/src/unistd/writev.c7
-rw-r--r--libc-top-half/musl/src/unistd/x32/lseek.c15
85 files changed, 1043 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/unistd/_exit.c b/libc-top-half/musl/src/unistd/_exit.c
new file mode 100644
index 0000000..7699482
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/_exit.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include <stdlib.h>
+
+_Noreturn void _exit(int status)
+{
+ _Exit(status);
+}
diff --git a/libc-top-half/musl/src/unistd/access.c b/libc-top-half/musl/src/unistd/access.c
new file mode 100644
index 0000000..d6eed68
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/access.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int access(const char *filename, int amode)
+{
+#ifdef SYS_access
+ return syscall(SYS_access, filename, amode);
+#else
+ return syscall(SYS_faccessat, AT_FDCWD, filename, amode, 0);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/acct.c b/libc-top-half/musl/src/unistd/acct.c
new file mode 100644
index 0000000..308ffc3
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/acct.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int acct(const char *filename)
+{
+ return syscall(SYS_acct, filename);
+}
diff --git a/libc-top-half/musl/src/unistd/alarm.c b/libc-top-half/musl/src/unistd/alarm.c
new file mode 100644
index 0000000..a5e0c82
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/alarm.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <sys/time.h>
+#include "syscall.h"
+
+unsigned alarm(unsigned seconds)
+{
+ struct itimerval it = { .it_value.tv_sec = seconds }, old = { 0 };
+ setitimer(ITIMER_REAL, &it, &old);
+ return old.it_value.tv_sec + !!old.it_value.tv_usec;
+}
diff --git a/libc-top-half/musl/src/unistd/chdir.c b/libc-top-half/musl/src/unistd/chdir.c
new file mode 100644
index 0000000..5ba78b6
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/chdir.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int chdir(const char *path)
+{
+ return syscall(SYS_chdir, path);
+}
diff --git a/libc-top-half/musl/src/unistd/chown.c b/libc-top-half/musl/src/unistd/chown.c
new file mode 100644
index 0000000..14b0325
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/chown.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int chown(const char *path, uid_t uid, gid_t gid)
+{
+#ifdef SYS_chown
+ return syscall(SYS_chown, path, uid, gid);
+#else
+ return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, 0);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/close.c b/libc-top-half/musl/src/unistd/close.c
new file mode 100644
index 0000000..a2105f5
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/close.c
@@ -0,0 +1,19 @@
+#include <unistd.h>
+#include <errno.h>
+#include "aio_impl.h"
+#include "syscall.h"
+
+static int dummy(int fd)
+{
+ return fd;
+}
+
+weak_alias(dummy, __aio_close);
+
+int close(int fd)
+{
+ fd = __aio_close(fd);
+ int r = __syscall_cp(SYS_close, fd);
+ if (r == -EINTR) r = 0;
+ return __syscall_ret(r);
+}
diff --git a/libc-top-half/musl/src/unistd/ctermid.c b/libc-top-half/musl/src/unistd/ctermid.c
new file mode 100644
index 0000000..1612770
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/ctermid.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <string.h>
+
+char *ctermid(char *s)
+{
+ return s ? strcpy(s, "/dev/tty") : "/dev/tty";
+}
diff --git a/libc-top-half/musl/src/unistd/dup.c b/libc-top-half/musl/src/unistd/dup.c
new file mode 100644
index 0000000..7fee012
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/dup.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int dup(int fd)
+{
+ return syscall(SYS_dup, fd);
+}
diff --git a/libc-top-half/musl/src/unistd/dup2.c b/libc-top-half/musl/src/unistd/dup2.c
new file mode 100644
index 0000000..8f43c6d
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/dup2.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int dup2(int old, int new)
+{
+ int r;
+#ifdef SYS_dup2
+ while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+#else
+ if (old==new) {
+ r = __syscall(SYS_fcntl, old, F_GETFD);
+ if (r >= 0) return old;
+ } else {
+ while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
+ }
+#endif
+ return __syscall_ret(r);
+}
diff --git a/libc-top-half/musl/src/unistd/dup3.c b/libc-top-half/musl/src/unistd/dup3.c
new file mode 100644
index 0000000..f919f79
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/dup3.c
@@ -0,0 +1,24 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int __dup3(int old, int new, int flags)
+{
+ int r;
+#ifdef SYS_dup2
+ if (old==new) return __syscall_ret(-EINVAL);
+ if (flags & O_CLOEXEC) {
+ while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
+ if (r!=-ENOSYS) return __syscall_ret(r);
+ }
+ while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+ if (flags & O_CLOEXEC) __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);
+#else
+ while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
+#endif
+ return __syscall_ret(r);
+}
+
+weak_alias(__dup3, dup3);
diff --git a/libc-top-half/musl/src/unistd/faccessat.c b/libc-top-half/musl/src/unistd/faccessat.c
new file mode 100644
index 0000000..557503e
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/faccessat.c
@@ -0,0 +1,61 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include "syscall.h"
+#include "pthread_impl.h"
+
+struct ctx {
+ int fd;
+ const char *filename;
+ int amode;
+ int p;
+};
+
+static int checker(void *p)
+{
+ struct ctx *c = p;
+ int ret;
+ if (__syscall(SYS_setregid, __syscall(SYS_getegid), -1)
+ || __syscall(SYS_setreuid, __syscall(SYS_geteuid), -1))
+ __syscall(SYS_exit, 1);
+ ret = __syscall(SYS_faccessat, c->fd, c->filename, c->amode, 0);
+ __syscall(SYS_write, c->p, &ret, sizeof ret);
+ return 0;
+}
+
+int faccessat(int fd, const char *filename, int amode, int flag)
+{
+ if (flag) {
+ int ret = __syscall(SYS_faccessat2, fd, filename, amode, flag);
+ if (ret != -ENOSYS) return __syscall_ret(ret);
+ }
+
+ if (flag & ~AT_EACCESS)
+ return __syscall_ret(-EINVAL);
+
+ if (!flag || (getuid()==geteuid() && getgid()==getegid()))
+ return syscall(SYS_faccessat, fd, filename, amode);
+
+ char stack[1024];
+ sigset_t set;
+ pid_t pid;
+ int status;
+ int ret, p[2];
+
+ if (pipe2(p, O_CLOEXEC)) return __syscall_ret(-EBUSY);
+ struct ctx c = { .fd = fd, .filename = filename, .amode = amode, .p = p[1] };
+
+ __block_all_sigs(&set);
+
+ pid = __clone(checker, stack+sizeof stack, 0, &c);
+ __syscall(SYS_close, p[1]);
+
+ if (pid<0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret))
+ ret = -EBUSY;
+ __syscall(SYS_close, p[0]);
+ __syscall(SYS_wait4, pid, &status, __WCLONE, 0);
+
+ __restore_sigs(&set);
+
+ return __syscall_ret(ret);
+}
diff --git a/libc-top-half/musl/src/unistd/fchdir.c b/libc-top-half/musl/src/unistd/fchdir.c
new file mode 100644
index 0000000..dee45ba
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/fchdir.c
@@ -0,0 +1,15 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int fchdir(int fd)
+{
+ int ret = __syscall(SYS_fchdir, fd);
+ if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+ return __syscall_ret(ret);
+
+ char buf[15+3*sizeof(int)];
+ __procfdname(buf, fd);
+ return syscall(SYS_chdir, buf);
+}
diff --git a/libc-top-half/musl/src/unistd/fchown.c b/libc-top-half/musl/src/unistd/fchown.c
new file mode 100644
index 0000000..737b367
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/fchown.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int fchown(int fd, uid_t uid, gid_t gid)
+{
+ int ret = __syscall(SYS_fchown, fd, uid, gid);
+ if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
+ return __syscall_ret(ret);
+
+ char buf[15+3*sizeof(int)];
+ __procfdname(buf, fd);
+#ifdef SYS_chown
+ return syscall(SYS_chown, buf, uid, gid);
+#else
+ return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid, 0);
+#endif
+
+}
diff --git a/libc-top-half/musl/src/unistd/fchownat.c b/libc-top-half/musl/src/unistd/fchownat.c
new file mode 100644
index 0000000..62457a3
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/fchownat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag)
+{
+ return syscall(SYS_fchownat, fd, path, uid, gid, flag);
+}
diff --git a/libc-top-half/musl/src/unistd/fdatasync.c b/libc-top-half/musl/src/unistd/fdatasync.c
new file mode 100644
index 0000000..3895ae5
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/fdatasync.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fdatasync(int fd)
+{
+ return syscall_cp(SYS_fdatasync, fd);
+}
diff --git a/libc-top-half/musl/src/unistd/fsync.c b/libc-top-half/musl/src/unistd/fsync.c
new file mode 100644
index 0000000..7a1c80b
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/fsync.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int fsync(int fd)
+{
+ return syscall_cp(SYS_fsync, fd);
+}
diff --git a/libc-top-half/musl/src/unistd/ftruncate.c b/libc-top-half/musl/src/unistd/ftruncate.c
new file mode 100644
index 0000000..b41be0f
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/ftruncate.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int ftruncate(int fd, off_t length)
+{
+ return syscall(SYS_ftruncate, fd, __SYSCALL_LL_O(length));
+}
+
+weak_alias(ftruncate, ftruncate64);
diff --git a/libc-top-half/musl/src/unistd/getcwd.c b/libc-top-half/musl/src/unistd/getcwd.c
new file mode 100644
index 0000000..f407ffe
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getcwd.c
@@ -0,0 +1,25 @@
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include "syscall.h"
+
+char *getcwd(char *buf, size_t size)
+{
+ char tmp[buf ? 1 : PATH_MAX];
+ if (!buf) {
+ buf = tmp;
+ size = sizeof tmp;
+ } else if (!size) {
+ errno = EINVAL;
+ return 0;
+ }
+ long ret = syscall(SYS_getcwd, buf, size);
+ if (ret < 0)
+ return 0;
+ if (ret == 0 || buf[0] != '/') {
+ errno = ENOENT;
+ return 0;
+ }
+ return buf == tmp ? strdup(buf) : buf;
+}
diff --git a/libc-top-half/musl/src/unistd/getegid.c b/libc-top-half/musl/src/unistd/getegid.c
new file mode 100644
index 0000000..6287490
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getegid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+gid_t getegid(void)
+{
+ return __syscall(SYS_getegid);
+}
diff --git a/libc-top-half/musl/src/unistd/geteuid.c b/libc-top-half/musl/src/unistd/geteuid.c
new file mode 100644
index 0000000..88f2cd5
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/geteuid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+uid_t geteuid(void)
+{
+ return __syscall(SYS_geteuid);
+}
diff --git a/libc-top-half/musl/src/unistd/getgid.c b/libc-top-half/musl/src/unistd/getgid.c
new file mode 100644
index 0000000..1c9fe71
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getgid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+gid_t getgid(void)
+{
+ return __syscall(SYS_getgid);
+}
diff --git a/libc-top-half/musl/src/unistd/getgroups.c b/libc-top-half/musl/src/unistd/getgroups.c
new file mode 100644
index 0000000..0e6e63a
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getgroups.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int getgroups(int count, gid_t list[])
+{
+ return syscall(SYS_getgroups, count, list);
+}
diff --git a/libc-top-half/musl/src/unistd/gethostname.c b/libc-top-half/musl/src/unistd/gethostname.c
new file mode 100644
index 0000000..633ef57
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/gethostname.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <sys/utsname.h>
+
+int gethostname(char *name, size_t len)
+{
+ size_t i;
+ struct utsname uts;
+ if (uname(&uts)) return -1;
+ if (len > sizeof uts.nodename) len = sizeof uts.nodename;
+ for (i=0; i<len && (name[i] = uts.nodename[i]); i++);
+ if (i && i==len) name[i-1] = 0;
+ return 0;
+}
diff --git a/libc-top-half/musl/src/unistd/getlogin.c b/libc-top-half/musl/src/unistd/getlogin.c
new file mode 100644
index 0000000..0601191
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getlogin.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include <stdlib.h>
+
+char *getlogin(void)
+{
+ return getenv("LOGNAME");
+}
diff --git a/libc-top-half/musl/src/unistd/getlogin_r.c b/libc-top-half/musl/src/unistd/getlogin_r.c
new file mode 100644
index 0000000..53866c6
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getlogin_r.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+int getlogin_r(char *name, size_t size)
+{
+ char *logname = getlogin();
+ if (!logname) return ENXIO; /* or...? */
+ if (strlen(logname) >= size) return ERANGE;
+ strcpy(name, logname);
+ return 0;
+}
diff --git a/libc-top-half/musl/src/unistd/getpgid.c b/libc-top-half/musl/src/unistd/getpgid.c
new file mode 100644
index 0000000..d295bfd
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getpgid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpgid(pid_t pid)
+{
+ return syscall(SYS_getpgid, pid);
+}
diff --git a/libc-top-half/musl/src/unistd/getpgrp.c b/libc-top-half/musl/src/unistd/getpgrp.c
new file mode 100644
index 0000000..90e9bb0
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getpgrp.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpgrp(void)
+{
+ return __syscall(SYS_getpgid, 0);
+}
diff --git a/libc-top-half/musl/src/unistd/getpid.c b/libc-top-half/musl/src/unistd/getpid.c
new file mode 100644
index 0000000..a6d4e6d
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getpid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getpid(void)
+{
+ return __syscall(SYS_getpid);
+}
diff --git a/libc-top-half/musl/src/unistd/getppid.c b/libc-top-half/musl/src/unistd/getppid.c
new file mode 100644
index 0000000..05cade5
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getppid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getppid(void)
+{
+ return __syscall(SYS_getppid);
+}
diff --git a/libc-top-half/musl/src/unistd/getsid.c b/libc-top-half/musl/src/unistd/getsid.c
new file mode 100644
index 0000000..93ba690
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getsid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t getsid(pid_t pid)
+{
+ return syscall(SYS_getsid, pid);
+}
diff --git a/libc-top-half/musl/src/unistd/getuid.c b/libc-top-half/musl/src/unistd/getuid.c
new file mode 100644
index 0000000..61309d1
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/getuid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+uid_t getuid(void)
+{
+ return __syscall(SYS_getuid);
+}
diff --git a/libc-top-half/musl/src/unistd/isatty.c b/libc-top-half/musl/src/unistd/isatty.c
new file mode 100644
index 0000000..75a9c18
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/isatty.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include "syscall.h"
+
+int isatty(int fd)
+{
+ struct winsize wsz;
+ unsigned long r = syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz);
+ if (r == 0) return 1;
+ if (errno != EBADF) errno = ENOTTY;
+ return 0;
+}
diff --git a/libc-top-half/musl/src/unistd/lchown.c b/libc-top-half/musl/src/unistd/lchown.c
new file mode 100644
index 0000000..ccd5ee0
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/lchown.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int lchown(const char *path, uid_t uid, gid_t gid)
+{
+#ifdef SYS_lchown
+ return syscall(SYS_lchown, path, uid, gid);
+#else
+ return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/link.c b/libc-top-half/musl/src/unistd/link.c
new file mode 100644
index 0000000..feec18e
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/link.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int link(const char *existing, const char *new)
+{
+#ifdef SYS_link
+ return syscall(SYS_link, existing, new);
+#else
+ return syscall(SYS_linkat, AT_FDCWD, existing, AT_FDCWD, new, 0);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/linkat.c b/libc-top-half/musl/src/unistd/linkat.c
new file mode 100644
index 0000000..6a9a0b7
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/linkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int linkat(int fd1, const char *existing, int fd2, const char *new, int flag)
+{
+ return syscall(SYS_linkat, fd1, existing, fd2, new, flag);
+}
diff --git a/libc-top-half/musl/src/unistd/lseek.c b/libc-top-half/musl/src/unistd/lseek.c
new file mode 100644
index 0000000..48a638a
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/lseek.c
@@ -0,0 +1,23 @@
+#include <unistd.h>
+#include "syscall.h"
+
+off_t __lseek(int fd, off_t offset, int whence)
+{
+#ifdef SYS__llseek
+ off_t result;
+#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
+ return syscall(SYS__llseek, fd, offset>>32, offset, &result, whence) ? -1 : result;
+#else
+ return llseek(fd, offset>>32, offset, &result, whence) ? -1 : result;
+#endif
+#else
+#ifdef __wasilibc_unmodified_upstream // WASI has no syscall
+ return syscall(SYS_lseek, fd, offset, whence);
+#else
+ return lseek(fd, offset, whence);
+#endif
+#endif
+}
+
+weak_alias(__lseek, lseek);
+weak_alias(__lseek, lseek64);
diff --git a/libc-top-half/musl/src/unistd/mips/pipe.s b/libc-top-half/musl/src/unistd/mips/pipe.s
new file mode 100644
index 0000000..ba2c39a
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/mips/pipe.s
@@ -0,0 +1,20 @@
+.set noreorder
+
+.global pipe
+.type pipe,@function
+pipe:
+ lui $gp, %hi(_gp_disp)
+ addiu $gp, %lo(_gp_disp)
+ addu $gp, $gp, $25
+ li $2, 4042
+ syscall
+ beq $7, $0, 1f
+ nop
+ lw $25, %call16(__syscall_ret)($gp)
+ jr $25
+ subu $4, $0, $2
+1: sw $2, 0($4)
+ sw $3, 4($4)
+ move $2, $0
+ jr $ra
+ nop
diff --git a/libc-top-half/musl/src/unistd/mips64/pipe.s b/libc-top-half/musl/src/unistd/mips64/pipe.s
new file mode 100644
index 0000000..f8a27dc
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/mips64/pipe.s
@@ -0,0 +1,19 @@
+.set noreorder
+.global pipe
+.type pipe,@function
+pipe:
+ lui $3, %hi(%neg(%gp_rel(pipe)))
+ daddiu $3, $3, %lo(%neg(%gp_rel(pipe)))
+ daddu $3, $3, $25
+ li $2, 5021
+ syscall
+ beq $7, $0, 1f
+ nop
+ ld $25, %got_disp(__syscall_ret)($3)
+ jr $25
+ dsubu $4, $0, $2
+1: sw $2, 0($4)
+ sw $3, 4($4)
+ move $2, $0
+ jr $ra
+ nop
diff --git a/libc-top-half/musl/src/unistd/mipsn32/lseek.c b/libc-top-half/musl/src/unistd/mipsn32/lseek.c
new file mode 100644
index 0000000..60e74a5
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/mipsn32/lseek.c
@@ -0,0 +1,20 @@
+#include <unistd.h>
+#include "syscall.h"
+
+off_t __lseek(int fd, off_t offset, int whence)
+{
+ register long long r4 __asm__("$4") = fd;
+ register long long r5 __asm__("$5") = offset;
+ register long long r6 __asm__("$6") = whence;
+ register long long r7 __asm__("$7");
+ register long long r2 __asm__("$2") = SYS_lseek;
+ __asm__ __volatile__ (
+ "syscall"
+ : "+&r"(r2), "=r"(r7)
+ : "r"(r4), "r"(r5), "r"(r6)
+ : SYSCALL_CLOBBERLIST);
+ return r7 ? __syscall_ret(-r2) : r2;
+}
+
+weak_alias(__lseek, lseek);
+weak_alias(__lseek, lseek64);
diff --git a/libc-top-half/musl/src/unistd/mipsn32/pipe.s b/libc-top-half/musl/src/unistd/mipsn32/pipe.s
new file mode 100644
index 0000000..80f882e
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/mipsn32/pipe.s
@@ -0,0 +1,19 @@
+.set noreorder
+.global pipe
+.type pipe,@function
+pipe:
+ lui $3, %hi(%neg(%gp_rel(pipe)))
+ addiu $3, $3, %lo(%neg(%gp_rel(pipe)))
+ addu $3, $3, $25
+ li $2, 6021
+ syscall
+ beq $7, $0, 1f
+ nop
+ lw $25, %got_disp(__syscall_ret)($3)
+ jr $25
+ subu $4, $0, $2
+1: sw $2, 0($4)
+ sw $3, 4($4)
+ move $2, $0
+ jr $ra
+ nop
diff --git a/libc-top-half/musl/src/unistd/nice.c b/libc-top-half/musl/src/unistd/nice.c
new file mode 100644
index 0000000..1c2295f
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/nice.c
@@ -0,0 +1,23 @@
+#include <unistd.h>
+#include <errno.h>
+#include <sys/resource.h>
+#include <limits.h>
+#include "syscall.h"
+
+int nice(int inc)
+{
+ int prio = inc;
+ // Only query old priority if it can affect the result.
+ // This also avoids issues with integer overflow.
+ if (inc > -2*NZERO && inc < 2*NZERO)
+ prio += getpriority(PRIO_PROCESS, 0);
+ if (prio > NZERO-1) prio = NZERO-1;
+ if (prio < -NZERO) prio = -NZERO;
+ if (setpriority(PRIO_PROCESS, 0, prio)) {
+ if (errno == EACCES)
+ errno = EPERM;
+ return -1;
+ } else {
+ return prio;
+ }
+}
diff --git a/libc-top-half/musl/src/unistd/pause.c b/libc-top-half/musl/src/unistd/pause.c
new file mode 100644
index 0000000..90bbf4c
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/pause.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int pause(void)
+{
+#ifdef SYS_pause
+ return syscall_cp(SYS_pause);
+#else
+ return syscall_cp(SYS_ppoll, 0, 0, 0, 0);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/pipe.c b/libc-top-half/musl/src/unistd/pipe.c
new file mode 100644
index 0000000..d07b8d2
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/pipe.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int pipe(int fd[2])
+{
+#ifdef SYS_pipe
+ return syscall(SYS_pipe, fd);
+#else
+ return syscall(SYS_pipe2, fd, 0);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/pipe2.c b/libc-top-half/musl/src/unistd/pipe2.c
new file mode 100644
index 0000000..f24f74f
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/pipe2.c
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int pipe2(int fd[2], int flag)
+{
+ if (!flag) return pipe(fd);
+ int ret = __syscall(SYS_pipe2, fd, flag);
+ if (ret != -ENOSYS) return __syscall_ret(ret);
+ ret = pipe(fd);
+ if (ret) return ret;
+ if (flag & O_CLOEXEC) {
+ __syscall(SYS_fcntl, fd[0], F_SETFD, FD_CLOEXEC);
+ __syscall(SYS_fcntl, fd[1], F_SETFD, FD_CLOEXEC);
+ }
+ if (flag & O_NONBLOCK) {
+ __syscall(SYS_fcntl, fd[0], F_SETFL, O_NONBLOCK);
+ __syscall(SYS_fcntl, fd[1], F_SETFL, O_NONBLOCK);
+ }
+ return 0;
+}
diff --git a/libc-top-half/musl/src/unistd/posix_close.c b/libc-top-half/musl/src/unistd/posix_close.c
new file mode 100644
index 0000000..90f51a8
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/posix_close.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+int posix_close(int fd, int flags)
+{
+ return close(fd);
+}
diff --git a/libc-top-half/musl/src/unistd/pread.c b/libc-top-half/musl/src/unistd/pread.c
new file mode 100644
index 0000000..5681b04
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/pread.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
+{
+ return syscall_cp(SYS_pread, fd, buf, size, __SYSCALL_LL_PRW(ofs));
+}
+
+weak_alias(pread, pread64);
diff --git a/libc-top-half/musl/src/unistd/preadv.c b/libc-top-half/musl/src/unistd/preadv.c
new file mode 100644
index 0000000..8376d60
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/preadv.c
@@ -0,0 +1,12 @@
+#define _BSD_SOURCE
+#include <sys/uio.h>
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs)
+{
+ return syscall_cp(SYS_preadv, fd, iov, count,
+ (long)(ofs), (long)(ofs>>32));
+}
+
+weak_alias(preadv, preadv64);
diff --git a/libc-top-half/musl/src/unistd/pwrite.c b/libc-top-half/musl/src/unistd/pwrite.c
new file mode 100644
index 0000000..ca37657
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/pwrite.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs)
+{
+ return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs));
+}
+
+weak_alias(pwrite, pwrite64);
diff --git a/libc-top-half/musl/src/unistd/pwritev.c b/libc-top-half/musl/src/unistd/pwritev.c
new file mode 100644
index 0000000..f5a612c
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/pwritev.c
@@ -0,0 +1,12 @@
+#define _BSD_SOURCE
+#include <sys/uio.h>
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs)
+{
+ return syscall_cp(SYS_pwritev, fd, iov, count,
+ (long)(ofs), (long)(ofs>>32));
+}
+
+weak_alias(pwritev, pwritev64);
diff --git a/libc-top-half/musl/src/unistd/read.c b/libc-top-half/musl/src/unistd/read.c
new file mode 100644
index 0000000..f3589c0
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/read.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t read(int fd, void *buf, size_t count)
+{
+ return syscall_cp(SYS_read, fd, buf, count);
+}
diff --git a/libc-top-half/musl/src/unistd/readlink.c b/libc-top-half/musl/src/unistd/readlink.c
new file mode 100644
index 0000000..32f4537
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/readlink.c
@@ -0,0 +1,19 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
+{
+ char dummy[1];
+ if (!bufsize) {
+ buf = dummy;
+ bufsize = 1;
+ }
+#ifdef SYS_readlink
+ int r = __syscall(SYS_readlink, path, buf, bufsize);
+#else
+ int r = __syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
+#endif
+ if (buf == dummy && r > 0) r = 0;
+ return __syscall_ret(r);
+}
diff --git a/libc-top-half/musl/src/unistd/readlinkat.c b/libc-top-half/musl/src/unistd/readlinkat.c
new file mode 100644
index 0000000..f79d3d1
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/readlinkat.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize)
+{
+ char dummy[1];
+ if (!bufsize) {
+ buf = dummy;
+ bufsize = 1;
+ }
+ int r = __syscall(SYS_readlinkat, fd, path, buf, bufsize);
+ if (buf == dummy && r > 0) r = 0;
+ return __syscall_ret(r);
+}
diff --git a/libc-top-half/musl/src/unistd/readv.c b/libc-top-half/musl/src/unistd/readv.c
new file mode 100644
index 0000000..91e6de8
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/readv.c
@@ -0,0 +1,7 @@
+#include <sys/uio.h>
+#include "syscall.h"
+
+ssize_t readv(int fd, const struct iovec *iov, int count)
+{
+ return syscall_cp(SYS_readv, fd, iov, count);
+}
diff --git a/libc-top-half/musl/src/unistd/renameat.c b/libc-top-half/musl/src/unistd/renameat.c
new file mode 100644
index 0000000..c3b40a2
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/renameat.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include "syscall.h"
+
+int renameat(int oldfd, const char *old, int newfd, const char *new)
+{
+#ifdef SYS_renameat
+ return syscall(SYS_renameat, oldfd, old, newfd, new);
+#else
+ return syscall(SYS_renameat2, oldfd, old, newfd, new, 0);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/rmdir.c b/libc-top-half/musl/src/unistd/rmdir.c
new file mode 100644
index 0000000..6825ffc
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/rmdir.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int rmdir(const char *path)
+{
+#ifdef SYS_rmdir
+ return syscall(SYS_rmdir, path);
+#else
+ return syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/setegid.c b/libc-top-half/musl/src/unistd/setegid.c
new file mode 100644
index 0000000..e6da257
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setegid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "libc.h"
+#include "syscall.h"
+
+int setegid(gid_t egid)
+{
+ return __setxid(SYS_setresgid, -1, egid, -1);
+}
diff --git a/libc-top-half/musl/src/unistd/seteuid.c b/libc-top-half/musl/src/unistd/seteuid.c
new file mode 100644
index 0000000..ef8b9df
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/seteuid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int seteuid(uid_t euid)
+{
+ return __setxid(SYS_setresuid, -1, euid, -1);
+}
diff --git a/libc-top-half/musl/src/unistd/setgid.c b/libc-top-half/musl/src/unistd/setgid.c
new file mode 100644
index 0000000..bae4616
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setgid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setgid(gid_t gid)
+{
+ return __setxid(SYS_setgid, gid, 0, 0);
+}
diff --git a/libc-top-half/musl/src/unistd/setpgid.c b/libc-top-half/musl/src/unistd/setpgid.c
new file mode 100644
index 0000000..0616069
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setpgid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int setpgid(pid_t pid, pid_t pgid)
+{
+ return syscall(SYS_setpgid, pid, pgid);
+}
diff --git a/libc-top-half/musl/src/unistd/setpgrp.c b/libc-top-half/musl/src/unistd/setpgrp.c
new file mode 100644
index 0000000..a2a37f6
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setpgrp.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+
+pid_t setpgrp(void)
+{
+ return setpgid(0, 0);
+}
diff --git a/libc-top-half/musl/src/unistd/setregid.c b/libc-top-half/musl/src/unistd/setregid.c
new file mode 100644
index 0000000..f5a8972
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setregid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setregid(gid_t rgid, gid_t egid)
+{
+ return __setxid(SYS_setregid, rgid, egid, 0);
+}
diff --git a/libc-top-half/musl/src/unistd/setresgid.c b/libc-top-half/musl/src/unistd/setresgid.c
new file mode 100644
index 0000000..b9af540
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setresgid.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+{
+ return __setxid(SYS_setresgid, rgid, egid, sgid);
+}
diff --git a/libc-top-half/musl/src/unistd/setresuid.c b/libc-top-half/musl/src/unistd/setresuid.c
new file mode 100644
index 0000000..83692b4
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setresuid.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setresuid(uid_t ruid, uid_t euid, uid_t suid)
+{
+ return __setxid(SYS_setresuid, ruid, euid, suid);
+}
diff --git a/libc-top-half/musl/src/unistd/setreuid.c b/libc-top-half/musl/src/unistd/setreuid.c
new file mode 100644
index 0000000..3fcc59e
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setreuid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setreuid(uid_t ruid, uid_t euid)
+{
+ return __setxid(SYS_setreuid, ruid, euid, 0);
+}
diff --git a/libc-top-half/musl/src/unistd/setsid.c b/libc-top-half/musl/src/unistd/setsid.c
new file mode 100644
index 0000000..609bbe4
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setsid.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+pid_t setsid(void)
+{
+ return syscall(SYS_setsid);
+}
diff --git a/libc-top-half/musl/src/unistd/setuid.c b/libc-top-half/musl/src/unistd/setuid.c
new file mode 100644
index 0000000..602ecbb
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setuid.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include "syscall.h"
+#include "libc.h"
+
+int setuid(uid_t uid)
+{
+ return __setxid(SYS_setuid, uid, 0, 0);
+}
diff --git a/libc-top-half/musl/src/unistd/setxid.c b/libc-top-half/musl/src/unistd/setxid.c
new file mode 100644
index 0000000..487c1a1
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/setxid.c
@@ -0,0 +1,34 @@
+#include <unistd.h>
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+
+struct ctx {
+ int id, eid, sid;
+ int nr, ret;
+};
+
+static void do_setxid(void *p)
+{
+ struct ctx *c = p;
+ if (c->ret<0) return;
+ int ret = __syscall(c->nr, c->id, c->eid, c->sid);
+ if (ret && !c->ret) {
+ /* If one thread fails to set ids after another has already
+ * succeeded, forcibly killing the process is the only safe
+ * thing to do. State is inconsistent and dangerous. Use
+ * SIGKILL because it is uncatchable. */
+ __block_all_sigs(0);
+ __syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL);
+ }
+ c->ret = ret;
+}
+
+int __setxid(int nr, int id, int eid, int sid)
+{
+ /* ret is initially nonzero so that failure of the first thread does not
+ * trigger the safety kill above. */
+ struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .ret = 1 };
+ __synccall(do_setxid, &c);
+ return __syscall_ret(c.ret);
+}
diff --git a/libc-top-half/musl/src/unistd/sh/pipe.s b/libc-top-half/musl/src/unistd/sh/pipe.s
new file mode 100644
index 0000000..46c4908
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/sh/pipe.s
@@ -0,0 +1,27 @@
+.global pipe
+.type pipe, @function
+pipe:
+ mov #42, r3
+ trapa #31
+
+ ! work around hardware bug
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+ cmp/pz r0
+ bt 1f
+
+ mov.l L1, r1
+ braf r1
+ mov r0, r4
+
+1: mov.l r0, @(0,r4)
+ mov.l r1, @(4,r4)
+ rts
+ mov #0, r0
+
+.align 2
+L1: .long __syscall_ret@PLT-(1b-.)
diff --git a/libc-top-half/musl/src/unistd/sleep.c b/libc-top-half/musl/src/unistd/sleep.c
new file mode 100644
index 0000000..d645094
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/sleep.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <time.h>
+
+unsigned sleep(unsigned seconds)
+{
+ struct timespec tv = { .tv_sec = seconds, .tv_nsec = 0 };
+ if (nanosleep(&tv, &tv))
+ return tv.tv_sec;
+ return 0;
+}
diff --git a/libc-top-half/musl/src/unistd/symlink.c b/libc-top-half/musl/src/unistd/symlink.c
new file mode 100644
index 0000000..0973d78
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/symlink.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int symlink(const char *existing, const char *new)
+{
+#ifdef SYS_symlink
+ return syscall(SYS_symlink, existing, new);
+#else
+ return syscall(SYS_symlinkat, existing, AT_FDCWD, new);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/symlinkat.c b/libc-top-half/musl/src/unistd/symlinkat.c
new file mode 100644
index 0000000..d1c59b4
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/symlinkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int symlinkat(const char *existing, int fd, const char *new)
+{
+ return syscall(SYS_symlinkat, existing, fd, new);
+}
diff --git a/libc-top-half/musl/src/unistd/sync.c b/libc-top-half/musl/src/unistd/sync.c
new file mode 100644
index 0000000..f18765a
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/sync.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+void sync(void)
+{
+ __syscall(SYS_sync);
+}
diff --git a/libc-top-half/musl/src/unistd/tcgetpgrp.c b/libc-top-half/musl/src/unistd/tcgetpgrp.c
new file mode 100644
index 0000000..50080c7
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/tcgetpgrp.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+pid_t tcgetpgrp(int fd)
+{
+ int pgrp;
+ if (ioctl(fd, TIOCGPGRP, &pgrp) < 0)
+ return -1;
+ return pgrp;
+}
diff --git a/libc-top-half/musl/src/unistd/tcsetpgrp.c b/libc-top-half/musl/src/unistd/tcsetpgrp.c
new file mode 100644
index 0000000..67c38cb
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/tcsetpgrp.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int tcsetpgrp(int fd, pid_t pgrp)
+{
+ int pgrp_int = pgrp;
+ return ioctl(fd, TIOCSPGRP, &pgrp_int);
+}
diff --git a/libc-top-half/musl/src/unistd/truncate.c b/libc-top-half/musl/src/unistd/truncate.c
new file mode 100644
index 0000000..9729680
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/truncate.c
@@ -0,0 +1,9 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int truncate(const char *path, off_t length)
+{
+ return syscall(SYS_truncate, path, __SYSCALL_LL_O(length));
+}
+
+weak_alias(truncate, truncate64);
diff --git a/libc-top-half/musl/src/unistd/ttyname.c b/libc-top-half/musl/src/unistd/ttyname.c
new file mode 100644
index 0000000..0f3e114
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/ttyname.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+
+char *ttyname(int fd)
+{
+ static char buf[TTY_NAME_MAX];
+ int result;
+ if ((result = ttyname_r(fd, buf, sizeof buf))) {
+ errno = result;
+ return NULL;
+ }
+ return buf;
+}
diff --git a/libc-top-half/musl/src/unistd/ttyname_r.c b/libc-top-half/musl/src/unistd/ttyname_r.c
new file mode 100644
index 0000000..82acb75
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/ttyname_r.c
@@ -0,0 +1,28 @@
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include "syscall.h"
+
+int ttyname_r(int fd, char *name, size_t size)
+{
+ struct stat st1, st2;
+ char procname[sizeof "/proc/self/fd/" + 3*sizeof(int) + 2];
+ ssize_t l;
+
+ if (!isatty(fd)) return errno;
+
+ __procfdname(procname, fd);
+ l = readlink(procname, name, size);
+
+ if (l < 0) return errno;
+ else if (l == size) return ERANGE;
+
+ name[l] = 0;
+
+ if (stat(name, &st1) || fstat(fd, &st2))
+ return errno;
+ if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
+ return ENODEV;
+
+ return 0;
+}
diff --git a/libc-top-half/musl/src/unistd/ualarm.c b/libc-top-half/musl/src/unistd/ualarm.c
new file mode 100644
index 0000000..2985855
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/ualarm.c
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/time.h>
+
+unsigned ualarm(unsigned value, unsigned interval)
+{
+ struct itimerval it = {
+ .it_interval.tv_usec = interval,
+ .it_value.tv_usec = value
+ }, it_old;
+ setitimer(ITIMER_REAL, &it, &it_old);
+ return it_old.it_value.tv_sec*1000000 + it_old.it_value.tv_usec;
+}
diff --git a/libc-top-half/musl/src/unistd/unlink.c b/libc-top-half/musl/src/unistd/unlink.c
new file mode 100644
index 0000000..c40c28d
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/unlink.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int unlink(const char *path)
+{
+#ifdef SYS_unlink
+ return syscall(SYS_unlink, path);
+#else
+ return syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
+}
diff --git a/libc-top-half/musl/src/unistd/unlinkat.c b/libc-top-half/musl/src/unistd/unlinkat.c
new file mode 100644
index 0000000..e0e25d2
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/unlinkat.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+int unlinkat(int fd, const char *path, int flag)
+{
+ return syscall(SYS_unlinkat, fd, path, flag);
+}
diff --git a/libc-top-half/musl/src/unistd/usleep.c b/libc-top-half/musl/src/unistd/usleep.c
new file mode 100644
index 0000000..6c96652
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/usleep.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <time.h>
+
+int usleep(unsigned useconds)
+{
+ struct timespec tv = {
+ .tv_sec = useconds/1000000,
+ .tv_nsec = (useconds%1000000)*1000
+ };
+ return nanosleep(&tv, &tv);
+}
diff --git a/libc-top-half/musl/src/unistd/write.c b/libc-top-half/musl/src/unistd/write.c
new file mode 100644
index 0000000..8fd5bc5
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/write.c
@@ -0,0 +1,7 @@
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t write(int fd, const void *buf, size_t count)
+{
+ return syscall_cp(SYS_write, fd, buf, count);
+}
diff --git a/libc-top-half/musl/src/unistd/writev.c b/libc-top-half/musl/src/unistd/writev.c
new file mode 100644
index 0000000..5a46c95
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/writev.c
@@ -0,0 +1,7 @@
+#include <sys/uio.h>
+#include "syscall.h"
+
+ssize_t writev(int fd, const struct iovec *iov, int count)
+{
+ return syscall_cp(SYS_writev, fd, iov, count);
+}
diff --git a/libc-top-half/musl/src/unistd/x32/lseek.c b/libc-top-half/musl/src/unistd/x32/lseek.c
new file mode 100644
index 0000000..3263642
--- /dev/null
+++ b/libc-top-half/musl/src/unistd/x32/lseek.c
@@ -0,0 +1,15 @@
+#include <unistd.h>
+#include "syscall.h"
+
+off_t __lseek(int fd, off_t offset, int whence)
+{
+ off_t ret;
+ __asm__ __volatile__ ("syscall"
+ : "=a"(ret)
+ : "a"(SYS_lseek), "D"(fd), "S"(offset), "d"(whence)
+ : "rcx", "r11", "memory");
+ return ret < 0 ? __syscall_ret(ret) : ret;
+}
+
+weak_alias(__lseek, lseek);
+weak_alias(__lseek, lseek64);