Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions options/ansi/generic/file-io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <mlibc/allocator.hpp>
#include <mlibc/file-io.hpp>
#include <mlibc/ansi-sysdeps.hpp>
#include <mlibc/sysdeps.hpp>
#include <mlibc/lock.hpp>

namespace mlibc {
Expand Down Expand Up @@ -513,22 +514,22 @@ int fd_file::determine_bufmode(buffer_mode *mode) {

int fd_file::io_read(char *buffer, size_t max_size, size_t *actual_size) {
ssize_t s;
if(int e = mlibc::sys_read(_fd, buffer, max_size, &s); e)
if(int e = sysdeps.read(_fd, buffer, max_size, &s); e)
return e;
*actual_size = s;
return 0;
}

int fd_file::io_write(const char *buffer, size_t max_size, size_t *actual_size) {
ssize_t s;
if(int e = mlibc::sys_write(_fd, buffer, max_size, &s); e)
if(int e = sysdeps.write(_fd, buffer, max_size, &s); e)
return e;
*actual_size = s;
return 0;
}

int fd_file::io_seek(off_t offset, int whence, off_t *new_offset) {
if(int e = mlibc::sys_seek(_fd, offset, whence, new_offset); e)
if(int e = sysdeps.seek(_fd, offset, whence, new_offset); e)
return e;
return 0;
}
Expand Down
9 changes: 4 additions & 5 deletions options/ansi/generic/signal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <mlibc/debug.hpp>
#include <mlibc/ansi-sysdeps.hpp>
#include <mlibc/sysdeps.hpp>

__sighandler signal(int sn, __sighandler handler) {
struct sigaction sa;
Expand All @@ -21,10 +22,9 @@ __sighandler signal(int sn, __sighandler handler) {
}

int raise(int sig) {
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getpid && mlibc::sys_kill, -1);
pid_t pid = mlibc::sys_getpid();
pid_t pid = sysdeps.getpid();

if (int e = mlibc::sys_kill(pid, sig)) {
if (int e = sysdeps.kill(pid, sig)) {
errno = e;
return -1;
}
Expand All @@ -34,8 +34,7 @@ int raise(int sig) {

// This is a POSIX extension, but we have it in here for sigsetjmp
int sigprocmask(int how, const sigset_t *__restrict set, sigset_t *__restrict retrieve) {
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigprocmask, -1);
if(int e = mlibc::sys_sigprocmask(how, set, retrieve); e) {
if(int e = sysdeps.sigprocmask(how, set, retrieve); e) {
errno = e;
return -1;
}
Expand Down
9 changes: 5 additions & 4 deletions options/ansi/generic/stdlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <mlibc/ansi-sysdeps.hpp>
#include <mlibc/strtofp.hpp>
#include <mlibc/strtol.hpp>
#include <mlibc/sysdeps.hpp>
#include <mlibc/threads.hpp>
#include <mlibc/global-config.hpp>

Expand Down Expand Up @@ -228,7 +229,7 @@ int system(const char *command) {
pid_t child;

MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fork && mlibc::sys_waitpid &&
mlibc::sys_execve && mlibc::sys_sigprocmask && mlibc::sys_sigaction, -1);
mlibc::sys_execve && (hasSysdep<&mlibc::Sysdeps::sigprocmask, mlibc::AnsiSysdeps>()) && mlibc::sys_sigaction, -1);

#if __MLIBC_POSIX_OPTION
pthread_testcancel();
Expand All @@ -249,14 +250,14 @@ int system(const char *command) {

sigemptyset(&new_mask);
sigaddset(&new_mask, SIGCHLD);
mlibc::sys_sigprocmask(SIG_BLOCK, &new_mask, &old_mask);
sysdeps.sigprocmask(SIG_BLOCK, &new_mask, &old_mask);

if (int e = mlibc::sys_fork(&child)) {
errno = e;
} else if (!child) {
mlibc::sys_sigaction(SIGINT, &old_int, nullptr);
mlibc::sys_sigaction(SIGQUIT, &old_quit, nullptr);
mlibc::sys_sigprocmask(SIG_SETMASK, &old_mask, nullptr);
sysdeps.sigprocmask(SIG_SETMASK, &old_mask, nullptr);

const char *args[] = {
"sh", "-c", command, nullptr
Expand All @@ -279,7 +280,7 @@ int system(const char *command) {

mlibc::sys_sigaction(SIGINT, &old_int, nullptr);
mlibc::sys_sigaction(SIGQUIT, &old_quit, nullptr);
mlibc::sys_sigprocmask(SIG_SETMASK, &old_mask, nullptr);
sysdeps.sigprocmask(SIG_SETMASK, &old_mask, nullptr);

return status;
}
Expand Down
35 changes: 31 additions & 4 deletions options/ansi/include/mlibc/ansi-sysdeps.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#ifndef MLIBC_ANSI_SYSDEPS
#define MLIBC_ANSI_SYSDEPS

#include <errno.h>
#include <stddef.h>
#include <signal.h>

#include <abi-bits/seek-whence.h>
#include <abi-bits/vm-flags.h>
Expand All @@ -10,15 +12,13 @@
#include <bits/off_t.h>
#include <bits/ssize_t.h>
#include <bits/ansi/time_t.h>
#include <signal.h>
#include <stdarg.h>

struct rusage;

namespace [[gnu::visibility("hidden")]] mlibc {

[[noreturn]] void sys_exit(int status);
[[noreturn, gnu::weak]] void sys_thread_exit();
[[noreturn]] void sys_thread_exit();

// If *stack is not null, it should point to the lowest addressable byte of the stack.
// Returns the new stack pointer in *stack and the stack base in *stack_base.
Expand Down Expand Up @@ -64,9 +64,36 @@ int sys_clock_get(int clock, time_t *secs, long *nanos);
[[gnu::weak]] int sys_waitpid(pid_t pid, int *status, int flags, struct rusage *ru, pid_t *ret_pid);
[[gnu::weak]] int sys_execve(const char *path, char *const argv[], char *const envp[]);

[[gnu::weak]] pid_t sys_getpid();
pid_t sys_getpid();
[[gnu::weak]] int sys_kill(int, int);

#define ENOSYS_BODY { return ENOSYS; }

struct AnsiSysdeps {
int prepare_stack(void **stack, void *entry, void *user_arg, void* tcb, size_t *stack_size, size_t *guard_size, void **stack_base) ENOSYS_BODY;
int clone(void *tcb, pid_t *pid_out, void *stack) ENOSYS_BODY;
int flock(int fd, int options) ENOSYS_BODY;
int open_dir(const char *path, int *handle) ENOSYS_BODY;
int read_entries(int handle, void *buffer, size_t max_size, size_t *bytes_read) ENOSYS_BODY;
int pread(int fd, void *buf, size_t n, off_t off, ssize_t *bytes_read) ENOSYS_BODY;
int clock_set(int clock, time_t secs, long nanos) ENOSYS_BODY;
int clock_getres(int clock, time_t *secs, long *nanos) ENOSYS_BODY;
int sleep(time_t *secs, long *nanos) ENOSYS_BODY;
int isatty(int fd) ENOSYS_BODY;
int rmdir(const char *path) ENOSYS_BODY;
int unlinkat(int dirfd, const char *path, int flags) ENOSYS_BODY;
int rename(const char *path, const char *new_path) ENOSYS_BODY;
int renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_path) ENOSYS_BODY;
int sigprocmask(int how, const sigset_t *__restrict set, sigset_t *__restrict retrieve) ENOSYS_BODY;
int sigaction(int, const struct sigaction *__restrict, struct sigaction *__restrict) ENOSYS_BODY;

int fork(pid_t *child) ENOSYS_BODY;
int waitpid(pid_t pid, int *status, int flags, struct rusage *ru, pid_t *ret_pid) ENOSYS_BODY;
int execve(const char *path, char *const argv[], char *const envp[]) ENOSYS_BODY;

int kill(int, int) ENOSYS_BODY;
};

} //namespace mlibc

#endif // MLIBC_ANSI_SYSDEPS
3 changes: 3 additions & 0 deletions options/internal/generic/global-config.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include <stdlib.h>
#include <string.h>
#include <mlibc/global-config.hpp>
#include <mlibc/sysdeps.hpp>

constinit SysdepsImpl<mlibc::Sysdeps> sysdeps;

namespace mlibc {

Expand Down
169 changes: 169 additions & 0 deletions options/internal/include/mlibc/sysdeps-interface.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#pragma once

#include <concepts>

#include <abi-bits/mode_t.h>
#include <abi-bits/pid_t.h>
#include <bits/ansi/time_t.h>
#include <bits/ansi/timespec.h>
#include <bits/ensure.h>
#include <bits/off_t.h>
#include <bits/size_t.h>
#include <bits/ssize_t.h>
#include <bits/sigset_t.h>

#include <mlibc/ansi-sysdeps.hpp>

namespace mlibc {

template <typename T>
concept RequiredSysdeps = requires(
T t,
int v_int,
size_t v_size,
ssize_t v_ssize,
off_t v_off,
mode_t v_mode,
void *p_void,
const char *p_char,
int *p_int,
long *p_long,
ssize_t *p_ssize,
off_t *p_off,
time_t *p_time,
struct timespec *p_timespec
) {
// [[noreturn]] void sys_exit(int status);
{ t.exit(v_int) } -> std::same_as<void>;
// [[noreturn]] void sys_thread_exit();
{ t.thread_exit() } -> std::same_as<void>;

// int sys_futex_wait(int *pointer, int expected, const struct timespec *time);
{ t.futex_wait(p_int, v_int, p_timespec) } -> std::same_as<int>;
// int sys_futex_wake(int *pointer);
{ t.futex_wake(p_int) } -> std::same_as<int>;

// int sys_open(const char *pathname, int flags, mode_t mode, int *fd);
{ t.open(p_char, v_int, v_mode, p_int) } -> std::same_as<int>;
// int sys_write(int fd, const void *buf, size_t count, ssize_t *bytes_written);
{ t.write(v_int, p_void, v_size, p_ssize) } -> std::same_as<int>;

// int sys_read(int fd, void *buf, size_t count, ssize_t *bytes_read);
{ t.read(v_int, p_void, v_size, p_ssize) } -> std::same_as<int>;

// int sys_seek(int fd, off_t offset, int whence, off_t *new_offset);
{ t.seek(v_int, v_off, v_int, p_off) } -> std::same_as<int>;

// int sys_close(int fd);
{ t.close(v_int) } -> std::same_as<int>;

// int sys_clock_get(int clock, time_t *secs, long *nanos);
{ t.clock_get(v_int, p_time, p_long) } -> std::same_as<int>;

// pid_t sys_getpid();
{ t.getpid() } -> std::same_as<pid_t>;
};

struct AnsiCompatSysdeps : public AnsiSysdeps {
int prepare_stack(void **stack, void *entry, void *user_arg, void* tcb, size_t *stack_size, size_t *guard_size, void **stack_base) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_prepare_stack, -1);
return sysdep(stack, entry, user_arg, tcb, stack_size, guard_size, stack_base);
}

int clone(void *tcb, pid_t *pid_out, void *stack) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_clone, -1);
return sysdep(tcb, pid_out, stack);
}

int flock(int fd, int options) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_flock, -1);
return sysdep(fd, options);
}

int open_dir(const char *path, int *handle) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_open_dir, -1);
return sysdep(path, handle);
}

int read_entries(int handle, void *buffer, size_t max_size, size_t *bytes_read) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_read_entries, -1);
return sysdep(handle, buffer, max_size, bytes_read);
}

int pread(int fd, void *buf, size_t n, off_t off, ssize_t *bytes_read) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pread, -1);
return sysdep(fd, buf, n, off, bytes_read);
}

int clock_set(int clock, time_t secs, long nanos) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_clock_set, -1);
return sysdep(clock, secs, nanos);
}

int clock_getres(int clock, time_t *secs, long *nanos) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_clock_getres, -1);
return sysdep(clock, secs, nanos);
}

int sleep(time_t *secs, long *nanos) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sleep, -1);
return sysdep(secs, nanos);
}

int isatty(int fd) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_isatty, -1);
return sysdep(fd);
}

int rmdir(const char *path) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_rmdir, -1);
return sysdep(path);
}

int unlinkat(int dirfd, const char *path, int flags) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_unlinkat, -1);
return sysdep(dirfd, path, flags);
}

int rename(const char *path, const char *new_path) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_rename, -1);
return sysdep(path, new_path);
}

int renameat(int olddirfd, const char *old_path, int newdirfd, const char *new_path) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_renameat, -1);
return sysdep(olddirfd, old_path, newdirfd, new_path);
}

int sigprocmask(int how, const sigset_t *__restrict set, sigset_t *__restrict retrieve) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigprocmask, -1);
return sysdep(how, set, retrieve);
}

int sigaction(int sig, const struct sigaction *__restrict sa, struct sigaction *__restrict sa_old) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sigaction, -1);
return sysdep(sig, sa, sa_old);
}

int fork(pid_t *child) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fork, -1);
return sysdep(child);
}

int waitpid(pid_t pid, int *status, int flags, struct rusage *ru, pid_t *ret_pid) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_waitpid, -1);
return sysdep(pid, status, flags, ru, ret_pid);
}

int execve(const char *path, char *const argv[], char *const envp[]) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_execve, -1);
return sysdep(path, argv, envp);
}

int kill(int pid, int num) {
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_kill, -1);
return sysdep(pid, num);
}
};

} // namespace mlibc
25 changes: 25 additions & 0 deletions options/internal/include/mlibc/sysdeps.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <mlibc/sysdeps-interface.hpp>
#include <mlibc/os-sysdeps.hpp>

template<mlibc::RequiredSysdeps Backend>
struct SysdepsImpl : public Backend {};

extern constinit SysdepsImpl<mlibc::Sysdeps> sysdeps;

template <typename T>
struct member_class_type;

template <typename C, typename R, typename... Args>
struct member_class_type<R (C::*)(Args...)> {
using type = C;
};

template <auto MemberFunc, typename Base>
constexpr bool hasSysdep() {
using MemberType = decltype(MemberFunc);
using OwnerClass = typename member_class_type<MemberType>::type;

return !std::is_same_v<OwnerClass, Base>;
}
Loading
Loading