aboutsummaryrefslogtreecommitdiff
path: root/lib/src/syscalls.c
blob: 074fced56508452a84ea79ea7c776c1dc2521884 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Copyright (c) 2021 Johannes Stoelp

#include <asm/unistd.h>  // __NR_*
#include <syscall.h>
#include <syscalls.h>

// Storage for `dynld_errno`.
int dynld_errno;

// Convert return value to errno/ret.
static long syscall_ret(unsigned long ret) {
    if (ret > (unsigned long)-4096ul) {
        dynld_errno = -ret;
        return -1;
    }
    return ret;
}

int open(const char* path, int flags) {
    long ret = syscall2(__NR_open, path, flags);
    return syscall_ret(ret);
}

int close(int fd) {
    long ret = syscall1(__NR_close, fd);
    return syscall_ret(ret);
}

int access(const char* path, int mode) {
    long ret = syscall2(__NR_access, path, mode);
    return syscall_ret(ret);
}

ssize_t write(int fd, const void* buf, size_t count) {
    long ret = syscall3(__NR_write, fd, buf, count);
    return syscall_ret(ret);
}

ssize_t read(int fd, void* buf, size_t count) {
    long ret = syscall3(__NR_read, fd, buf, count);
    return syscall_ret(ret);
}

ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
    long ret = syscall4(__NR_read, fd, buf, count, offset);
    return syscall_ret(ret);
}

void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) {
    long ret = syscall6(__NR_mmap, addr, length, prot, flags, fd, offset);
    return (void*)syscall_ret(ret);
}

int munmap(void* addr, size_t length) {
    long ret = syscall2(__NR_munmap, addr, length);
    return syscall_ret(ret);
}

void _exit(int status) {
    syscall1(__NR_exit, status);
    __builtin_unreachable();
}