summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/linux
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 13:54:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 13:54:38 +0000
commit8c1ab65c0f548d20b7f177bdb736daaf603340e1 (patch)
treedf55b7e75bf43f2bf500845b105afe3ac3a5157e /libc-top-half/musl/src/linux
parentInitial commit. (diff)
downloadwasi-libc-upstream/0.0_git20221206.8b7148f.tar.xz
wasi-libc-upstream/0.0_git20221206.8b7148f.zip
Adding upstream version 0.0~git20221206.8b7148f.upstream/0.0_git20221206.8b7148f
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libc-top-half/musl/src/linux')
-rw-r--r--libc-top-half/musl/src/linux/adjtime.c27
-rw-r--r--libc-top-half/musl/src/linux/adjtimex.c7
-rw-r--r--libc-top-half/musl/src/linux/arch_prctl.c7
-rw-r--r--libc-top-half/musl/src/linux/brk.c9
-rw-r--r--libc-top-half/musl/src/linux/cache.c50
-rw-r--r--libc-top-half/musl/src/linux/cap.c11
-rw-r--r--libc-top-half/musl/src/linux/chroot.c8
-rw-r--r--libc-top-half/musl/src/linux/clock_adjtime.c151
-rw-r--r--libc-top-half/musl/src/linux/clone.c21
-rw-r--r--libc-top-half/musl/src/linux/copy_file_range.c8
-rw-r--r--libc-top-half/musl/src/linux/epoll.c37
-rw-r--r--libc-top-half/musl/src/linux/eventfd.c23
-rw-r--r--libc-top-half/musl/src/linux/fallocate.c12
-rw-r--r--libc-top-half/musl/src/linux/fanotify.c14
-rw-r--r--libc-top-half/musl/src/linux/flock.c7
-rw-r--r--libc-top-half/musl/src/linux/getdents.c12
-rw-r--r--libc-top-half/musl/src/linux/getrandom.c7
-rw-r--r--libc-top-half/musl/src/linux/gettid.c8
-rw-r--r--libc-top-half/musl/src/linux/inotify.c26
-rw-r--r--libc-top-half/musl/src/linux/ioperm.c10
-rw-r--r--libc-top-half/musl/src/linux/iopl.c10
-rw-r--r--libc-top-half/musl/src/linux/klogctl.c7
-rw-r--r--libc-top-half/musl/src/linux/membarrier.c72
-rw-r--r--libc-top-half/musl/src/linux/memfd_create.c8
-rw-r--r--libc-top-half/musl/src/linux/mlock2.c10
-rw-r--r--libc-top-half/musl/src/linux/module.c11
-rw-r--r--libc-top-half/musl/src/linux/mount.c17
-rw-r--r--libc-top-half/musl/src/linux/name_to_handle_at.c10
-rw-r--r--libc-top-half/musl/src/linux/open_by_handle_at.c8
-rw-r--r--libc-top-half/musl/src/linux/personality.c8
-rw-r--r--libc-top-half/musl/src/linux/pivot_root.c6
-rw-r--r--libc-top-half/musl/src/linux/ppoll.c26
-rw-r--r--libc-top-half/musl/src/linux/prctl.c14
-rw-r--r--libc-top-half/musl/src/linux/prlimit.c26
-rw-r--r--libc-top-half/musl/src/linux/process_vm.c13
-rw-r--r--libc-top-half/musl/src/linux/ptrace.c29
-rw-r--r--libc-top-half/musl/src/linux/quotactl.c7
-rw-r--r--libc-top-half/musl/src/linux/readahead.c8
-rw-r--r--libc-top-half/musl/src/linux/reboot.c7
-rw-r--r--libc-top-half/musl/src/linux/remap_file_pages.c8
-rw-r--r--libc-top-half/musl/src/linux/sbrk.c11
-rw-r--r--libc-top-half/musl/src/linux/sendfile.c9
-rw-r--r--libc-top-half/musl/src/linux/setfsgid.c7
-rw-r--r--libc-top-half/musl/src/linux/setfsuid.c7
-rw-r--r--libc-top-half/musl/src/linux/setgroups.c36
-rw-r--r--libc-top-half/musl/src/linux/sethostname.c8
-rw-r--r--libc-top-half/musl/src/linux/setns.c8
-rw-r--r--libc-top-half/musl/src/linux/settimeofday.c13
-rw-r--r--libc-top-half/musl/src/linux/signalfd.c21
-rw-r--r--libc-top-half/musl/src/linux/splice.c8
-rw-r--r--libc-top-half/musl/src/linux/stime.c9
-rw-r--r--libc-top-half/musl/src/linux/swap.c12
-rw-r--r--libc-top-half/musl/src/linux/sync_file_range.c17
-rw-r--r--libc-top-half/musl/src/linux/syncfs.c8
-rw-r--r--libc-top-half/musl/src/linux/sysinfo.c9
-rw-r--r--libc-top-half/musl/src/linux/tee.c8
-rw-r--r--libc-top-half/musl/src/linux/timerfd.c59
-rw-r--r--libc-top-half/musl/src/linux/unshare.c8
-rw-r--r--libc-top-half/musl/src/linux/utimes.c8
-rw-r--r--libc-top-half/musl/src/linux/vhangup.c8
-rw-r--r--libc-top-half/musl/src/linux/vmsplice.c8
-rw-r--r--libc-top-half/musl/src/linux/wait3.c9
-rw-r--r--libc-top-half/musl/src/linux/wait4.c39
-rw-r--r--libc-top-half/musl/src/linux/x32/sysinfo.c49
-rw-r--r--libc-top-half/musl/src/linux/xattr.c62
65 files changed, 1201 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/linux/adjtime.c b/libc-top-half/musl/src/linux/adjtime.c
new file mode 100644
index 0000000..5a707f2
--- /dev/null
+++ b/libc-top-half/musl/src/linux/adjtime.c
@@ -0,0 +1,27 @@
+#define _GNU_SOURCE
+#include <sys/time.h>
+#include <sys/timex.h>
+#include <errno.h>
+#include "syscall.h"
+
+int adjtime(const struct timeval *in, struct timeval *out)
+{
+ struct timex tx = { 0 };
+ if (in) {
+ if (in->tv_sec > 1000 || in->tv_usec > 1000000000) {
+ errno = EINVAL;
+ return -1;
+ }
+ tx.offset = in->tv_sec*1000000 + in->tv_usec;
+ tx.modes = ADJ_OFFSET_SINGLESHOT;
+ }
+ if (adjtimex(&tx) < 0) return -1;
+ if (out) {
+ out->tv_sec = tx.offset / 1000000;
+ if ((out->tv_usec = tx.offset % 1000000) < 0) {
+ out->tv_sec--;
+ out->tv_usec += 1000000;
+ }
+ }
+ return 0;
+}
diff --git a/libc-top-half/musl/src/linux/adjtimex.c b/libc-top-half/musl/src/linux/adjtimex.c
new file mode 100644
index 0000000..e9d727c
--- /dev/null
+++ b/libc-top-half/musl/src/linux/adjtimex.c
@@ -0,0 +1,7 @@
+#include <sys/timex.h>
+#include <time.h>
+
+int adjtimex(struct timex *tx)
+{
+ return clock_adjtime(CLOCK_REALTIME, tx);
+}
diff --git a/libc-top-half/musl/src/linux/arch_prctl.c b/libc-top-half/musl/src/linux/arch_prctl.c
new file mode 100644
index 0000000..9460365
--- /dev/null
+++ b/libc-top-half/musl/src/linux/arch_prctl.c
@@ -0,0 +1,7 @@
+#include "syscall.h"
+#ifdef SYS_arch_prctl
+int arch_prctl(int code, unsigned long addr)
+{
+ return syscall(SYS_arch_prctl, code, addr);
+}
+#endif
diff --git a/libc-top-half/musl/src/linux/brk.c b/libc-top-half/musl/src/linux/brk.c
new file mode 100644
index 0000000..a6173e0
--- /dev/null
+++ b/libc-top-half/musl/src/linux/brk.c
@@ -0,0 +1,9 @@
+#define _BSD_SOURCE
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+
+int brk(void *end)
+{
+ return __syscall_ret(-ENOMEM);
+}
diff --git a/libc-top-half/musl/src/linux/cache.c b/libc-top-half/musl/src/linux/cache.c
new file mode 100644
index 0000000..0eb051c
--- /dev/null
+++ b/libc-top-half/musl/src/linux/cache.c
@@ -0,0 +1,50 @@
+#include <errno.h>
+#include "syscall.h"
+#include "atomic.h"
+
+#ifdef SYS_cacheflush
+int _flush_cache(void *addr, int len, int op)
+{
+ return syscall(SYS_cacheflush, addr, len, op);
+}
+weak_alias(_flush_cache, cacheflush);
+#endif
+
+#ifdef SYS_cachectl
+int __cachectl(void *addr, int len, int op)
+{
+ return syscall(SYS_cachectl, addr, len, op);
+}
+weak_alias(__cachectl, cachectl);
+#endif
+
+#ifdef SYS_riscv_flush_icache
+
+#define VDSO_FLUSH_ICACHE_SYM "__vdso_flush_icache"
+#define VDSO_FLUSH_ICACHE_VER "LINUX_4.5"
+
+static void *volatile vdso_func;
+
+static int flush_icache_init(void *start, void *end, unsigned long int flags)
+{
+ void *p = __vdsosym(VDSO_FLUSH_ICACHE_VER, VDSO_FLUSH_ICACHE_SYM);
+ int (*f)(void *, void *, unsigned long int) =
+ (int (*)(void *, void *, unsigned long int))p;
+ a_cas_p(&vdso_func, (void *)flush_icache_init, p);
+ return f ? f(start, end, flags) : -ENOSYS;
+}
+
+static void *volatile vdso_func = (void *)flush_icache_init;
+
+int __riscv_flush_icache(void *start, void *end, unsigned long int flags)
+{
+ int (*f)(void *, void *, unsigned long int) =
+ (int (*)(void *, void *, unsigned long int))vdso_func;
+ if (f) {
+ int r = f(start, end, flags);
+ if (!r) return r;
+ if (r != -ENOSYS) return __syscall_ret(r);
+ }
+}
+weak_alias(__riscv_flush_icache, riscv_flush_icache);
+#endif
diff --git a/libc-top-half/musl/src/linux/cap.c b/libc-top-half/musl/src/linux/cap.c
new file mode 100644
index 0000000..8d035e0
--- /dev/null
+++ b/libc-top-half/musl/src/linux/cap.c
@@ -0,0 +1,11 @@
+#include "syscall.h"
+
+int capset(void *a, void *b)
+{
+ return syscall(SYS_capset, a, b);
+}
+
+int capget(void *a, void *b)
+{
+ return syscall(SYS_capget, a, b);
+}
diff --git a/libc-top-half/musl/src/linux/chroot.c b/libc-top-half/musl/src/linux/chroot.c
new file mode 100644
index 0000000..0e69f14
--- /dev/null
+++ b/libc-top-half/musl/src/linux/chroot.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int chroot(const char *path)
+{
+ return syscall(SYS_chroot, path);
+}
diff --git a/libc-top-half/musl/src/linux/clock_adjtime.c b/libc-top-half/musl/src/linux/clock_adjtime.c
new file mode 100644
index 0000000..d4d03d2
--- /dev/null
+++ b/libc-top-half/musl/src/linux/clock_adjtime.c
@@ -0,0 +1,151 @@
+#include <sys/timex.h>
+#include <time.h>
+#include <errno.h>
+#include "syscall.h"
+
+#define IS32BIT(x) !((x)+0x80000000ULL>>32)
+
+struct ktimex64 {
+ unsigned modes;
+ int :32;
+ long long offset, freq, maxerror, esterror;
+ int status;
+ int :32;
+ long long constant, precision, tolerance;
+ long long time_sec, time_usec;
+ long long tick, ppsfreq, jitter;
+ int shift;
+ int :32;
+ long long stabil, jitcnt, calcnt, errcnt, stbcnt;
+ int tai;
+ int __padding[11];
+};
+
+struct ktimex {
+ unsigned modes;
+ long offset, freq, maxerror, esterror;
+ int status;
+ long constant, precision, tolerance;
+ long time_sec, time_usec;
+ long tick, ppsfreq, jitter;
+ int shift;
+ long stabil, jitcnt, calcnt, errcnt, stbcnt;
+ int tai;
+ int __padding[11];
+};
+
+int clock_adjtime (clockid_t clock_id, struct timex *utx)
+{
+ int r = -ENOSYS;
+#ifdef SYS_clock_adjtime64
+ struct ktimex64 ktx = {
+ .modes = utx->modes,
+ .offset = utx->offset,
+ .freq = utx->freq,
+ .maxerror = utx->maxerror,
+ .esterror = utx->esterror,
+ .status = utx->status,
+ .constant = utx->constant,
+ .precision = utx->precision,
+ .tolerance = utx->tolerance,
+ .time_sec = utx->time.tv_sec,
+ .time_usec = utx->time.tv_usec,
+ .tick = utx->tick,
+ .ppsfreq = utx->ppsfreq,
+ .jitter = utx->jitter,
+ .shift = utx->shift,
+ .stabil = utx->stabil,
+ .jitcnt = utx->jitcnt,
+ .calcnt = utx->calcnt,
+ .errcnt = utx->errcnt,
+ .stbcnt = utx->stbcnt,
+ .tai = utx->tai,
+ };
+ r = __syscall(SYS_clock_adjtime64, clock_id, &ktx);
+ if (r>=0) {
+ utx->modes = ktx.modes;
+ utx->offset = ktx.offset;
+ utx->freq = ktx.freq;
+ utx->maxerror = ktx.maxerror;
+ utx->esterror = ktx.esterror;
+ utx->status = ktx.status;
+ utx->constant = ktx.constant;
+ utx->precision = ktx.precision;
+ utx->tolerance = ktx.tolerance;
+ utx->time.tv_sec = ktx.time_sec;
+ utx->time.tv_usec = ktx.time_usec;
+ utx->tick = ktx.tick;
+ utx->ppsfreq = ktx.ppsfreq;
+ utx->jitter = ktx.jitter;
+ utx->shift = ktx.shift;
+ utx->stabil = ktx.stabil;
+ utx->jitcnt = ktx.jitcnt;
+ utx->calcnt = ktx.calcnt;
+ utx->errcnt = ktx.errcnt;
+ utx->stbcnt = ktx.stbcnt;
+ utx->tai = ktx.tai;
+ }
+ if (SYS_clock_adjtime == SYS_clock_adjtime64 || r!=-ENOSYS)
+ return __syscall_ret(r);
+ if ((utx->modes & ADJ_SETOFFSET) && !IS32BIT(utx->time.tv_sec))
+ return __syscall_ret(-ENOTSUP);
+#endif
+ if (sizeof(time_t) > sizeof(long)) {
+ struct ktimex ktx = {
+ .modes = utx->modes,
+ .offset = utx->offset,
+ .freq = utx->freq,
+ .maxerror = utx->maxerror,
+ .esterror = utx->esterror,
+ .status = utx->status,
+ .constant = utx->constant,
+ .precision = utx->precision,
+ .tolerance = utx->tolerance,
+ .time_sec = utx->time.tv_sec,
+ .time_usec = utx->time.tv_usec,
+ .tick = utx->tick,
+ .ppsfreq = utx->ppsfreq,
+ .jitter = utx->jitter,
+ .shift = utx->shift,
+ .stabil = utx->stabil,
+ .jitcnt = utx->jitcnt,
+ .calcnt = utx->calcnt,
+ .errcnt = utx->errcnt,
+ .stbcnt = utx->stbcnt,
+ .tai = utx->tai,
+ };
+#ifdef SYS_adjtimex
+ if (clock_id==CLOCK_REALTIME) r = __syscall(SYS_adjtimex, &ktx);
+ else
+#endif
+ r = __syscall(SYS_clock_adjtime, clock_id, &ktx);
+ if (r>=0) {
+ utx->modes = ktx.modes;
+ utx->offset = ktx.offset;
+ utx->freq = ktx.freq;
+ utx->maxerror = ktx.maxerror;
+ utx->esterror = ktx.esterror;
+ utx->status = ktx.status;
+ utx->constant = ktx.constant;
+ utx->precision = ktx.precision;
+ utx->tolerance = ktx.tolerance;
+ utx->time.tv_sec = ktx.time_sec;
+ utx->time.tv_usec = ktx.time_usec;
+ utx->tick = ktx.tick;
+ utx->ppsfreq = ktx.ppsfreq;
+ utx->jitter = ktx.jitter;
+ utx->shift = ktx.shift;
+ utx->stabil = ktx.stabil;
+ utx->jitcnt = ktx.jitcnt;
+ utx->calcnt = ktx.calcnt;
+ utx->errcnt = ktx.errcnt;
+ utx->stbcnt = ktx.stbcnt;
+ utx->tai = ktx.tai;
+ }
+ return __syscall_ret(r);
+ }
+#ifdef SYS_adjtimex
+ if (clock_id==CLOCK_REALTIME) return syscall(SYS_adjtimex, utx);
+#endif
+ return syscall(SYS_clock_adjtime, clock_id, utx);
+}
diff --git a/libc-top-half/musl/src/linux/clone.c b/libc-top-half/musl/src/linux/clone.c
new file mode 100644
index 0000000..8c1af7d
--- /dev/null
+++ b/libc-top-half/musl/src/linux/clone.c
@@ -0,0 +1,21 @@
+#define _GNU_SOURCE
+#include <stdarg.h>
+#include <unistd.h>
+#include <sched.h>
+#include "pthread_impl.h"
+#include "syscall.h"
+
+int clone(int (*func)(void *), void *stack, int flags, void *arg, ...)
+{
+ va_list ap;
+ pid_t *ptid, *ctid;
+ void *tls;
+
+ va_start(ap, arg);
+ ptid = va_arg(ap, pid_t *);
+ tls = va_arg(ap, void *);
+ ctid = va_arg(ap, pid_t *);
+ va_end(ap);
+
+ return __syscall_ret(__clone(func, stack, flags, arg, ptid, tls, ctid));
+}
diff --git a/libc-top-half/musl/src/linux/copy_file_range.c b/libc-top-half/musl/src/linux/copy_file_range.c
new file mode 100644
index 0000000..dd4b133
--- /dev/null
+++ b/libc-top-half/musl/src/linux/copy_file_range.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+ssize_t copy_file_range(int fd_in, off_t *off_in, int fd_out, off_t *off_out, size_t len, unsigned flags)
+{
+ return syscall(SYS_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags);
+}
diff --git a/libc-top-half/musl/src/linux/epoll.c b/libc-top-half/musl/src/linux/epoll.c
new file mode 100644
index 0000000..93baa81
--- /dev/null
+++ b/libc-top-half/musl/src/linux/epoll.c
@@ -0,0 +1,37 @@
+#include <sys/epoll.h>
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+
+int epoll_create(int size)
+{
+ return epoll_create1(0);
+}
+
+int epoll_create1(int flags)
+{
+ int r = __syscall(SYS_epoll_create1, flags);
+#ifdef SYS_epoll_create
+ if (r==-ENOSYS && !flags) r = __syscall(SYS_epoll_create, 1);
+#endif
+ return __syscall_ret(r);
+}
+
+int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
+{
+ return syscall(SYS_epoll_ctl, fd, op, fd2, ev);
+}
+
+int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs)
+{
+ int r = __syscall_cp(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8);
+#ifdef SYS_epoll_wait
+ if (r==-ENOSYS && !sigs) r = __syscall_cp(SYS_epoll_wait, fd, ev, cnt, to);
+#endif
+ return __syscall_ret(r);
+}
+
+int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to)
+{
+ return epoll_pwait(fd, ev, cnt, to, 0);
+}
diff --git a/libc-top-half/musl/src/linux/eventfd.c b/libc-top-half/musl/src/linux/eventfd.c
new file mode 100644
index 0000000..68e489c
--- /dev/null
+++ b/libc-top-half/musl/src/linux/eventfd.c
@@ -0,0 +1,23 @@
+#include <sys/eventfd.h>
+#include <unistd.h>
+#include <errno.h>
+#include "syscall.h"
+
+int eventfd(unsigned int count, int flags)
+{
+ int r = __syscall(SYS_eventfd2, count, flags);
+#ifdef SYS_eventfd
+ if (r==-ENOSYS && !flags) r = __syscall(SYS_eventfd, count);
+#endif
+ return __syscall_ret(r);
+}
+
+int eventfd_read(int fd, eventfd_t *value)
+{
+ return (sizeof(*value) == read(fd, value, sizeof(*value))) ? 0 : -1;
+}
+
+int eventfd_write(int fd, eventfd_t value)
+{
+ return (sizeof(value) == write(fd, &value, sizeof(value))) ? 0 : -1;
+}
diff --git a/libc-top-half/musl/src/linux/fallocate.c b/libc-top-half/musl/src/linux/fallocate.c
new file mode 100644
index 0000000..7d68bc8
--- /dev/null
+++ b/libc-top-half/musl/src/linux/fallocate.c
@@ -0,0 +1,12 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+int fallocate(int fd, int mode, off_t base, off_t len)
+{
+ return syscall(SYS_fallocate, fd, mode, __SYSCALL_LL_E(base),
+ __SYSCALL_LL_E(len));
+}
+
+#undef fallocate64
+weak_alias(fallocate, fallocate64);
diff --git a/libc-top-half/musl/src/linux/fanotify.c b/libc-top-half/musl/src/linux/fanotify.c
new file mode 100644
index 0000000..c6211af
--- /dev/null
+++ b/libc-top-half/musl/src/linux/fanotify.c
@@ -0,0 +1,14 @@
+#include "syscall.h"
+#include <sys/fanotify.h>
+
+int fanotify_init(unsigned flags, unsigned event_f_flags)
+{
+ return syscall(SYS_fanotify_init, flags, event_f_flags);
+}
+
+int fanotify_mark(int fanotify_fd, unsigned flags, unsigned long long mask,
+ int dfd, const char *pathname)
+{
+ return syscall(SYS_fanotify_mark, fanotify_fd, flags, __SYSCALL_LL_E(mask), dfd, pathname);
+}
+
diff --git a/libc-top-half/musl/src/linux/flock.c b/libc-top-half/musl/src/linux/flock.c
new file mode 100644
index 0000000..87aa5cf
--- /dev/null
+++ b/libc-top-half/musl/src/linux/flock.c
@@ -0,0 +1,7 @@
+#include <sys/file.h>
+#include "syscall.h"
+
+int flock(int fd, int op)
+{
+ return syscall(SYS_flock, fd, op);
+}
diff --git a/libc-top-half/musl/src/linux/getdents.c b/libc-top-half/musl/src/linux/getdents.c
new file mode 100644
index 0000000..796c1e5
--- /dev/null
+++ b/libc-top-half/musl/src/linux/getdents.c
@@ -0,0 +1,12 @@
+#define _BSD_SOURCE
+#include <dirent.h>
+#include <limits.h>
+#include "syscall.h"
+
+int getdents(int fd, struct dirent *buf, size_t len)
+{
+ if (len>INT_MAX) len = INT_MAX;
+ return syscall(SYS_getdents, fd, buf, len);
+}
+
+weak_alias(getdents, getdents64);
diff --git a/libc-top-half/musl/src/linux/getrandom.c b/libc-top-half/musl/src/linux/getrandom.c
new file mode 100644
index 0000000..6cc6f6b
--- /dev/null
+++ b/libc-top-half/musl/src/linux/getrandom.c
@@ -0,0 +1,7 @@
+#include <sys/random.h>
+#include "syscall.h"
+
+ssize_t getrandom(void *buf, size_t buflen, unsigned flags)
+{
+ return syscall_cp(SYS_getrandom, buf, buflen, flags);
+}
diff --git a/libc-top-half/musl/src/linux/gettid.c b/libc-top-half/musl/src/linux/gettid.c
new file mode 100644
index 0000000..7076713
--- /dev/null
+++ b/libc-top-half/musl/src/linux/gettid.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "pthread_impl.h"
+
+pid_t gettid(void)
+{
+ return __pthread_self()->tid;
+}
diff --git a/libc-top-half/musl/src/linux/inotify.c b/libc-top-half/musl/src/linux/inotify.c
new file mode 100644
index 0000000..df5e48b
--- /dev/null
+++ b/libc-top-half/musl/src/linux/inotify.c
@@ -0,0 +1,26 @@
+#include <sys/inotify.h>
+#include <errno.h>
+#include "syscall.h"
+
+int inotify_init()
+{
+ return inotify_init1(0);
+}
+int inotify_init1(int flags)
+{
+ int r = __syscall(SYS_inotify_init1, flags);
+#ifdef SYS_inotify_init
+ if (r==-ENOSYS && !flags) r = __syscall(SYS_inotify_init);
+#endif
+ return __syscall_ret(r);
+}
+
+int inotify_add_watch(int fd, const char *pathname, uint32_t mask)
+{
+ return syscall(SYS_inotify_add_watch, fd, pathname, mask);
+}
+
+int inotify_rm_watch(int fd, int wd)
+{
+ return syscall(SYS_inotify_rm_watch, fd, wd);
+}
diff --git a/libc-top-half/musl/src/linux/ioperm.c b/libc-top-half/musl/src/linux/ioperm.c
new file mode 100644
index 0000000..08c6d8b
--- /dev/null
+++ b/libc-top-half/musl/src/linux/ioperm.c
@@ -0,0 +1,10 @@
+#include "syscall.h"
+
+#ifdef SYS_ioperm
+#include <sys/io.h>
+
+int ioperm(unsigned long from, unsigned long num, int turn_on)
+{
+ return syscall(SYS_ioperm, from, num, turn_on);
+}
+#endif
diff --git a/libc-top-half/musl/src/linux/iopl.c b/libc-top-half/musl/src/linux/iopl.c
new file mode 100644
index 0000000..835d3d4
--- /dev/null
+++ b/libc-top-half/musl/src/linux/iopl.c
@@ -0,0 +1,10 @@
+#include "syscall.h"
+
+#ifdef SYS_iopl
+#include <sys/io.h>
+
+int iopl(int level)
+{
+ return syscall(SYS_iopl, level);
+}
+#endif
diff --git a/libc-top-half/musl/src/linux/klogctl.c b/libc-top-half/musl/src/linux/klogctl.c
new file mode 100644
index 0000000..8102ee6
--- /dev/null
+++ b/libc-top-half/musl/src/linux/klogctl.c
@@ -0,0 +1,7 @@
+#include <sys/klog.h>
+#include "syscall.h"
+
+int klogctl (int type, char *buf, int len)
+{
+ return syscall(SYS_syslog, type, buf, len);
+}
diff --git a/libc-top-half/musl/src/linux/membarrier.c b/libc-top-half/musl/src/linux/membarrier.c
new file mode 100644
index 0000000..343f736
--- /dev/null
+++ b/libc-top-half/musl/src/linux/membarrier.c
@@ -0,0 +1,72 @@
+#include <sys/membarrier.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <string.h>
+#include "pthread_impl.h"
+#include "syscall.h"
+
+static void dummy_0(void)
+{
+}
+
+weak_alias(dummy_0, __tl_lock);
+weak_alias(dummy_0, __tl_unlock);
+
+static sem_t barrier_sem;
+
+static void bcast_barrier(int s)
+{
+ sem_post(&barrier_sem);
+}
+
+int __membarrier(int cmd, int flags)
+{
+ int r = __syscall(SYS_membarrier, cmd, flags);
+ /* Emulate the private expedited command, which is needed by the
+ * dynamic linker for installation of dynamic TLS, for older
+ * kernels that lack the syscall. Unlike the syscall, this only
+ * synchronizes with threads of the process, not other processes
+ * sharing the VM, but such sharing is not a supported usage
+ * anyway. */
+ if (r && cmd == MEMBARRIER_CMD_PRIVATE_EXPEDITED && !flags) {
+ pthread_t self=__pthread_self(), td;
+ sigset_t set;
+ __block_app_sigs(&set);
+ __tl_lock();
+ sem_init(&barrier_sem, 0, 0);
+ struct sigaction sa = {
+ .sa_flags = SA_RESTART,
+ .sa_handler = bcast_barrier
+ };
+ memset(&sa.sa_mask, -1, sizeof sa.sa_mask);
+ if (!__libc_sigaction(SIGSYNCCALL, &sa, 0)) {
+ for (td=self->next; td!=self; td=td->next)
+ __syscall(SYS_tkill, td->tid, SIGSYNCCALL);
+ for (td=self->next; td!=self; td=td->next)
+ sem_wait(&barrier_sem);
+ r = 0;
+ sa.sa_handler = SIG_IGN;
+ __libc_sigaction(SIGSYNCCALL, &sa, 0);
+ }
+ sem_destroy(&barrier_sem);
+ __tl_unlock();
+ __restore_sigs(&set);
+ }
+ return __syscall_ret(r);
+}
+
+void __membarrier_init(void)
+{
+ /* If membarrier is linked, attempt to pre-register to be able to use
+ * the private expedited command before the process becomes multi-
+ * threaded, since registering later has bad, potentially unbounded
+ * latency. This syscall should be essentially free, and it's arguably
+ * a mistake in the API design that registration was even required.
+ * For other commands, registration may impose some cost, so it's left
+ * to the application to do so if desired. Unfortunately this means
+ * library code initialized after the process becomes multi-threaded
+ * cannot use these features without accepting registration latency. */
+ __syscall(SYS_membarrier, MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0);
+}
+
+weak_alias(__membarrier, membarrier);
diff --git a/libc-top-half/musl/src/linux/memfd_create.c b/libc-top-half/musl/src/linux/memfd_create.c
new file mode 100644
index 0000000..1649fe5
--- /dev/null
+++ b/libc-top-half/musl/src/linux/memfd_create.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE 1
+#include <sys/mman.h>
+#include "syscall.h"
+
+int memfd_create(const char *name, unsigned flags)
+{
+ return syscall(SYS_memfd_create, name, flags);
+}
diff --git a/libc-top-half/musl/src/linux/mlock2.c b/libc-top-half/musl/src/linux/mlock2.c
new file mode 100644
index 0000000..1013274
--- /dev/null
+++ b/libc-top-half/musl/src/linux/mlock2.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE 1
+#include <sys/mman.h>
+#include "syscall.h"
+
+int mlock2(const void *addr, size_t len, unsigned flags)
+{
+ if (flags == 0)
+ return mlock(addr, len);
+ return syscall(SYS_mlock2, addr, len, flags);
+}
diff --git a/libc-top-half/musl/src/linux/module.c b/libc-top-half/musl/src/linux/module.c
new file mode 100644
index 0000000..33f69a0
--- /dev/null
+++ b/libc-top-half/musl/src/linux/module.c
@@ -0,0 +1,11 @@
+#include "syscall.h"
+
+int init_module(void *a, unsigned long b, const char *c)
+{
+ return syscall(SYS_init_module, a, b, c);
+}
+
+int delete_module(const char *a, unsigned b)
+{
+ return syscall(SYS_delete_module, a, b);
+}
diff --git a/libc-top-half/musl/src/linux/mount.c b/libc-top-half/musl/src/linux/mount.c
new file mode 100644
index 0000000..34e11af
--- /dev/null
+++ b/libc-top-half/musl/src/linux/mount.c
@@ -0,0 +1,17 @@
+#include <sys/mount.h>
+#include "syscall.h"
+
+int mount(const char *special, const char *dir, const char *fstype, unsigned long flags, const void *data)
+{
+ return syscall(SYS_mount, special, dir, fstype, flags, data);
+}
+
+int umount(const char *special)
+{
+ return syscall(SYS_umount2, special, 0);
+}
+
+int umount2(const char *special, int flags)
+{
+ return syscall(SYS_umount2, special, flags);
+}
diff --git a/libc-top-half/musl/src/linux/name_to_handle_at.c b/libc-top-half/musl/src/linux/name_to_handle_at.c
new file mode 100644
index 0000000..cd4075b
--- /dev/null
+++ b/libc-top-half/musl/src/linux/name_to_handle_at.c
@@ -0,0 +1,10 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+int name_to_handle_at(int dirfd, const char *pathname,
+ struct file_handle *handle, int *mount_id, int flags)
+{
+ return syscall(SYS_name_to_handle_at, dirfd,
+ pathname, handle, mount_id, flags);
+}
diff --git a/libc-top-half/musl/src/linux/open_by_handle_at.c b/libc-top-half/musl/src/linux/open_by_handle_at.c
new file mode 100644
index 0000000..1c9b6a2
--- /dev/null
+++ b/libc-top-half/musl/src/linux/open_by_handle_at.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+int open_by_handle_at(int mount_fd, struct file_handle *handle, int flags)
+{
+ return syscall(SYS_open_by_handle_at, mount_fd, handle, flags);
+}
diff --git a/libc-top-half/musl/src/linux/personality.c b/libc-top-half/musl/src/linux/personality.c
new file mode 100644
index 0000000..e00cf79
--- /dev/null
+++ b/libc-top-half/musl/src/linux/personality.c
@@ -0,0 +1,8 @@
+#include <sys/personality.h>
+#include "syscall.h"
+#ifdef SYS_personality
+int personality(unsigned long persona)
+{
+ return syscall(SYS_personality, persona);
+}
+#endif
diff --git a/libc-top-half/musl/src/linux/pivot_root.c b/libc-top-half/musl/src/linux/pivot_root.c
new file mode 100644
index 0000000..17e70c9
--- /dev/null
+++ b/libc-top-half/musl/src/linux/pivot_root.c
@@ -0,0 +1,6 @@
+#include "syscall.h"
+
+int pivot_root(const char *new, const char *old)
+{
+ return syscall(SYS_pivot_root, new, old);
+}
diff --git a/libc-top-half/musl/src/linux/ppoll.c b/libc-top-half/musl/src/linux/ppoll.c
new file mode 100644
index 0000000..e614600
--- /dev/null
+++ b/libc-top-half/musl/src/linux/ppoll.c
@@ -0,0 +1,26 @@
+#define _GNU_SOURCE
+#include <poll.h>
+#include <signal.h>
+#include <errno.h>
+#include "syscall.h"
+
+#define IS32BIT(x) !((x)+0x80000000ULL>>32)
+#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63))
+
+int ppoll(struct pollfd *fds, nfds_t n, const struct timespec *to, const sigset_t *mask)
+{
+ time_t s = to ? to->tv_sec : 0;
+ long ns = to ? to->tv_nsec : 0;
+#ifdef SYS_ppoll_time64
+ int r = -ENOSYS;
+ if (SYS_ppoll == SYS_ppoll_time64 || !IS32BIT(s))
+ r = __syscall_cp(SYS_ppoll_time64, fds, n,
+ to ? ((long long[]){s, ns}) : 0,
+ mask, _NSIG/8);
+ if (SYS_ppoll == SYS_ppoll_time64 || r != -ENOSYS)
+ return __syscall_ret(r);
+ s = CLAMP(s);
+#endif
+ return syscall_cp(SYS_ppoll, fds, n,
+ to ? ((long[]){s, ns}) : 0, mask, _NSIG/8);
+}
diff --git a/libc-top-half/musl/src/linux/prctl.c b/libc-top-half/musl/src/linux/prctl.c
new file mode 100644
index 0000000..19f4267
--- /dev/null
+++ b/libc-top-half/musl/src/linux/prctl.c
@@ -0,0 +1,14 @@
+#include <sys/prctl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+int prctl(int op, ...)
+{
+ unsigned long x[4];
+ int i;
+ va_list ap;
+ va_start(ap, op);
+ for (i=0; i<4; i++) x[i] = va_arg(ap, unsigned long);
+ va_end(ap);
+ return syscall(SYS_prctl, op, x[0], x[1], x[2], x[3]);
+}
diff --git a/libc-top-half/musl/src/linux/prlimit.c b/libc-top-half/musl/src/linux/prlimit.c
new file mode 100644
index 0000000..3df9ffb
--- /dev/null
+++ b/libc-top-half/musl/src/linux/prlimit.c
@@ -0,0 +1,26 @@
+#define _GNU_SOURCE
+#include <sys/resource.h>
+#include "syscall.h"
+
+#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
+
+int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit)
+{
+ struct rlimit tmp;
+ int r;
+ if (new_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
+ tmp = *new_limit;
+ FIX(tmp.rlim_cur);
+ FIX(tmp.rlim_max);
+ new_limit = &tmp;
+ }
+ r = syscall(SYS_prlimit64, pid, resource, new_limit, old_limit);
+ if (!r && old_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
+ FIX(old_limit->rlim_cur);
+ FIX(old_limit->rlim_max);
+ }
+ return r;
+}
+
+#undef prlimit64
+weak_alias(prlimit, prlimit64);
diff --git a/libc-top-half/musl/src/linux/process_vm.c b/libc-top-half/musl/src/linux/process_vm.c
new file mode 100644
index 0000000..7703bdf
--- /dev/null
+++ b/libc-top-half/musl/src/linux/process_vm.c
@@ -0,0 +1,13 @@
+#define _GNU_SOURCE
+#include <sys/uio.h>
+#include "syscall.h"
+
+ssize_t process_vm_writev(pid_t pid, const struct iovec *lvec, unsigned long liovcnt, const struct iovec *rvec, unsigned long riovcnt, unsigned long flags)
+{
+ return syscall(SYS_process_vm_writev, pid, lvec, liovcnt, rvec, riovcnt, flags);
+}
+
+ssize_t process_vm_readv(pid_t pid, const struct iovec *lvec, unsigned long liovcnt, const struct iovec *rvec, unsigned long riovcnt, unsigned long flags)
+{
+ return syscall(SYS_process_vm_readv, pid, lvec, liovcnt, rvec, riovcnt, flags);
+}
diff --git a/libc-top-half/musl/src/linux/ptrace.c b/libc-top-half/musl/src/linux/ptrace.c
new file mode 100644
index 0000000..a3f393d
--- /dev/null
+++ b/libc-top-half/musl/src/linux/ptrace.c
@@ -0,0 +1,29 @@
+#include <sys/ptrace.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include "syscall.h"
+
+long ptrace(int req, ...)
+{
+ va_list ap;
+ pid_t pid;
+ void *addr, *data, *addr2 = 0;
+ long ret, result;
+
+ va_start(ap, req);
+ pid = va_arg(ap, pid_t);
+ addr = va_arg(ap, void *);
+ data = va_arg(ap, void *);
+ /* PTRACE_{READ,WRITE}{DATA,TEXT} (16...19) are specific to SPARC. */
+#ifdef PTRACE_READDATA
+ if ((unsigned)req - PTRACE_READDATA < 4)
+ addr2 = va_arg(ap, void *);
+#endif
+ va_end(ap);
+
+ if (req-1U < 3) data = &result;
+ ret = syscall(SYS_ptrace, req, pid, addr, data, addr2);
+
+ if (ret < 0 || req-1U >= 3) return ret;
+ return result;
+}
diff --git a/libc-top-half/musl/src/linux/quotactl.c b/libc-top-half/musl/src/linux/quotactl.c
new file mode 100644
index 0000000..344eb0d
--- /dev/null
+++ b/libc-top-half/musl/src/linux/quotactl.c
@@ -0,0 +1,7 @@
+#include <sys/quota.h>
+#include "syscall.h"
+
+int quotactl(int cmd, const char *special, int id, char *addr)
+{
+ return syscall(SYS_quotactl, cmd, special, id, addr);
+}
diff --git a/libc-top-half/musl/src/linux/readahead.c b/libc-top-half/musl/src/linux/readahead.c
new file mode 100644
index 0000000..5c70bfd
--- /dev/null
+++ b/libc-top-half/musl/src/linux/readahead.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t readahead(int fd, off_t pos, size_t len)
+{
+ return syscall(SYS_readahead, fd, __SYSCALL_LL_O(pos), len);
+}
diff --git a/libc-top-half/musl/src/linux/reboot.c b/libc-top-half/musl/src/linux/reboot.c
new file mode 100644
index 0000000..7f12af7
--- /dev/null
+++ b/libc-top-half/musl/src/linux/reboot.c
@@ -0,0 +1,7 @@
+#include <sys/reboot.h>
+#include "syscall.h"
+
+int reboot(int type)
+{
+ return syscall(SYS_reboot, 0xfee1dead, 672274793, type);
+}
diff --git a/libc-top-half/musl/src/linux/remap_file_pages.c b/libc-top-half/musl/src/linux/remap_file_pages.c
new file mode 100644
index 0000000..a9699ce
--- /dev/null
+++ b/libc-top-half/musl/src/linux/remap_file_pages.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sys/mman.h>
+#include "syscall.h"
+
+int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff, int flags)
+{
+ return syscall(SYS_remap_file_pages, addr, size, prot, pgoff, flags);
+}
diff --git a/libc-top-half/musl/src/linux/sbrk.c b/libc-top-half/musl/src/linux/sbrk.c
new file mode 100644
index 0000000..bb86630
--- /dev/null
+++ b/libc-top-half/musl/src/linux/sbrk.c
@@ -0,0 +1,11 @@
+#define _BSD_SOURCE
+#include <unistd.h>
+#include <stdint.h>
+#include <errno.h>
+#include "syscall.h"
+
+void *sbrk(intptr_t inc)
+{
+ if (inc) return (void *)__syscall_ret(-ENOMEM);
+ return (void *)__syscall(SYS_brk, 0);
+}
diff --git a/libc-top-half/musl/src/linux/sendfile.c b/libc-top-half/musl/src/linux/sendfile.c
new file mode 100644
index 0000000..9afe6dd
--- /dev/null
+++ b/libc-top-half/musl/src/linux/sendfile.c
@@ -0,0 +1,9 @@
+#include <sys/sendfile.h>
+#include "syscall.h"
+
+ssize_t sendfile(int out_fd, int in_fd, off_t *ofs, size_t count)
+{
+ return syscall(SYS_sendfile, out_fd, in_fd, ofs, count);
+}
+
+weak_alias(sendfile, sendfile64);
diff --git a/libc-top-half/musl/src/linux/setfsgid.c b/libc-top-half/musl/src/linux/setfsgid.c
new file mode 100644
index 0000000..e29d9c0
--- /dev/null
+++ b/libc-top-half/musl/src/linux/setfsgid.c
@@ -0,0 +1,7 @@
+#include <sys/fsuid.h>
+#include "syscall.h"
+
+int setfsgid(gid_t gid)
+{
+ return syscall(SYS_setfsgid, gid);
+}
diff --git a/libc-top-half/musl/src/linux/setfsuid.c b/libc-top-half/musl/src/linux/setfsuid.c
new file mode 100644
index 0000000..1bae441
--- /dev/null
+++ b/libc-top-half/musl/src/linux/setfsuid.c
@@ -0,0 +1,7 @@
+#include <sys/fsuid.h>
+#include "syscall.h"
+
+int setfsuid(uid_t uid)
+{
+ return syscall(SYS_setfsuid, uid);
+}
diff --git a/libc-top-half/musl/src/linux/setgroups.c b/libc-top-half/musl/src/linux/setgroups.c
new file mode 100644
index 0000000..47142f1
--- /dev/null
+++ b/libc-top-half/musl/src/linux/setgroups.c
@@ -0,0 +1,36 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <signal.h>
+#include "syscall.h"
+#include "libc.h"
+
+struct ctx {
+ size_t count;
+ const gid_t *list;
+ int ret;
+};
+
+static void do_setgroups(void *p)
+{
+ struct ctx *c = p;
+ if (c->ret<0) return;
+ int ret = __syscall(SYS_setgroups, c->count, c->list);
+ if (ret && !c->ret) {
+ /* If one thread fails to set groups 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 setgroups(size_t count, const gid_t list[])
+{
+ /* ret is initially nonzero so that failure of the first thread does not
+ * trigger the safety kill above. */
+ struct ctx c = { .count = count, .list = list, .ret = 1 };
+ __synccall(do_setgroups, &c);
+ return __syscall_ret(c.ret);
+}
diff --git a/libc-top-half/musl/src/linux/sethostname.c b/libc-top-half/musl/src/linux/sethostname.c
new file mode 100644
index 0000000..9313b32
--- /dev/null
+++ b/libc-top-half/musl/src/linux/sethostname.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int sethostname(const char *name, size_t len)
+{
+ return syscall(SYS_sethostname, name, len);
+}
diff --git a/libc-top-half/musl/src/linux/setns.c b/libc-top-half/musl/src/linux/setns.c
new file mode 100644
index 0000000..0afec81
--- /dev/null
+++ b/libc-top-half/musl/src/linux/setns.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include "syscall.h"
+
+int setns(int fd, int nstype)
+{
+ return syscall(SYS_setns, fd, nstype);
+}
diff --git a/libc-top-half/musl/src/linux/settimeofday.c b/libc-top-half/musl/src/linux/settimeofday.c
new file mode 100644
index 0000000..860fb5d
--- /dev/null
+++ b/libc-top-half/musl/src/linux/settimeofday.c
@@ -0,0 +1,13 @@
+#define _BSD_SOURCE
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+#include "syscall.h"
+
+int settimeofday(const struct timeval *tv, const struct timezone *tz)
+{
+ if (!tv) return 0;
+ if (tv->tv_usec >= 1000000ULL) return __syscall_ret(-EINVAL);
+ return clock_settime(CLOCK_REALTIME, &((struct timespec){
+ .tv_sec = tv->tv_sec, .tv_nsec = tv->tv_usec * 1000}));
+}
diff --git a/libc-top-half/musl/src/linux/signalfd.c b/libc-top-half/musl/src/linux/signalfd.c
new file mode 100644
index 0000000..4bf4332
--- /dev/null
+++ b/libc-top-half/musl/src/linux/signalfd.c
@@ -0,0 +1,21 @@
+#include <sys/signalfd.h>
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "syscall.h"
+
+int signalfd(int fd, const sigset_t *sigs, int flags)
+{
+ int ret = __syscall(SYS_signalfd4, fd, sigs, _NSIG/8, flags);
+#ifdef SYS_signalfd
+ if (ret != -ENOSYS) return __syscall_ret(ret);
+ ret = __syscall(SYS_signalfd, fd, sigs, _NSIG/8);
+ if (ret >= 0) {
+ if (flags & SFD_CLOEXEC)
+ __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
+ if (flags & SFD_NONBLOCK)
+ __syscall(SYS_fcntl, ret, F_SETFL, O_NONBLOCK);
+ }
+#endif
+ return __syscall_ret(ret);
+}
diff --git a/libc-top-half/musl/src/linux/splice.c b/libc-top-half/musl/src/linux/splice.c
new file mode 100644
index 0000000..78b6220
--- /dev/null
+++ b/libc-top-half/musl/src/linux/splice.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t splice(int fd_in, off_t *off_in, int fd_out, off_t *off_out, size_t len, unsigned flags)
+{
+ return syscall(SYS_splice, fd_in, off_in, fd_out, off_out, len, flags);
+}
diff --git a/libc-top-half/musl/src/linux/stime.c b/libc-top-half/musl/src/linux/stime.c
new file mode 100644
index 0000000..7d0443b
--- /dev/null
+++ b/libc-top-half/musl/src/linux/stime.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <time.h>
+#include <sys/time.h>
+
+int stime(const time_t *t)
+{
+ struct timeval tv = { .tv_sec = *t, .tv_usec = 0 };
+ return settimeofday(&tv, (void *)0);
+}
diff --git a/libc-top-half/musl/src/linux/swap.c b/libc-top-half/musl/src/linux/swap.c
new file mode 100644
index 0000000..8137d51
--- /dev/null
+++ b/libc-top-half/musl/src/linux/swap.c
@@ -0,0 +1,12 @@
+#include <sys/swap.h>
+#include "syscall.h"
+
+int swapon(const char *path, int flags)
+{
+ return syscall(SYS_swapon, path, flags);
+}
+
+int swapoff(const char *path)
+{
+ return syscall(SYS_swapoff, path);
+}
diff --git a/libc-top-half/musl/src/linux/sync_file_range.c b/libc-top-half/musl/src/linux/sync_file_range.c
new file mode 100644
index 0000000..6859abc
--- /dev/null
+++ b/libc-top-half/musl/src/linux/sync_file_range.c
@@ -0,0 +1,17 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <errno.h>
+#include "syscall.h"
+
+int sync_file_range(int fd, off_t pos, off_t len, unsigned flags)
+{
+#if defined(SYS_sync_file_range2)
+ return syscall(SYS_sync_file_range2, fd, flags,
+ __SYSCALL_LL_E(pos), __SYSCALL_LL_E(len));
+#elif defined(SYS_sync_file_range)
+ return syscall(SYS_sync_file_range, fd,
+ __SYSCALL_LL_O(pos), __SYSCALL_LL_E(len), flags);
+#else
+ return __syscall_ret(-ENOSYS);
+#endif
+}
diff --git a/libc-top-half/musl/src/linux/syncfs.c b/libc-top-half/musl/src/linux/syncfs.c
new file mode 100644
index 0000000..bc7d301
--- /dev/null
+++ b/libc-top-half/musl/src/linux/syncfs.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int syncfs(int fd)
+{
+ return syscall(SYS_syncfs, fd);
+}
diff --git a/libc-top-half/musl/src/linux/sysinfo.c b/libc-top-half/musl/src/linux/sysinfo.c
new file mode 100644
index 0000000..db86476
--- /dev/null
+++ b/libc-top-half/musl/src/linux/sysinfo.c
@@ -0,0 +1,9 @@
+#include <sys/sysinfo.h>
+#include "syscall.h"
+
+int __lsysinfo(struct sysinfo *info)
+{
+ return syscall(SYS_sysinfo, info);
+}
+
+weak_alias(__lsysinfo, sysinfo);
diff --git a/libc-top-half/musl/src/linux/tee.c b/libc-top-half/musl/src/linux/tee.c
new file mode 100644
index 0000000..a24748c
--- /dev/null
+++ b/libc-top-half/musl/src/linux/tee.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t tee(int src, int dest, size_t len, unsigned flags)
+{
+ return syscall(SYS_tee, src, dest, len, flags);
+}
diff --git a/libc-top-half/musl/src/linux/timerfd.c b/libc-top-half/musl/src/linux/timerfd.c
new file mode 100644
index 0000000..5bdfaf1
--- /dev/null
+++ b/libc-top-half/musl/src/linux/timerfd.c
@@ -0,0 +1,59 @@
+#include <sys/timerfd.h>
+#include <errno.h>
+#include "syscall.h"
+
+#define IS32BIT(x) !((x)+0x80000000ULL>>32)
+
+int timerfd_create(int clockid, int flags)
+{
+ return syscall(SYS_timerfd_create, clockid, flags);
+}
+
+int timerfd_settime(int fd, int flags, const struct itimerspec *new, struct itimerspec *old)
+{
+#ifdef SYS_timerfd_settime64
+ time_t is = new->it_interval.tv_sec, vs = new->it_value.tv_sec;
+ long ins = new->it_interval.tv_nsec, vns = new->it_value.tv_nsec;
+ int r = -ENOSYS;
+ if (SYS_timerfd_settime == SYS_timerfd_settime64
+ || !IS32BIT(is) || !IS32BIT(vs) || (sizeof(time_t)>4 && old))
+ r = __syscall(SYS_timerfd_settime64, fd, flags,
+ ((long long[]){is, ins, vs, vns}), old);
+ if (SYS_timerfd_settime == SYS_timerfd_settime64 || r!=-ENOSYS)
+ return __syscall_ret(r);
+ if (!IS32BIT(is) || !IS32BIT(vs))
+ return __syscall_ret(-ENOTSUP);
+ long old32[4];
+ r = __syscall(SYS_timerfd_settime, fd, flags,
+ ((long[]){is, ins, vs, vns}), old32);
+ if (!r && old) {
+ old->it_interval.tv_sec = old32[0];
+ old->it_interval.tv_nsec = old32[1];
+ old->it_value.tv_sec = old32[2];
+ old->it_value.tv_nsec = old32[3];
+ }
+ return __syscall_ret(r);
+#endif
+ return syscall(SYS_timerfd_settime, fd, flags, new, old);
+}
+
+int timerfd_gettime(int fd, struct itimerspec *cur)
+{
+#ifdef SYS_timerfd_gettime64
+ int r = -ENOSYS;
+ if (sizeof(time_t) > 4)
+ r = __syscall(SYS_timerfd_gettime64, fd, cur);
+ if (SYS_timerfd_gettime == SYS_timerfd_gettime64 || r!=-ENOSYS)
+ return __syscall_ret(r);
+ long cur32[4];
+ r = __syscall(SYS_timerfd_gettime, fd, cur32);
+ if (!r) {
+ cur->it_interval.tv_sec = cur32[0];
+ cur->it_interval.tv_nsec = cur32[1];
+ cur->it_value.tv_sec = cur32[2];
+ cur->it_value.tv_nsec = cur32[3];
+ }
+ return __syscall_ret(r);
+#endif
+ return syscall(SYS_timerfd_gettime, fd, cur);
+}
diff --git a/libc-top-half/musl/src/linux/unshare.c b/libc-top-half/musl/src/linux/unshare.c
new file mode 100644
index 0000000..3861db3
--- /dev/null
+++ b/libc-top-half/musl/src/linux/unshare.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include "syscall.h"
+
+int unshare(int flags)
+{
+ return syscall(SYS_unshare, flags);
+}
diff --git a/libc-top-half/musl/src/linux/utimes.c b/libc-top-half/musl/src/linux/utimes.c
new file mode 100644
index 0000000..6ca025d
--- /dev/null
+++ b/libc-top-half/musl/src/linux/utimes.c
@@ -0,0 +1,8 @@
+#include <sys/time.h>
+#include "fcntl.h"
+#include "syscall.h"
+
+int utimes(const char *path, const struct timeval times[2])
+{
+ return __futimesat(AT_FDCWD, path, times);
+}
diff --git a/libc-top-half/musl/src/linux/vhangup.c b/libc-top-half/musl/src/linux/vhangup.c
new file mode 100644
index 0000000..0203071
--- /dev/null
+++ b/libc-top-half/musl/src/linux/vhangup.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <unistd.h>
+#include "syscall.h"
+
+int vhangup(void)
+{
+ return syscall(SYS_vhangup);
+}
diff --git a/libc-top-half/musl/src/linux/vmsplice.c b/libc-top-half/musl/src/linux/vmsplice.c
new file mode 100644
index 0000000..ebf13ee
--- /dev/null
+++ b/libc-top-half/musl/src/linux/vmsplice.c
@@ -0,0 +1,8 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include "syscall.h"
+
+ssize_t vmsplice(int fd, const struct iovec *iov, size_t cnt, unsigned flags)
+{
+ return syscall(SYS_vmsplice, fd, iov, cnt, flags);
+}
diff --git a/libc-top-half/musl/src/linux/wait3.c b/libc-top-half/musl/src/linux/wait3.c
new file mode 100644
index 0000000..61c7359
--- /dev/null
+++ b/libc-top-half/musl/src/linux/wait3.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include "syscall.h"
+
+pid_t wait3(int *status, int options, struct rusage *usage)
+{
+ return wait4(-1, status, options, usage);
+}
diff --git a/libc-top-half/musl/src/linux/wait4.c b/libc-top-half/musl/src/linux/wait4.c
new file mode 100644
index 0000000..83650e3
--- /dev/null
+++ b/libc-top-half/musl/src/linux/wait4.c
@@ -0,0 +1,39 @@
+#define _GNU_SOURCE
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include <string.h>
+#include <errno.h>
+#include "syscall.h"
+
+pid_t wait4(pid_t pid, int *status, int options, struct rusage *ru)
+{
+ int r;
+#ifdef SYS_wait4_time64
+ if (ru) {
+ long long kru64[18];
+ r = __syscall(SYS_wait4_time64, pid, status, options, kru64);
+ if (!r) {
+ ru->ru_utime = (struct timeval)
+ { .tv_sec = kru64[0], .tv_usec = kru64[1] };
+ ru->ru_stime = (struct timeval)
+ { .tv_sec = kru64[2], .tv_usec = kru64[3] };
+ char *slots = (char *)&ru->ru_maxrss;
+ for (int i=0; i<14; i++)
+ *(long *)(slots + i*sizeof(long)) = kru64[4+i];
+ }
+ if (SYS_wait4_time64 == SYS_wait4 || r != -ENOSYS)
+ return __syscall_ret(r);
+ }
+#endif
+ char *dest = ru ? (char *)&ru->ru_maxrss - 4*sizeof(long) : 0;
+ r = __syscall(SYS_wait4, pid, status, options, dest);
+ if (r>0 && ru && sizeof(time_t) > sizeof(long)) {
+ long kru[4];
+ memcpy(kru, dest, 4*sizeof(long));
+ ru->ru_utime = (struct timeval)
+ { .tv_sec = kru[0], .tv_usec = kru[1] };
+ ru->ru_stime = (struct timeval)
+ { .tv_sec = kru[2], .tv_usec = kru[3] };
+ }
+ return __syscall_ret(r);
+}
diff --git a/libc-top-half/musl/src/linux/x32/sysinfo.c b/libc-top-half/musl/src/linux/x32/sysinfo.c
new file mode 100644
index 0000000..59b3bb7
--- /dev/null
+++ b/libc-top-half/musl/src/linux/x32/sysinfo.c
@@ -0,0 +1,49 @@
+#include <sys/sysinfo.h>
+#include "syscall.h"
+
+#define klong long long
+#define kulong unsigned long long
+
+struct kernel_sysinfo {
+ klong uptime;
+ kulong loads[3];
+ kulong totalram;
+ kulong freeram;
+ kulong sharedram;
+ kulong bufferram;
+ kulong totalswap;
+ kulong freeswap;
+ short procs;
+ short pad;
+ kulong totalhigh;
+ kulong freehigh;
+ unsigned mem_unit;
+};
+
+int __lsysinfo(struct sysinfo *info)
+{
+ struct kernel_sysinfo tmp;
+ int ret = syscall(SYS_sysinfo, &tmp);
+ if(ret == -1) return ret;
+ info->uptime = tmp.uptime;
+ info->loads[0] = tmp.loads[0];
+ info->loads[1] = tmp.loads[1];
+ info->loads[2] = tmp.loads[2];
+ kulong shifts;
+ kulong max = tmp.totalram | tmp.totalswap;
+ __asm__("bsr %1,%0" : "=r"(shifts) : "r"(max));
+ shifts = shifts >= 32 ? shifts - 31 : 0;
+ info->totalram = tmp.totalram >> shifts;
+ info->freeram = tmp.freeram >> shifts;
+ info->sharedram = tmp.sharedram >> shifts;
+ info->bufferram = tmp.bufferram >> shifts;
+ info->totalswap = tmp.totalswap >> shifts;
+ info->freeswap = tmp.freeswap >> shifts;
+ info->procs = tmp.procs ;
+ info->totalhigh = tmp.totalhigh >> shifts;
+ info->freehigh = tmp.freehigh >> shifts;
+ info->mem_unit = (tmp.mem_unit ? tmp.mem_unit : 1) << shifts;
+ return ret;
+}
+
+weak_alias(__lsysinfo, sysinfo);
diff --git a/libc-top-half/musl/src/linux/xattr.c b/libc-top-half/musl/src/linux/xattr.c
new file mode 100644
index 0000000..fea0d20
--- /dev/null
+++ b/libc-top-half/musl/src/linux/xattr.c
@@ -0,0 +1,62 @@
+#include <sys/xattr.h>
+#include "syscall.h"
+
+ssize_t getxattr(const char *path, const char *name, void *value, size_t size)
+{
+ return syscall(SYS_getxattr, path, name, value, size);
+}
+
+ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size)
+{
+ return syscall(SYS_lgetxattr, path, name, value, size);
+}
+
+ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size)
+{
+ return syscall(SYS_fgetxattr, filedes, name, value, size);
+}
+
+ssize_t listxattr(const char *path, char *list, size_t size)
+{
+ return syscall(SYS_listxattr, path, list, size);
+}
+
+ssize_t llistxattr(const char *path, char *list, size_t size)
+{
+ return syscall(SYS_llistxattr, path, list, size);
+}
+
+ssize_t flistxattr(int filedes, char *list, size_t size)
+{
+ return syscall(SYS_flistxattr, filedes, list, size);
+}
+
+int setxattr(const char *path, const char *name, const void *value, size_t size, int flags)
+{
+ return syscall(SYS_setxattr, path, name, value, size, flags);
+}
+
+int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags)
+{
+ return syscall(SYS_lsetxattr, path, name, value, size, flags);
+}
+
+int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags)
+{
+ return syscall(SYS_fsetxattr, filedes, name, value, size, flags);
+}
+
+int removexattr(const char *path, const char *name)
+{
+ return syscall(SYS_removexattr, path, name);
+}
+
+int lremovexattr(const char *path, const char *name)
+{
+ return syscall(SYS_lremovexattr, path, name);
+}
+
+int fremovexattr(int fd, const char *name)
+{
+ return syscall(SYS_fremovexattr, fd, name);
+}