diff options
Diffstat (limited to '')
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); +} |