diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:00 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:32 -0500 |
commit | bd5969fc876a10b18613302db7087ef3c40f18e1 (patch) | |
tree | 7c2b8619afe902abf99570df2873fbdf40a4d1a1 /lib/mlibc/options/linux/generic | |
parent | a95b38b1b92b172e6cc4e8e56a88a30cc65907b0 (diff) |
lib: Add mlibc
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/options/linux/generic')
29 files changed, 1134 insertions, 0 deletions
diff --git a/lib/mlibc/options/linux/generic/capabilities.cpp b/lib/mlibc/options/linux/generic/capabilities.cpp new file mode 100644 index 0000000..871822a --- /dev/null +++ b/lib/mlibc/options/linux/generic/capabilities.cpp @@ -0,0 +1,19 @@ +#include <mlibc/debug.hpp> + +#ifdef __cplusplus +extern "C" { +#endif + +int capset(void *, void *) { + mlibc::infoLogger() << "mlibc: capset is a no-op!" << frg::endlog; + return 0; +} + +int capget(void *, void *) { + mlibc::infoLogger() << "mlibc: capget is a no-op!" << frg::endlog; + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/lib/mlibc/options/linux/generic/cpuset.cpp b/lib/mlibc/options/linux/generic/cpuset.cpp new file mode 100644 index 0000000..d0292b7 --- /dev/null +++ b/lib/mlibc/options/linux/generic/cpuset.cpp @@ -0,0 +1,71 @@ +#include <limits.h> +#include <sched.h> +#include <stdlib.h> +#include <string.h> + +cpu_set_t *__mlibc_cpu_alloc(int num_cpus) { + return reinterpret_cast<cpu_set_t *>(calloc(1, CPU_ALLOC_SIZE(num_cpus))); +} + +#define CPU_MASK_BITS (CHAR_BIT * sizeof(__cpu_mask)) + +size_t __mlibc_cpu_alloc_size(int num_cpus) { + /* calculate the (unaligned) remainder that doesn't neatly fit in one __cpu_mask; 0 or 1 */ + size_t remainder = ((num_cpus % CPU_MASK_BITS) + CPU_MASK_BITS - 1) / CPU_MASK_BITS; + return sizeof(__cpu_mask) * (num_cpus / CPU_MASK_BITS + remainder); +} + +void __mlibc_cpu_zero(const size_t setsize, cpu_set_t *set) { + memset(set, 0, CPU_ALLOC_SIZE(setsize)); +} + +void __mlibc_cpu_set(const int cpu, const size_t setsize, cpu_set_t *set) { + if(cpu >= static_cast<int>(setsize * CHAR_BIT)) { + return; + } + + unsigned char *ptr = reinterpret_cast<unsigned char *>(set); + size_t off = cpu / CHAR_BIT; + size_t mask = 1 << (cpu % CHAR_BIT); + + ptr[off] |= mask; +} + +void __mlibc_cpu_clear(const int cpu, const size_t setsize, cpu_set_t *set) { + if(cpu >= static_cast<int>(setsize * CHAR_BIT)) { + return; + } + + unsigned char *ptr = reinterpret_cast<unsigned char *>(set); + size_t off = cpu / CHAR_BIT; + size_t mask = 1 << (cpu % CHAR_BIT); + + ptr[off] &= ~mask; +} + + +int __mlibc_cpu_isset(const int cpu, const size_t setsize, const cpu_set_t *set) { + if(cpu >= static_cast<int>(setsize * CHAR_BIT)) { + return false; + } + + const unsigned char *ptr = reinterpret_cast<const unsigned char *>(set); + size_t off = cpu / CHAR_BIT; + size_t mask = 1 << (cpu % CHAR_BIT); + + return (ptr[off] & mask); +} + +int __mlibc_cpu_count(const size_t setsize, const cpu_set_t *set) { + size_t count = 0; + const unsigned char *ptr = reinterpret_cast<const unsigned char *>(set); + + for(size_t i = 0; i < setsize; i++) { + for(size_t bit = 0; bit < CHAR_BIT; bit++) { + if((1 << bit) & ptr[i]) + count++; + } + } + + return count; +} diff --git a/lib/mlibc/options/linux/generic/ifaddrs.cpp b/lib/mlibc/options/linux/generic/ifaddrs.cpp new file mode 100644 index 0000000..67dfbc6 --- /dev/null +++ b/lib/mlibc/options/linux/generic/ifaddrs.cpp @@ -0,0 +1,15 @@ +#include <bits/ensure.h> +#include <mlibc/debug.hpp> +#include <ifaddrs.h> +#include <errno.h> + +int getifaddrs(struct ifaddrs **) { + mlibc::infoLogger() << "mlibc: getifaddrs fails unconditionally!" << frg::endlog; + errno = ENOSYS; + return -1; +} + +void freeifaddrs(struct ifaddrs *) { + mlibc::infoLogger() << "mlibc: freeifaddrs is a stub!" << frg::endlog; + return; +} diff --git a/lib/mlibc/options/linux/generic/linux-unistd.cpp b/lib/mlibc/options/linux/generic/linux-unistd.cpp new file mode 100644 index 0000000..ec13f72 --- /dev/null +++ b/lib/mlibc/options/linux/generic/linux-unistd.cpp @@ -0,0 +1,33 @@ +#include <bits/linux/linux_unistd.h> +#include <bits/ensure.h> + +#include <errno.h> +#include <mlibc/posix-sysdeps.hpp> +#include <unistd.h> + +int dup3(int oldfd, int newfd, int flags) { + if(oldfd == newfd) { + errno = EINVAL; + return -1; + } + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_dup2, -1); + if(int e = mlibc::sys_dup2(oldfd, flags, newfd); e) { + errno = e; + return -1; + } + return newfd; +} + +int vhangup(void) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} + +int getdtablesize(void){ + return sysconf(_SC_OPEN_MAX); +} + +int syncfs(int) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} diff --git a/lib/mlibc/options/linux/generic/malloc.cpp b/lib/mlibc/options/linux/generic/malloc.cpp new file mode 100644 index 0000000..065de6c --- /dev/null +++ b/lib/mlibc/options/linux/generic/malloc.cpp @@ -0,0 +1,7 @@ +#include <bits/ensure.h> +#include <malloc.h> + +void *memalign(size_t, size_t) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} diff --git a/lib/mlibc/options/linux/generic/mntent-stubs.cpp b/lib/mlibc/options/linux/generic/mntent-stubs.cpp new file mode 100644 index 0000000..35c0e92 --- /dev/null +++ b/lib/mlibc/options/linux/generic/mntent-stubs.cpp @@ -0,0 +1,98 @@ + +#include <errno.h> +#include <mntent.h> +#include <stdio.h> +#include <limits.h> +#include <string.h> +#include <bits/ensure.h> + +namespace { + +char *internal_buf; +size_t internal_bufsize; + +} + +#define SENTINEL (char *)&internal_buf + +FILE *setmntent(const char *name, const char *mode) { + return fopen(name, mode); +} + +struct mntent *getmntent(FILE *f) { + static struct mntent mnt; + return getmntent_r(f, &mnt, SENTINEL, 0); +} + +int addmntent(FILE *f, const struct mntent *mnt) { + if(fseek(f, 0, SEEK_END)) { + return 1; + } + return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n", + mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts, + mnt->mnt_freq, mnt->mnt_passno) < 0; +} + +int endmntent(FILE *f) { + if(f) { + fclose(f); + } + return 1; +} + +char *hasmntopt(const struct mntent *mnt, const char *opt) { + return strstr(mnt->mnt_opts, opt); +} + +/* Adapted from musl */ +struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen) { + int n[8]; + bool use_internal = (linebuf == SENTINEL); + int len; + size_t i; + + mnt->mnt_freq = 0; + mnt->mnt_passno = 0; + + do { + if(use_internal) { + getline(&internal_buf, &internal_bufsize, f); + linebuf = internal_buf; + } else { + fgets(linebuf, buflen, f); + } + if(feof(f) || ferror(f)) { + return 0; + } + if(!strchr(linebuf, '\n')) { + fscanf(f, "%*[^\n]%*[\n]"); + errno = ERANGE; + return 0; + } + + len = strlen(linebuf); + if(len > INT_MAX) { + continue; + } + + for(i = 0; i < sizeof n / sizeof *n; i++) { + n[i] = len; + } + + sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d", + n, n + 1, n + 2, n + 3, n + 4, n + 5, n + 6, n + 7, + &mnt->mnt_freq, &mnt->mnt_passno); + } while(linebuf[n[0]] == '#' || n[1] == len); + + linebuf[n[1]] = 0; + linebuf[n[3]] = 0; + linebuf[n[5]] = 0; + linebuf[n[7]] = 0; + + mnt->mnt_fsname = linebuf + n[0]; + mnt->mnt_dir = linebuf + n[2]; + mnt->mnt_type = linebuf + n[4]; + mnt->mnt_opts = linebuf + n[6]; + + return mnt; +} diff --git a/lib/mlibc/options/linux/generic/module.cpp b/lib/mlibc/options/linux/generic/module.cpp new file mode 100644 index 0000000..53b6dc8 --- /dev/null +++ b/lib/mlibc/options/linux/generic/module.cpp @@ -0,0 +1,24 @@ +#include <errno.h> +#include <module.h> + +#include <bits/ensure.h> +#include <mlibc/debug.hpp> +#include <mlibc/linux-sysdeps.hpp> + +int init_module(void *module, unsigned long length, const char *args) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_init_module, -1); + if(int e = mlibc::sys_init_module(module, length, args); e) { + errno = e; + return -1; + } + return 0; +} + +int delete_module(const char *name, unsigned flags) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_delete_module, -1); + if(int e = mlibc::sys_delete_module(name, flags); e) { + errno = e; + return -1; + } + return 0; +} diff --git a/lib/mlibc/options/linux/generic/pty-stubs.cpp b/lib/mlibc/options/linux/generic/pty-stubs.cpp new file mode 100644 index 0000000..8d95027 --- /dev/null +++ b/lib/mlibc/options/linux/generic/pty-stubs.cpp @@ -0,0 +1,101 @@ + +#include <asm/ioctls.h> +#include <bits/ensure.h> +#include <errno.h> +#include <fcntl.h> +#include <pty.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdlib.h> + +#include <mlibc/debug.hpp> +#include <mlibc/linux-sysdeps.hpp> + +int openpty(int *mfd, int *sfd, char *name, const struct termios *ios, const struct winsize *win) { + int ptmx_fd; + if(int e = mlibc::sys_open("/dev/ptmx", O_RDWR | O_NOCTTY, 0, &ptmx_fd); e) { + errno = e; + goto fail; + } + + char spath[32]; + if(!name) + name = spath; + if(ptsname_r(ptmx_fd, name, 32)) + goto fail; + + int pts_fd; + unlockpt(ptmx_fd); + if(int e = mlibc::sys_open(name, O_RDWR | O_NOCTTY, 0, &pts_fd); e) { + errno = e; + goto fail; + } + + if(ios) + tcsetattr(ptmx_fd, TCSAFLUSH, ios); + + if(win) + ioctl(ptmx_fd, TIOCSWINSZ, (void*)win); + + *mfd = ptmx_fd; + *sfd = pts_fd; + return 0; + +fail: + mlibc::sys_close(ptmx_fd); + return -1; +} + +int login_tty(int fd) { + if(setsid() == -1) + return -1; + if(ioctl(fd, TIOCSCTTY, 0)) + return -1; + + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_dup2, -1); + if(int e = mlibc::sys_dup2(fd, 0, STDIN_FILENO); e) { + errno = e; + return -1; + } + if(int e = mlibc::sys_dup2(fd, 0, STDOUT_FILENO); e) { + errno = e; + return -1; + } + if(int e = mlibc::sys_dup2(fd, 0, STDERR_FILENO); e) { + errno = e; + return -1; + } + + if(int e = mlibc::sys_close(fd); e) { + errno = e; + return -1; + } + return 0; +} + +int forkpty(int *mfd, char *name, const struct termios *ios, const struct winsize *win) { + int sfd; + if(openpty(mfd, &sfd, name, ios, win)) + return -1; + + pid_t child; + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fork, -1); + if(int e = mlibc::sys_fork(&child); e) { + errno = e; + return -1; + } + + if(!child) { + if(login_tty(sfd)) + mlibc::panicLogger() << "mlibc: TTY login fail in forkpty() child" << frg::endlog; + }else{ + if(int e = mlibc::sys_close(sfd); e) { + errno = e; + return -1; + } + } + + return child; +} + diff --git a/lib/mlibc/options/linux/generic/sched.cpp b/lib/mlibc/options/linux/generic/sched.cpp new file mode 100644 index 0000000..760a9f5 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sched.cpp @@ -0,0 +1,50 @@ +#include <bits/ensure.h> +#include <errno.h> +#include <sched.h> + +#include <mlibc/linux-sysdeps.hpp> +#include <mlibc/posix-sysdeps.hpp> + +int sched_getcpu(void) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getcpu, -1); + int cpu; + if(int e = mlibc::sys_getcpu(&cpu); e) { + errno = e; + return -1; + } + return cpu; +} + +int setns(int, int) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} + +int sched_getscheduler(pid_t) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} + +int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getaffinity, -1); + if(int e = mlibc::sys_getaffinity(pid, cpusetsize, mask); e) { + errno = e; + return -1; + } + return 0; +} + +int unshare(int) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} + +int sched_setaffinity(pid_t, size_t, const cpu_set_t *) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} + +int clone(int (*)(void *), void *, int, void *, ...) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} diff --git a/lib/mlibc/options/linux/generic/sys-epoll.cpp b/lib/mlibc/options/linux/generic/sys-epoll.cpp new file mode 100644 index 0000000..799d1a9 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-epoll.cpp @@ -0,0 +1,58 @@ + +#include <errno.h> +#include <sys/epoll.h> + +#include <bits/ensure.h> +#include <mlibc/linux-sysdeps.hpp> +#include <stddef.h> + +int epoll_create(int) { + int fd; + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_create, -1); + if(int e = mlibc::sys_epoll_create(0, &fd); e) { + errno = e; + return -1; + } + return fd; +} + +int epoll_pwait(int epfd, struct epoll_event *evnts, int n, int timeout, + const sigset_t *sigmask) { + int raised; + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_pwait, -1); + if(int e = mlibc::sys_epoll_pwait(epfd, evnts, n, timeout, sigmask, &raised)) { + errno = e; + return -1; + } + return raised; +} + +int epoll_create1(int flags) { + int fd; + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_create, -1); + if(int e = mlibc::sys_epoll_create(flags, &fd); e) { + errno = e; + return -1; + } + return fd; +} + +int epoll_ctl(int epfd, int mode, int fd, struct epoll_event *ev) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_ctl, -1); + if(int e = mlibc::sys_epoll_ctl(epfd, mode, fd, ev); e) { + errno = e; + return -1; + } + return 0; +} + +int epoll_wait(int epfd, struct epoll_event *evnts, int n, int timeout) { + int raised; + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_pwait, -1); + if(int e = mlibc::sys_epoll_pwait(epfd, evnts, n, timeout, NULL, &raised)) { + errno = e; + return -1; + } + return raised; +} + diff --git a/lib/mlibc/options/linux/generic/sys-eventfd.cpp b/lib/mlibc/options/linux/generic/sys-eventfd.cpp new file mode 100644 index 0000000..1d83d8c --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-eventfd.cpp @@ -0,0 +1,45 @@ +#include <sys/eventfd.h> +#include <errno.h> + +#include <bits/ensure.h> +#include <mlibc/linux-sysdeps.hpp> + +int eventfd(unsigned int initval, int flags) { + int fd = 0; + + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_eventfd_create, -1); + if (int e = mlibc::sys_eventfd_create(initval, flags, &fd); e) { + errno = e; + return -1; + } + + return fd; +} + +int eventfd_read(int fd, eventfd_t *value) { + ssize_t bytes_read; + if (int e = mlibc::sys_read(fd, value, 8, &bytes_read); e) { + errno = e; + return -1; + } + + if (bytes_read != 8) { + return -1; + } + + return 0; +} + +int eventfd_write(int fd, eventfd_t value) { + ssize_t bytes_written; + if (int e = mlibc::sys_write(fd, &value, 8, &bytes_written); e) { + errno = e; + return -1; + } + + if (bytes_written != 8) { + return -1; + } + + return 0; +} diff --git a/lib/mlibc/options/linux/generic/sys-fsuid.cpp b/lib/mlibc/options/linux/generic/sys-fsuid.cpp new file mode 100644 index 0000000..653456c --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-fsuid.cpp @@ -0,0 +1,12 @@ +#include <bits/ensure.h> +#include <sys/fsuid.h> + +int setfsuid(uid_t) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} + +int setfsgid(gid_t) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} diff --git a/lib/mlibc/options/linux/generic/sys-inotify-stubs.cpp b/lib/mlibc/options/linux/generic/sys-inotify-stubs.cpp new file mode 100644 index 0000000..0bc25c9 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-inotify-stubs.cpp @@ -0,0 +1,47 @@ + +#include <errno.h> +#include <sys/inotify.h> + +#include <bits/ensure.h> +#include <mlibc/debug.hpp> +#include <mlibc/linux-sysdeps.hpp> + +int inotify_init(void) { + int fd; + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_inotify_create, -1); + if(int e = mlibc::sys_inotify_create(0, &fd); e) { + errno = e; + return -1; + } + return fd; +} + +int inotify_init1(int flags) { + int fd; + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_inotify_create, -1); + if(int e = mlibc::sys_inotify_create(flags, &fd); e) { + errno = e; + return -1; + } + return fd; +} + +int inotify_add_watch(int ifd, const char *path, uint32_t mask) { + int wd; + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_inotify_add_watch, -1); + if(int e = mlibc::sys_inotify_add_watch(ifd, path, mask, &wd); e) { + errno = e; + return -1; + } + return wd; +} + +int inotify_rm_watch(int ifd, int wd) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_inotify_rm_watch, -1); + if(int e = mlibc::sys_inotify_rm_watch(ifd, wd); e) { + errno = e; + return -1; + } + return 0; +} + diff --git a/lib/mlibc/options/linux/generic/sys-klog.cpp b/lib/mlibc/options/linux/generic/sys-klog.cpp new file mode 100644 index 0000000..059e292 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-klog.cpp @@ -0,0 +1,16 @@ +#include <errno.h> +#include <sys/klog.h> + +#include <bits/ensure.h> + +#include <mlibc/linux-sysdeps.hpp> + +int klogctl(int type, char *bufp, int len) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_klogctl, -1); + int out; + if (int e = mlibc::sys_klogctl(type, bufp, len, &out); e) { + errno = e; + return -1; + } + return out; +} diff --git a/lib/mlibc/options/linux/generic/sys-mount.cpp b/lib/mlibc/options/linux/generic/sys-mount.cpp new file mode 100644 index 0000000..4783183 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-mount.cpp @@ -0,0 +1,29 @@ + +#include <errno.h> +#include <sys/mount.h> + +#include <bits/ensure.h> +#include <mlibc/linux-sysdeps.hpp> + +int mount(const char *source, const char *target, + const char *fstype, unsigned long flags, const void *data) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_mount, -1); + if(int e = mlibc::sys_mount(source, target, fstype, flags, data); e) { + errno = e; + return -1; + } + return 0; +} + +int umount(const char *target) { + return umount2(target, 0); +} + +int umount2(const char *target, int flags) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_umount2, -1); + if(int e = mlibc::sys_umount2(target, flags); e) { + errno = e; + return -1; + } + return 0; +} diff --git a/lib/mlibc/options/linux/generic/sys-prctl-stubs.cpp b/lib/mlibc/options/linux/generic/sys-prctl-stubs.cpp new file mode 100644 index 0000000..5280332 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-prctl-stubs.cpp @@ -0,0 +1,25 @@ + +#include <stdarg.h> +#include <errno.h> +#include <bits/ensure.h> +#include <sys/prctl.h> + +#include <mlibc/debug.hpp> + +#include "mlibc/linux-sysdeps.hpp" + +int prctl(int op, ...) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_prctl, -1); + + int val; + va_list ap; + va_start(ap, op); + if(int e = mlibc::sys_prctl(op, ap, &val); e) { + errno = e; + return -1; + } + va_end(ap); + + return val; +} + diff --git a/lib/mlibc/options/linux/generic/sys-ptrace-stubs.cpp b/lib/mlibc/options/linux/generic/sys-ptrace-stubs.cpp new file mode 100644 index 0000000..8c836c5 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-ptrace-stubs.cpp @@ -0,0 +1,36 @@ + +#include <sys/ptrace.h> +#include <stdarg.h> +#include <errno.h> + +#include <bits/ensure.h> +#include <mlibc/debug.hpp> +#include <mlibc/linux-sysdeps.hpp> + +long ptrace(int req, ...) { + va_list ap; + + va_start(ap, req); + auto pid = va_arg(ap, pid_t); + auto addr = va_arg(ap, void *); + auto data = va_arg(ap, void *); + va_end(ap); + + long ret; + if(req > 0 && req < 4) { + data = &ret; + } + + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ptrace, -1); + long out; + if(int e = mlibc::sys_ptrace(req, pid, addr, data, &out); e) { + errno = e; + return -1; + } else if(req > 0 && req < 4) { + errno = 0; + return ret; + } + + return out; +} + diff --git a/lib/mlibc/options/linux/generic/sys-quota.cpp b/lib/mlibc/options/linux/generic/sys-quota.cpp new file mode 100644 index 0000000..27c0e6d --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-quota.cpp @@ -0,0 +1,7 @@ +#include <bits/ensure.h> +#include <sys/quota.h> + +int quotactl(int, const char *, int, caddr_t) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} diff --git a/lib/mlibc/options/linux/generic/sys-random-stubs.cpp b/lib/mlibc/options/linux/generic/sys-random-stubs.cpp new file mode 100644 index 0000000..5e5057f --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-random-stubs.cpp @@ -0,0 +1,21 @@ + +#include <sys/random.h> +#include <bits/ensure.h> + +#include <mlibc/debug.hpp> +#include <mlibc/posix-sysdeps.hpp> + +#include <errno.h> + +ssize_t getrandom(void *buffer, size_t max_size, unsigned int flags) { + if(flags & ~(GRND_RANDOM | GRND_NONBLOCK)) { + errno = EINVAL; + return -1; + } + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getentropy, -1); + if(int e = mlibc::sys_getentropy(buffer, max_size); e) { + errno = e; + return -1; + } + return max_size; +} diff --git a/lib/mlibc/options/linux/generic/sys-reboot.cpp b/lib/mlibc/options/linux/generic/sys-reboot.cpp new file mode 100644 index 0000000..c9b503f --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-reboot.cpp @@ -0,0 +1,13 @@ +#include <errno.h> +#include <sys/reboot.h> +#include <bits/ensure.h> +#include <mlibc/linux-sysdeps.hpp> + +int reboot(int what) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_reboot, -1); + if (int e = mlibc::sys_reboot(what); e) { + errno = e; + return -1; + } + return 0; +} diff --git a/lib/mlibc/options/linux/generic/sys-sendfile-stubs.cpp b/lib/mlibc/options/linux/generic/sys-sendfile-stubs.cpp new file mode 100644 index 0000000..25cd0a0 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-sendfile-stubs.cpp @@ -0,0 +1,9 @@ + +#include <sys/sendfile.h> +#include <bits/ensure.h> + +ssize_t sendfile(int, int, off_t *, size_t) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} + diff --git a/lib/mlibc/options/linux/generic/sys-signalfd.cpp b/lib/mlibc/options/linux/generic/sys-signalfd.cpp new file mode 100644 index 0000000..28cfea0 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-signalfd.cpp @@ -0,0 +1,17 @@ + +#include <errno.h> +#include <sys/signalfd.h> + +#include <bits/ensure.h> +#include <mlibc/linux-sysdeps.hpp> + +int signalfd(int fd, const sigset_t *mask, int flags) { + __ensure(fd == -1); + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_signalfd_create, -1); + if(int e = mlibc::sys_signalfd_create(mask, flags, &fd); e) { + errno = e; + return -1; + } + return fd; +} + diff --git a/lib/mlibc/options/linux/generic/sys-statfs-stubs.cpp b/lib/mlibc/options/linux/generic/sys-statfs-stubs.cpp new file mode 100644 index 0000000..6152ef2 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-statfs-stubs.cpp @@ -0,0 +1,26 @@ + +#include <errno.h> +#include <sys/statfs.h> +#include <bits/ensure.h> + +#include <mlibc/debug.hpp> +#include <mlibc/linux-sysdeps.hpp> + +int statfs(const char *path, struct statfs *buf) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_statfs, -1); + if(int e = mlibc::sys_statfs(path, buf); e) { + errno = e; + return -1; + } + return 0; +} + +int fstatfs(int fd, struct statfs *buf) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fstatfs, -1); + if (int e = mlibc::sys_fstatfs(fd, buf); e) { + errno = e; + return -1; + } + return 0; +} + diff --git a/lib/mlibc/options/linux/generic/sys-swap.cpp b/lib/mlibc/options/linux/generic/sys-swap.cpp new file mode 100644 index 0000000..44ddf98 --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-swap.cpp @@ -0,0 +1,24 @@ +#include <errno.h> +#include <sys/swap.h> + +#include <bits/ensure.h> +#include <mlibc/debug.hpp> +#include <mlibc/linux-sysdeps.hpp> + +int swapon(const char *path, int flags) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_swapon, -1); + if(int e = mlibc::sys_swapon(path, flags); e) { + errno = e; + return -1; + } + return 0; +} + +int swapoff(const char *path) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_swapoff, -1); + if(int e = mlibc::sys_swapoff(path); e) { + errno = e; + return -1; + } + return 0; +} diff --git a/lib/mlibc/options/linux/generic/sys-sysinfo.cpp b/lib/mlibc/options/linux/generic/sys-sysinfo.cpp new file mode 100644 index 0000000..950c38a --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-sysinfo.cpp @@ -0,0 +1,15 @@ +#include <errno.h> +#include <sys/sysinfo.h> + +#include <bits/ensure.h> +#include <mlibc/debug.hpp> +#include <mlibc/linux-sysdeps.hpp> + +int sysinfo(struct sysinfo *info) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sysinfo, -1); + if(int e = mlibc::sys_sysinfo(info); e) { + errno = e; + return -1; + } + return 0; +} diff --git a/lib/mlibc/options/linux/generic/sys-timerfd.cpp b/lib/mlibc/options/linux/generic/sys-timerfd.cpp new file mode 100644 index 0000000..80bca1b --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-timerfd.cpp @@ -0,0 +1,33 @@ + +#include <errno.h> +#include <sys/timerfd.h> + +#include <bits/ensure.h> +#include <mlibc/debug.hpp> +#include <mlibc/linux-sysdeps.hpp> + +int timerfd_create(int clockid, int flags) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_timerfd_create, -1); + int fd; + if(int e = mlibc::sys_timerfd_create(clockid, flags, &fd); e) { + errno = e; + return -1; + } + return fd; +} + +int timerfd_settime(int fd, int flags, const struct itimerspec *value, + struct itimerspec *oldvalue) { + MLIBC_CHECK_OR_ENOSYS(mlibc::sys_timerfd_settime, -1); + if(int e = mlibc::sys_timerfd_settime(fd, flags, value, oldvalue); e) { + errno = e; + return -1; + } + return 0; +} + +int timerfd_gettime(int, struct itimerspec *) { + __ensure(!"Not implemented"); + __builtin_unreachable(); +} + diff --git a/lib/mlibc/options/linux/generic/sys-xattr.cpp b/lib/mlibc/options/linux/generic/sys-xattr.cpp new file mode 100644 index 0000000..c8d598f --- /dev/null +++ b/lib/mlibc/options/linux/generic/sys-xattr.cpp @@ -0,0 +1,122 @@ +#include <errno.h> +#include <sys/xattr.h> + +#include <mlibc/linux-sysdeps.hpp> +#include <bits/ensure.h> + +int setxattr(const char *path, const char *name, const void *val, size_t size, + int flags) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setxattr, -1); + + if (int e = sysdep(path, name, val, size, flags); e) { + errno = e; + return -1; + } + return 0; +} + +int lsetxattr(const char *path, const char *name, const void *val, size_t size, + int flags) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_lsetxattr, -1); + + if (int e = sysdep(path, name, val, size, flags); e) { + errno = e; + return -1; + } + return 0; +} + +int fsetxattr(int fd, const char *name, const void *val, size_t size, + int flags) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fsetxattr, -1); + + if (int e = sysdep(fd, name, val, size, flags); e) { + errno = e; + return -1; + } + return 0; +} + +ssize_t getxattr(const char *path, const char *name, void *val, size_t size) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getxattr, -1); + + ssize_t nread; + if (int e = sysdep(path, name, val, size, &nread); e) { + errno = e; + return -1; + } + + return nread; +} + +ssize_t lgetxattr(const char *path, const char *name, void *val, size_t size) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_lgetxattr, -1); + + ssize_t nread; + if (int e = sysdep(path, name, val, size, &nread); e) { + errno = e; + return -1; + } + + return nread; +} + +ssize_t fgetxattr(int fd, const char *name, void *val, size_t size) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fgetxattr, -1); + + ssize_t nread; + if (int e = sysdep(fd, name, val, size, &nread); e) { + errno = e; + return -1; + } + + return nread; +} + +int removexattr(const char *path, const char *name) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_removexattr, -1); + return sysdep(path, name); +} + +int lremovexattr(const char *path, const char *name) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_lremovexattr, -1); + return sysdep(path, name); +} + +int fremovexattr(int fd, const char *name) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fremovexattr, -1); + return sysdep(fd, name); +} + +ssize_t listxattr(const char *path, char *list, size_t size) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_listxattr, -1); + + ssize_t nread; + if (int e = sysdep(path, list, size, &nread); e) { + errno = e; + return -1; + } + return nread; +} + +ssize_t llistxattr(const char *path, char *list, size_t size) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_llistxattr, -1); + + ssize_t nread; + if (int e = sysdep(path, list, size, &nread); e) { + errno = e; + return -1; + } + return nread; +} + +ssize_t flistxattr(int fd, char *list, size_t size) { + auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_flistxattr, -1); + + ssize_t nread; + if (int e = sysdep(fd, list, size, &nread); e) { + errno = e; + return -1; + } + return nread; +} diff --git a/lib/mlibc/options/linux/generic/utmp-stubs.cpp b/lib/mlibc/options/linux/generic/utmp-stubs.cpp new file mode 100644 index 0000000..658dfd3 --- /dev/null +++ b/lib/mlibc/options/linux/generic/utmp-stubs.cpp @@ -0,0 +1,116 @@ +#include <utmp.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> + +#include <bits/ensure.h> +#include <mlibc/debug.hpp> + +/* + * The code in this file is largely based on glibc. + * This includes: + * - setutent + * - read_last_entry + * - getutent + * - getutent_r + * - endutent + */ +static int fd = -1; +static off_t offset; + +static struct utmp last_entry; + +void setutent(void) { + if(fd < 0) { + fd = open("/run/utmp", O_RDONLY | O_LARGEFILE | O_CLOEXEC); + if(fd == -1) { + return; + } + } + + lseek(fd, 0, SEEK_SET); + offset = 0; +} + +static ssize_t read_last_entry(void) { + struct utmp buf; + ssize_t bytes_read = pread(fd, &buf, sizeof(buf), offset); + + if(bytes_read < 0) { + return -1; + } else if(bytes_read != sizeof(buf)) { + // EOF + return 0; + } else { + last_entry = buf; + offset += sizeof(buf); + return 1; + } +} + +struct utmp *getutent(void) { + struct utmp *result; + static struct utmp *buf; + if(buf == NULL) { + buf = (struct utmp *)malloc(sizeof(struct utmp)); + if(buf == NULL) { + return NULL; + } + } + + if(getutent_r(buf, &result) < 0) { + return NULL; + } + return result; +} + +int getutent_r(struct utmp *buf, struct utmp **res) { + int saved_errno = errno; + + if(fd < 0) { + setutent(); + } + + ssize_t bytes_read = read_last_entry(); + + if(bytes_read <= 0) { + if(bytes_read == 0) { + errno = saved_errno; + *res = NULL; + return -1; + } + } + + memcpy(buf, &last_entry, sizeof(struct utmp)); + *res = buf; + + return 0; +} + +void endutent(void) { + if(fd >= 0) { + close(fd); + fd = -1; + } +} + +struct utmp *pututline(const struct utmp *) { + mlibc::infoLogger() << "\e[31mmlibc: pututline() is a stub!\e[39m" << frg::endlog; + return NULL; +} + +struct utmp *getutline(const struct utmp *) { + mlibc::infoLogger() << "\e[31mmlibc: getutline() is a stub!\e[39m" << frg::endlog; + return NULL; +} + +int utmpname(const char *) { + mlibc::infoLogger() << "\e[31mmlibc: utmpname() is a stub!\e[39m" << frg::endlog; + return -1; +} + +struct utmp *getutid(const struct utmp *) { + mlibc::infoLogger() << "\e[31mmlibc: getutid() is a stub!\e[39m" << frg::endlog; + return NULL; +} diff --git a/lib/mlibc/options/linux/generic/utmpx.cpp b/lib/mlibc/options/linux/generic/utmpx.cpp new file mode 100644 index 0000000..4742567 --- /dev/null +++ b/lib/mlibc/options/linux/generic/utmpx.cpp @@ -0,0 +1,45 @@ +#include <bits/ensure.h> +#include <stddef.h> +#include <errno.h> +#include <utmpx.h> +#include <mlibc/debug.hpp> + +void updwtmpx(const char *, const struct utmpx *) { + // Empty as musl does + mlibc::infoLogger() << "\e[31mmlibc: updwtmpx() is a stub\e[39m" << frg::endlog; +} + +void endutxent(void) { + // Empty as musl does + mlibc::infoLogger() << "\e[31mmlibc: endutxent() is a stub\e[39m" << frg::endlog; +} + +void setutxent(void) { + // Empty as musl does + mlibc::infoLogger() << "\e[31mmlibc: setutxent() is a stub\e[39m" << frg::endlog; +} + +struct utmpx *getutxent(void) { + // return NULL as musl does + mlibc::infoLogger() << "\e[31mmlibc: getutxent() is a stub\e[39m" << frg::endlog; + return NULL; +} + +struct utmpx *pututxline(const struct utmpx *) { + // return NULL as musl does + mlibc::infoLogger() << "\e[31mmlibc: pututxline() is a stub\e[39m" << frg::endlog; + return NULL; +} + +int utmpxname(const char *) { + // return -1 as musl does + mlibc::infoLogger() << "\e[31mmlibc: utmpxname() is a stub\e[39m" << frg::endlog; + errno = ENOSYS; + return -1; +} + +struct utmpx *getutxid(const struct utmpx *) { + // return NULL as musl does + mlibc::infoLogger() << "\e[31mmlibc: getutxid() is a stub\e[39m" << frg::endlog; + return NULL; +} |