major refactorings

Signed-off-by: kaguya3311 <kaguya3311@national.shitposting.agency>
This commit is contained in:
kaguya
2026-05-18 04:02:59 -04:00
parent f7aa6f913a
commit b28a6bcf29
211 changed files with 17699 additions and 8107 deletions
+22 -139
View File
@@ -1,151 +1,34 @@
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/wait.h>
#include <stdio.h>
#define STDIN 0
#define STDOUT 1
int main() {
printf("\nforking!");
pid_t pid = fork();
static void print(const char* s)
{
write(STDOUT, s, strlen(s));
}
static void touch(const char* path)
{
int fd = open(path, O_CREAT | O_WRONLY, 0644);
if (fd < 0) {
print("touch: cannot create file\n");
return;
if (pid < 0) {
perror("fork failed");
return 1;
}
close(fd);
}
if (pid == 0) {
// Child process
printf("child processed!");
char *argv[] = {"/bin/pwd", NULL};
char *envp[] = {NULL};
static void ls(const char* path)
{
struct dirent* entry;
execve("/bin/pwd", argv, envp);
DIR* dir = opendir(path ? path : ".");
if (!dir) {
print("ls: cannot open directory\n");
return;
// If execve returns, it failed
perror("execve failed");
return 1;
} else {
// Parent process
waitpid(pid, NULL, 0);
printf("Child process finished\n");
}
while ((entry = readdir(dir)) != NULL)
{
// skip . and ..
if (entry->d_name[0] == '.' &&
(entry->d_name[1] == '\0' ||
(entry->d_name[1] == '.' && entry->d_name[2] == '\0')))
continue;
print(entry->d_name);
print("\n");
}
closedir(dir);
}
static void readline(char* buf, size_t max)
{
size_t i = 0;
while (i < max - 1)
{
char c;
ssize_t n = read(STDIN, &c, 1);
if (n <= 0)
continue;
if (c == '\n')
break;
if (c == '\b') {
if (i > 0) i--;
continue;
}
buf[i++] = c;
}
buf[i] = '\0';
}
static void cat(const char* path)
{
char buf[256];
int fd = open(path, O_RDONLY);
if (fd < 0) {
print("cat: cannot open file\n");
return;
}
ssize_t n = read(fd, buf, sizeof(buf));
close(fd);
if (n > 0)
write(STDOUT, buf, (size_t)n);
}
int main(void)
{
const char* path = "/qwerty.txt";
const char* msg = "Suki Suki Daisuki Kekkon Shiyo, my honey!";
char buf[128];
int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
write(fd, msg, strlen(msg));
close(fd);
fd = open(path, O_RDONLY);
ssize_t n = read(fd, buf, sizeof(buf));
close(fd);
if (n > 0)
write(STDOUT, buf, (size_t)n);
char line[128];
while (1)
{
print("> ");
readline(line, sizeof(line));
if (strcmp(line, "exit") == 0)
break;
if (line[0] == 'c' && line[1] == 'a' && line[2] == 't' && line[3] == ' ')
{
cat(&line[4]);
continue;
}
if (line[0] == 't' && line[1] == 'o' && line[2] == 'u' && line[3] == 'c' && line[4] == 'h' && line[5] == ' ')
{
touch(&line[6]);
continue;
}
if (line[0] == 'l' && line[1] == 's')
{
if (line[2] == ' ')
ls(&line[3]);
else
ls(NULL);
continue;
}
if (line[0] != '\0')
print("Unknown command\n");
}
printf("comp");
return 0;
}
@@ -65,7 +65,7 @@ int chown(const char *path, uid_t uid, gid_t gid) {
return 0;
}
ssize_t confstr(int name, char *buf, size_t len) {
size_t confstr(int name, char *buf, size_t len) {
const char *str = "";
if (name == _CS_PATH) {
str = "/bin:/usr/bin";
@@ -264,7 +264,7 @@ unsigned int alarm(unsigned int __seconds);
int chdir(const char *__path);
int chown(const char *__path, uid_t __uid, gid_t __gid);
int close(int __fd);
ssize_t confstr(int __name, char *__buf, size_t __size);
size_t confstr(int __name, char *__buf, size_t __size);
char *ctermid(char *__s);
int dup(int __fd);
int dup2(int __src_fd, int __dest_fd);
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -euo pipefail
SYSROOT_DIR="/home/kaguya/KirkOS/ext2_root/"
rm -rf headers-build build
rm -f "$SYSROOT_DIR/usr/lib/libc.a" "$SYSROOT_DIR/usr/lib/libm.a" "$SYSROOT_DIR/usr/lib/libdl.a"
# 1. Headers
meson setup \
--cross-file=x86_64-kirkos-gcc.txt \
--prefix=/usr \
-Dheaders_only=true \
-Dlinux_kernel_headers=/home/kaguya/KirkOS/linux-headers/include \
headers-build --reconfigure
DESTDIR="$SYSROOT_DIR" ninja -C headers-build install
# 2. Static libraries
meson setup \
--cross-file=/home/kaguya/KirkOS/user/include/mlibc/x86_64-kirkos-gcc.txt \
--prefix=/usr \
-Ddefault_library=static \
-Dno_headers=true \
-Dlinux_kernel_headers=/home/kaguya/KirkOS/linux-headers/include \
build --reconfigure
DESTDIR="$SYSROOT_DIR" ninja -C build install
@@ -6,5 +6,6 @@
#define HOST_NAME_MAX 64
#define NAME_MAX 255
#define OPEN_MAX 256
#define _POSIX_PATH_MAX 256
#endif /*_ABIBITS_LIMITS_H */
@@ -21,7 +21,9 @@ struct KirkSysdepTags
public Open,
public VmMap,
public VmUnmap,
public ClockGet
public ClockGet,
public Sigaction,
public GetPid
{ };
template<typename Tag>
@@ -1,29 +1,50 @@
#pragma once
#define SYS_READ 0
#define SYS_WRITE 1
#define SYS_OPEN 2
#define SYS_CLOSE 3
#define SYS_MMAP 9
#define SYS_MUNMAP 11
#define SYS_BRK 12
#define SYS_SIGACTION 13 /* rt_sigaction on Linux */
#define SYS_SIGPROCMASK 14 /* rt_sigprocmask on Linux */
#define SYS_SCHED_YIELD 24
#define SYS_GETPID 39
#define SYS_NICE 34
#define SYS_FORK 57
#define SYS_EXECVE 59
#define SYS_EXIT 60
#define SYS_KILL 62
#define SYS_GETPPID 110
#define SYS_SCHED_GETSCHEDULER 138
#define SYS_SCHED_SETSCHEDULER 139
#define SYS_FUTEX 202
#define SYS_EXIT_GROUP 231
#define SYS_TCB_SET 300
#define SYS_GETRANDOM 318
#define SYS_OPEN_DIR 319
#define SYS_READ_ENTRIES 320
#define SYS_read 0
#define SYS_write 1
#define SYS_open 2
#define SYS_close 3
#define SYS_seek 8
#define SYS_mmap 9
#define SYS_mprotect 10
#define SYS_munmap 11
#define SYS_ioctl 16
#define SYS_nanosleep 35
#define SYS_getpid 39
#define SYS_fork 57
#define SYS_execve 59
#define SYS_exit 60
#define SYS_kill 62
#define SYS_fcntl 72
#define SYS_getcwd 79
#define SYS_chdir 80
#define SYS_rmdir 84
#define SYS_readdir 89
#define SYS_puts 103
#define SYS_getppid 110
#define SYS_setsid 112
#define SYS_waitpid 114
#define SYS_prctl 157
#define SYS_futex 202
#define SYS_openat 257
#define SYS_mkdirat 258
#define SYS_fstatat 262
#define SYS_unlinkat 263
#define SYS_linkat 265
#define SYS_readlinkat 267
#define SYS_fchmodat 268
#define SYS_dup3 292
#define SYS_pipe 293
#define SYS_getclock 314
#define SYS_ppoll 271
#define SYS_socket 41
#define SYS_connect 42
#define SYS_accept 43
#define SYS_recvmsg 47
#define SYS_bind 49
#define SYS_listen 50
#define SYS_getpeername 52
#define SYS_socketpair 83
#define SYS_threadnew 56
#define SYS_threadexit 61
@@ -86,7 +86,7 @@ if not headers_only
endif
rtld_sources += files(
rtld_dso_sources += files(
'sysdeps.cpp',
'syscall.cpp',
'dso.c',
+621 -121
View File
@@ -1,17 +1,19 @@
#include "mlibc/tcb.hpp"
#include <abi-bits/errno.h>
#include <abi-bits/fcntl.h>
#include <asm/ioctls.h>
#include <bits/ensure.h>
#include <bits/syscall.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <frg/hash.hpp>
#include <frg/hash_map.hpp>
#include <limits.h>
#include <mlibc/all-sysdeps.hpp>
#include <string.h>
#include <mlibc/sysdeps.hpp>
#include <mlibc/allocator.hpp>
#include <mlibc/debug.hpp>
#include <bits/syscall.h>
#include <stdlib.h>
#include "syscall.h"
#define SYS_EXIT 60
#define SYS_READ 0
#define SYS_WRITE 1
#define STUB() \
({ \
__ensure(!"STUB function was called"); \
@@ -20,140 +22,638 @@
namespace mlibc {
void sys_libc_log(const char *msg) {
ssize_t dummy;
sys_write(1, msg, strlen(msg), &dummy);
int fcntl_helper(int fd, int request, int *result, ...) {
va_list args;
va_start(args, result);
if (!mlibc::sys_fcntl) {
return ENOSYS;
}
int ret = mlibc::sys_fcntl(fd, request, args, result);
va_end(args);
return ret;
}
void sys_libc_panic() {
sys_libc_log("!!! mlibc panic !!!\n");
sys_exit(1);
__builtin_trap();
}
int sys_isatty(int fd) {
return 0; // everything is a tty for now
}
int sys_write(int fd, const void *buf, size_t size, ssize_t *ret) {
long r = syscall(SYS_WRITE, fd, (uintptr_t)buf, size);
if (ret) *ret = r;
return r >= 0 ? 0 : -r;
}
int sys_read(int fd, void *buf, size_t size, ssize_t *ret) {
long r = syscall(SYS_READ, fd, (uintptr_t)buf, size);
if (ret) *ret = r;
return r >= 0 ? 0 : -r;
void sys_libc_log(const char *message) {
syscall(SYS_puts, message);
syscall(SYS_puts, "\n");
}
void sys_exit(int status) {
syscall(SYS_EXIT, status);
__builtin_unreachable();
syscall(SYS_exit, status);
__builtin_unreachable();
}
int sys_close(int fd) {
long r = syscall(SYS_CLOSE, fd);
return r >= 0 ? 0 : -r;
}
int sys_getrandom(void *buffer, size_t length, int flags) {
long r = syscall(SYS_GETRANDOM, buffer, length, flags);
return r;
}
// ─────────────────────────────────────────────────────────────────────────────
// Memory
// ─────────────────────────────────────────────────────────────────────────────
int sys_anon_allocate(size_t size, void **pointer) {
long r = syscall(SYS_MMAP, 0, size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
*pointer = (void*)r;
return (r == (long)MAP_FAILED) ? ENOMEM : 0;
}
int sys_anon_free(void *ptr, size_t size) {
if (!ptr || size == 0) return 0;
long r = syscall(SYS_MUNMAP, (uintptr_t)ptr, size);
return r == 0 ? 0 : ENOMEM;
}
int sys_vm_map(void *hint, size_t size, int prot, int flags,
int fd, off_t offset, void **out) {
long r = syscall(SYS_MMAP,
(uintptr_t)hint,
size,
prot,
flags,
fd,
offset);
if (r < 0)
return -r;
*out = (void *)r;
return 0;
}
int sys_vm_unmap(void *addr, size_t size) {
long r = syscall(SYS_MUNMAP, (uintptr_t)addr, size);
return (r == 0) ? 0 : -r;
}
// ─────────────────────────────────────────────────────────────────────────────
// Others
// ─────────────────────────────────────────────────────────────────────────────
int sys_seek(int, off_t, int, off_t *) {
return ESPIPE; // no real files yet
void sys_libc_panic() {
sys_libc_log("\nmlibc: panic!\n");
sys_exit(1);
__builtin_unreachable();
}
int sys_tcb_set(void *pointer) {
sys_libc_log("[sysdeps] sys_tcb_set called");
long ret = syscall(SYS_TCB_SET, (uintptr_t)pointer);
if (ret < 0)
return -ret;
sys_libc_log("[sysdeps] TCB set via syscall.\n");
return 0;
// ARCH_SET_FS
syscall(SYS_prctl, 0x1002, pointer);
return 0;
}
int sys_open(const char *path, int flags, unsigned int mode, int *fd) {
long r = syscall(SYS_OPEN, (uintptr_t)path, (long)flags, (long)mode);
if (r < 0) return -r;
*fd = (int)r;
return 0;
int sys_futex_wait(int *pointer, int expected, const struct timespec *time) {
(void)time;
return -(syscall(SYS_futex, pointer, 0, expected));
}
// Futexes
int sys_futex_wait(int *ptr, int expected, const timespec *time) {
long r = syscall(SYS_FUTEX, ptr, 0, expected, time);
return (r < 0) ? -r : 0;
int sys_futex_wake(int *pointer) { return -(syscall(SYS_futex, pointer, 1, 0)); }
int sys_ioctl(int fd, unsigned long request, void *arg, int *result) {
int ret = syscall(SYS_ioctl, fd, request, arg);
if (ret < 0) {
return -ret;
}
*result = ret;
return 0;
}
int sys_futex_wake(int *ptr) {
long r = syscall(SYS_FUTEX, ptr, 1, 1, 0);
return (r < 0) ? -r : 0;
int sys_isatty(int fd) {
struct winsize ws;
int ret;
if (!sys_ioctl(fd, TIOCGWINSZ, &ws, &ret))
return 0;
return ENOTTY;
}
int sys_getcwd(char *buffer, size_t size) {
syscall(SYS_getcwd, buffer, size);
return 0;
}
int sys_openat(int dirfd, const char *path, int flags, mode_t mode, int *fd) {
int ret = syscall(SYS_openat, dirfd, path, flags, mode);
if (ret < 0) {
*fd = -1;
return -ret;
}
*fd = (int)ret;
return 0;
}
int sys_open(const char *path, int flags, mode_t mode, int *fd) {
return sys_openat(AT_FDCWD, path, flags, mode, fd);
}
#ifndef MLIBC_BUILDING_RTLD
void sys_thread_exit() {
syscall(SYS_threadexit);
__builtin_unreachable();
}
extern "C" void __mlibc_thread_entry();
int sys_clone(void *tcb, pid_t *pid_out, void *stack) {
(void)tcb;
int ret = syscall(SYS_threadnew, (uintptr_t)__mlibc_thread_entry, (uintptr_t)stack);
if (ret < 0) {
return -ret;
}
*pid_out = ret;
return 0;
}
extern "C" void __mlibc_thread_entry() {
/* Minimal stub so linking succeeds.
If you need real pthread support later, replace this with the
proper mlibc thread startup logic (pop start_routine + arg from stack,
call it, then sys_thread_exit). */
mlibc::sys_libc_panic();
__builtin_unreachable();
}
int sys_tcgetattr(int fd, struct termios *attr) {
int ret;
if (int r = sys_ioctl(fd, TCGETS, attr, &ret) != 0) {
return r;
}
return ret;
}
int sys_tcsetattr(int fd, int optional_action, const struct termios *attr) {
int ret;
switch (optional_action) {
case TCSANOW:
optional_action = TCSETS;
break;
case TCSADRAIN:
optional_action = TCSETSW;
break;
case TCSAFLUSH:
optional_action = TCSETSF;
break;
default:
__ensure(!"Unsupported tcsetattr");
}
if (int r = sys_ioctl(fd, optional_action, (void *)attr, &ret) != 0) {
return r;
}
return ret;
}
int sys_open_dir(const char *path, int *handle) {
long r = syscall(SYS_OPEN_DIR, (uintptr_t)path, (uintptr_t)handle);
return (r < 0) ? -r : 0;
return sys_openat(AT_FDCWD, path, O_DIRECTORY, 0, handle);
}
int sys_read_entries(int handle, void *buf, size_t bufsize, size_t *out) {
long r = syscall(SYS_READ_ENTRIES, handle, (uintptr_t)buf, bufsize, (uintptr_t)out);
if (r < 0) return -r;
struct ReadDirState {
size_t offset;
size_t capacity;
void *buffer;
};
// Kernel already wrote the byte count into *out via the pointer.
// Do NOT overwrite it with r (which is always 0 on success).
return 0;
static frg::hash_map<int, ReadDirState *, frg::hash<int>, MemoryAllocator> open_dirs{
frg::hash<int>{}, getAllocator()
};
static ReadDirState *get_dir_state(int fdnum) {
ReadDirState *result;
if (auto value = open_dirs.get(fdnum)) {
result = *value;
} else {
result = (ReadDirState *)malloc(sizeof(ReadDirState));
result->offset = 0;
result->capacity = 1024;
result->buffer = malloc(result->capacity);
open_dirs.insert(fdnum, result);
}
return result;
}
int sys_clock_get(int, time_t *, long *) { return ENOSYS; }
int sys_read_entries(int fdnum, void *buffer, size_t max_size, size_t *bytes_read) {
ReadDirState *state = get_dir_state(fdnum);
retry:
uint64_t ret = syscall(SYS_readdir, fdnum, state->buffer, &state->capacity);
int ret_but_int = (int)ret;
if (ret_but_int < 0) {
if (-ret_but_int == ENOBUFS) {
state->buffer = realloc(state->buffer, state->capacity);
goto retry;
} else {
return -ret_but_int;
}
}
size_t offset = 0;
while (offset < max_size) {
struct dirent *ent = (struct dirent *)((char *)state->buffer + state->offset);
if (ent->d_reclen == 0) {
break;
}
if (offset + ent->d_reclen >= max_size) {
break;
}
memcpy((char *)buffer + offset, ent, ent->d_reclen);
offset += ent->d_reclen;
state->offset += ent->d_reclen;
}
*bytes_read = offset;
return ret;
}
#endif
int sys_close(int fd) {
syscall(SYS_close, fd);
#ifndef MLIBC_BUILDING_RTLD
open_dirs.remove(fd);
#endif
return 0;
}
int sys_seek(int fd, off_t offset, int whence, off_t *new_offset) {
uint64_t ret = syscall(SYS_seek, fd, offset, whence);
int ret_but_int = (int)ret;
if (ret_but_int < 0) {
*new_offset = -1;
return -ret_but_int;
}
*new_offset = (off_t)ret;
return 0;
}
int sys_read(int fd, void *buf, size_t count, ssize_t *bytes_read) {
*bytes_read = (ssize_t)syscall(SYS_read, fd, buf, count);
int ret = *bytes_read;
if (ret < 0) {
*bytes_read = -1;
return -ret;
}
return 0;
}
int sys_write(int fd, const void *buf, size_t count, ssize_t *bytes_written) {
*bytes_written = (ssize_t)syscall(SYS_write, fd, buf, count);
int ret = *bytes_written;
if (ret < 0) {
*bytes_written = -1;
return -ret;
}
return 0;
}
int sys_readlink(const char *path, void *data, size_t max_size, ssize_t *length) {
*length = (ssize_t)syscall(SYS_readlinkat, AT_FDCWD, path, data, max_size);
int ret = *length;
if (ret < 0) {
*length = -1;
return -ret;
}
return 0;
}
int sys_linkat(int olddirfd, const char *old_path, int newdirfd, const char *new_path, int flags) {
int ret = syscall(SYS_linkat, olddirfd, old_path, newdirfd, new_path, flags);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_link(const char *old_path, const char *new_path) {
return sys_linkat(AT_FDCWD, old_path, AT_FDCWD, new_path, 0);
}
int sys_unlinkat(int fd, const char *path, int flags) {
int ret = syscall(SYS_unlinkat, fd, path, flags);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_fchmodat(int fd, const char *pathname, mode_t mode, int flags) {
int ret = syscall(SYS_fchmodat, fd, pathname, mode, flags);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_fchmod(int fd, mode_t mode) { return sys_fchmodat(fd, "", mode, AT_EMPTY_PATH); }
int sys_chmod(const char *pathname, mode_t mode) {
int ret = sys_fchmodat(AT_FDCWD, pathname, mode, 0);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_vm_map(void *hint, size_t size, int prot, int flags, int fd, off_t offset, void **window) {
uint64_t ret = syscall(SYS_mmap, hint, size, prot, flags, fd, offset);
int64_t ret_but_int = (int64_t)ret;
if ((ret_but_int < 0) && (ret_but_int > -4096)) {
*window = ((void *)-1);
return -ret_but_int;
}
*window = (void *)ret;
return 0;
}
int sys_vm_protect(void *pointer, size_t size, int prot) {
return -(syscall(SYS_mprotect, pointer, size, prot));
}
int sys_vm_unmap(void *pointer, size_t size) { return -(syscall(SYS_munmap, pointer, size)); }
int sys_anon_allocate(size_t size, void **pointer) {
return sys_vm_map(NULL, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1, 0, pointer);
}
int sys_anon_free(void *pointer, size_t size) { return sys_vm_unmap(pointer, size); }
#ifndef MLIBC_BUILDING_RTLD
pid_t sys_getpid() { return (pid_t)syscall(SYS_getpid); }
pid_t sys_getppid() { return (pid_t)syscall(SYS_getppid); }
uid_t sys_getuid() { return 0; }
uid_t sys_geteuid() { return 0; }
gid_t sys_getgid() { return 0; }
int sys_setgid(gid_t) { return 0; }
int sys_getpgid(pid_t, pid_t *) { return 0; }
gid_t sys_getegid() { return 0; }
int sys_setpgid(pid_t, pid_t) { return 0; }
int sys_kill(pid_t p, int sig) {
(void)sig;
syscall(SYS_kill, p);
return 0;
}
int sys_clock_get(int clock, time_t *secs, long *nanos) {
struct timespec buf;
syscall(SYS_getclock, clock, &buf);
*secs = buf.tv_sec;
*nanos = buf.tv_nsec;
return 0;
}
int sys_sleep(time_t *secs, long *nanos) {
struct timespec req = {.tv_sec = *secs, .tv_nsec = *nanos};
struct timespec rem = {0, 0};
int ret = syscall(0x23, &req, &rem);
if (ret < 0) {
return -ret;
}
*secs = rem.tv_sec;
*nanos = rem.tv_nsec;
return 0;
}
int sys_stat(fsfd_target fsfdt, int fd, const char *path, int flags, struct stat *statbuf) {
int ret = 0;
switch (fsfdt) {
case fsfd_target::fd:
ret = syscall(SYS_fstatat, fd, "", statbuf, flags | AT_EMPTY_PATH);
break;
case fsfd_target::path:
ret = syscall(SYS_fstatat, AT_FDCWD, path, statbuf, flags);
break;
case fsfd_target::fd_path:
ret = syscall(SYS_fstatat, fd, path, statbuf, flags);
break;
default:
__ensure(!"sys_stat: Invalid fsfdt");
__builtin_unreachable();
}
return -ret;
}
int sys_faccessat(int dirfd, const char *pathname, int mode, int flags) {
(void)flags;
struct stat buf;
if (int r = sys_stat(fsfd_target::fd_path, dirfd, pathname, mode & AT_SYMLINK_FOLLOW, &buf)) {
return r;
}
return 0;
}
int sys_access(const char *path, int mode) { return sys_faccessat(AT_FDCWD, path, mode, 0); }
int sys_pipe(int *fds, int flags) {
int ret = syscall(SYS_pipe, fds, flags);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_chdir(const char *path) {
int ret = syscall(SYS_chdir, path);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_mkdirat(int dirfd, const char *path, mode_t mode) {
int ret = syscall(SYS_mkdirat, dirfd, path, mode);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_mkdir(const char *path, mode_t mode) { return sys_mkdirat(AT_FDCWD, path, mode); }
int sys_inotify_create(int, int *) {
mlibc::infoLogger() << "mlibc: sys_inotify_create() is unimplemented" << frg::endlog;
return ENOSYS;
}
int sys_fork(pid_t *child) {
*child = (pid_t)syscall(SYS_fork);
return 0;
}
int sys_execve(const char *path, char *const argv[], char *const envp[]) {
int ret = syscall(SYS_execve, path, argv, envp);
ret = ret < 0 ? -ret : 0;
return ret;
}
int sys_fcntl(int fd, int request, va_list args, int *result) {
*result = (int)syscall(SYS_fcntl, fd, request, va_arg(args, uint64_t));
int ret = *result;
if (ret < 0) {
*result = ret;
return -ret;
}
return 0;
}
int sys_dup(int fd, int flags, int *newfd) {
(void)flags;
*newfd = (int)syscall(SYS_fcntl, fd, F_DUPFD, 0);
int ret = *newfd;
if (ret < 0) {
*newfd = -1;
return -ret;
}
return 0;
}
int sys_dup2(int fd, int flags, int newfd) {
int ret = syscall(SYS_dup3, fd, newfd, flags);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_rmdir(const char *path) {
int ret = syscall(SYS_rmdir, path);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_setsid(pid_t *sid) {
(void)sid;
int ret = syscall(SYS_setsid);
ret = ret < 0 ? -ret : ret;
return ret;
}
int sys_sigprocmask(int, const sigset_t *__restrict, sigset_t *__restrict) {
mlibc::infoLogger() << "mlibc: sys_sigprocmask() is a stub\n" << frg::endlog;
return 0;
}
int sys_sigaction(int, const struct sigaction *, struct sigaction *) {
mlibc::infoLogger() << "mlibc: sys_sigaction() is a stub\n" << frg::endlog;
return 0;
}
int sys_waitpid(pid_t pid, int *status, int flags, struct rusage *ru, pid_t *ret_pid) {
if (ru) {
mlibc::infoLogger() << "mlibc: struct rusage in sys_waitpid is unsupported\n"
<< frg::endlog;
return ENOSYS;
}
int ret = syscall(SYS_waitpid, pid, status, flags);
if (ret < 0) {
*ret_pid = -1;
return -ret;
}
*ret_pid = ret;
return 0;
}
int sys_getgroups(size_t, const gid_t *, int *) {
mlibc::infoLogger() << "mlibc: sys_getgroups() is unimplemented" << frg::endlog;
return ENOSYS;
}
int sys_gethostname(char *buffer, size_t bufsize) {
struct utsname utsname;
if (int err = sys_uname(&utsname)) {
return err;
}
if (strlen(utsname.nodename) >= bufsize) {
return ENAMETOOLONG;
}
strncpy(buffer, utsname.nodename, bufsize);
return 0;
}
int sys_getitimer(int, struct itimerval *) {
mlibc::infoLogger() << "mlibc: sys_getitimer() is unimplemented" << frg::endlog;
return ENOSYS;
}
int sys_setitimer(int, const struct itimerval *, struct itimerval *) {
mlibc::infoLogger() << "mlibc: sys_setitimer() is unimplemented" << frg::endlog;
return ENOSYS;
}
int sys_umask(mode_t mode, mode_t *old) {
int ret = syscall(0x5f, mode);
if (ret < 0) {
return -ret;
}
*old = ret;
return 0;
}
int sys_uname(struct utsname *buf) { return syscall(0x3f, buf); }
int sys_fsync(int) {
mlibc::infoLogger() << "sys_fsync is a stub" << frg::endlog;
return 0;
}
int sys_ppoll(
struct pollfd *fds,
int nfds,
const struct timespec *timeout,
const sigset_t *sigmask,
int *num_events
) {
int ret = syscall(SYS_ppoll, fds, nfds, timeout, sigmask);
if (ret < 0)
return -ret;
*num_events = ret;
return 0;
}
int sys_poll(struct pollfd *fds, nfds_t count, int timeout, int *num_events) {
struct timespec ts;
ts.tv_sec = timeout / 1000;
ts.tv_nsec = (timeout % 1000) * 1000000;
return sys_ppoll(fds, count, timeout < 0 ? NULL : &ts, NULL, num_events);
}
int sys_pselect(
int nfds,
fd_set *read_set,
fd_set *write_set,
fd_set *except_set,
const struct timespec *timeout,
const sigset_t *sigmask,
int *num_events
) {
struct pollfd *fds = (struct pollfd *)calloc(nfds, sizeof(struct pollfd));
if (fds == NULL) {
return ENOMEM;
}
for (int i = 0; i < nfds; i++) {
struct pollfd *fd = &fds[i];
if (read_set && FD_ISSET(i, read_set)) {
fd->events |= POLLIN;
}
if (write_set && FD_ISSET(i, write_set)) {
fd->events |= POLLOUT;
}
if (except_set && FD_ISSET(i, except_set)) {
fd->events |= POLLPRI;
}
if (!fd->events) {
fd->fd = -1;
continue;
}
fd->fd = i;
}
int ret = sys_ppoll(fds, nfds, timeout, sigmask, num_events);
if (ret < 0) {
free(fds);
return -ret;
}
fd_set res_read_set, res_write_set, res_except_set;
FD_ZERO(&res_read_set);
FD_ZERO(&res_write_set);
FD_ZERO(&res_except_set);
for (int i = 0; i < nfds; i++) {
struct pollfd *fd = &fds[i];
if (read_set && FD_ISSET(i, read_set)
&& (fd->revents & (POLLIN | POLLERR | POLLHUP)) != 0) {
FD_SET(i, &res_read_set);
}
if (write_set && FD_ISSET(i, write_set)
&& (fd->revents & (POLLOUT | POLLERR | POLLHUP)) != 0) {
FD_SET(i, &res_write_set);
}
if (except_set && FD_ISSET(i, except_set) && (fd->revents & POLLPRI) != 0) {
FD_SET(i, &res_except_set);
}
}
free(fds);
if (read_set) {
*read_set = res_read_set;
}
if (write_set) {
*write_set = res_write_set;
}
if (except_set) {
*except_set = res_except_set;
}
return 0;
}
#endif
} // namespace mlibc
@@ -19,7 +19,7 @@ __sc_word_t __do_syscall6(long, __sc_word_t, __sc_word_t, __sc_word_t, __sc_word
__sc_word_t, __sc_word_t);
__sc_word_t __do_syscall7(long, __sc_word_t, __sc_word_t, __sc_word_t, __sc_word_t,
__sc_word_t, __sc_word_t, __sc_word_t);
long __do_syscall_ret(unsigned long);
long __do_syscall_ret(unsigned long ret);
#ifdef __cplusplus
extern "C++" {