diff options
author | nthnluu <nate1299@me.com> | 2024-01-28 21:20:27 -0500 |
---|---|---|
committer | nthnluu <nate1299@me.com> | 2024-01-28 21:20:27 -0500 |
commit | c63f340d90800895f007de64b7d2d14624263331 (patch) | |
tree | 2c0849fa597dd6da831c8707b6f2603403778d7b /user/lib/libc/syscall.c |
Created student weenix repository
Diffstat (limited to 'user/lib/libc/syscall.c')
-rw-r--r-- | user/lib/libc/syscall.c | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/user/lib/libc/syscall.c b/user/lib/libc/syscall.c new file mode 100644 index 0000000..3d921d1 --- /dev/null +++ b/user/lib/libc/syscall.c @@ -0,0 +1,391 @@ +#include "sys/types.h" + +#include "stdlib.h" +#include "string.h" +#include "unistd.h" + +#include "stdio.h" +#include "weenix/trap.h" + +#include "dirent.h" + +static void *__curbrk = NULL; +#define MAX_EXIT_HANDLERS 32 + +static void (*atexit_func[MAX_EXIT_HANDLERS])(); + +static int atexit_handlers = 0; + +void *sbrk(intptr_t incr) +{ + uintptr_t oldbrk; + + /* If we don't have a saved break, find it from the kernel */ + if (!__curbrk) + { + if (0 > (long)(__curbrk = (void *)trap(SYS_brk, (uintptr_t)NULL))) + { + return (void *)-1; + } + } + + oldbrk = (uintptr_t)__curbrk; + + /* Increment or decrement the saved break */ + + if (incr < 0) + { + if ((uintptr_t)-incr > oldbrk) + { + return (void *)-1; + } + else if (brk((void *)(oldbrk - (uintptr_t)-incr)) < 0) + { + return (void *)-1; + } + } + else if (incr > 0) + { + if (brk((void *)(oldbrk + (uintptr_t)incr)) < 0) + { + return (void *)-1; + } + } + return (void *)oldbrk; +} + +int brk(void *addr) +{ + if (NULL == addr) + { + return -1; + } + void *newbrk = (void *)trap(SYS_brk, (uintptr_t)addr); + if (newbrk == (void *)-1) + { + return -1; + } + __curbrk = newbrk; + return 0; +} + +pid_t fork(void) { return (pid_t)trap(SYS_fork, 0); } + +int atexit(void (*func)(void)) +{ + if (atexit_handlers < MAX_EXIT_HANDLERS) + { + atexit_func[atexit_handlers++] = func; + return 0; + } + + return 1; +} + +__attribute__((noreturn)) void exit(int status) +{ + while (atexit_handlers--) + { + atexit_func[atexit_handlers](); + } + + fflush(NULL); + trap(SYS_exit, (ssize_t)status); + __builtin_unreachable(); +} + +void _Exit(int status) +{ + trap(SYS_exit, (ssize_t)status); + __builtin_unreachable(); +} + +int sched_yield(void) { return (int)trap(SYS_sched_yield, NULL); } + +pid_t wait(int *status) +{ + waitpid_args_t args; + + args.wpa_pid = -1; + args.wpa_options = 0; + args.wpa_status = status; + + return (int)trap(SYS_waitpid, (uintptr_t)&args); +} + +pid_t waitpid(pid_t pid, int *status, int options) +{ + waitpid_args_t args; + + args.wpa_pid = pid; + args.wpa_status = status; + args.wpa_options = options; + + return (int)trap(SYS_waitpid, (uintptr_t)&args); +} + +void thr_exit(int status) { trap(SYS_thr_exit, (ssize_t)status); } + +pid_t getpid(void) { return (int)trap(SYS_getpid, 0); } + +int halt(void) { return (int)trap(SYS_halt, 0); } + +void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off) +{ + mmap_args_t args; + + args.mma_addr = addr; + args.mma_len = len; + args.mma_prot = prot; + args.mma_flags = flags; + args.mma_fd = fd; + args.mma_off = off; + + return (void *)trap(SYS_mmap, (uintptr_t)&args); +} + +int munmap(void *addr, size_t len) +{ + munmap_args_t args; + + args.addr = addr; + args.len = len; + + return (int)trap(SYS_munmap, (uintptr_t)&args); +} + +int debug(const char *str) +{ + argstr_t argstr; + argstr.as_len = strlen(str); + argstr.as_str = str; + return (int)trap(SYS_debug, (uintptr_t)&argstr); +} + +void sync(void) { trap(SYS_sync, NULL); } + +int open(const char *filename, int flags, int mode) +{ + open_args_t args; + + args.filename.as_len = strlen(filename); + args.filename.as_str = filename; + args.flags = flags; + args.mode = mode; + + return (int)trap(SYS_open, (uintptr_t)&args); +} + +off_t lseek(int fd, off_t offset, int whence) +{ + lseek_args_t args; + + args.fd = fd; + args.offset = offset; + args.whence = whence; + + return (int)trap(SYS_lseek, (uintptr_t)&args); +} + +ssize_t read(int fd, void *buf, size_t nbytes) +{ + read_args_t args; + + args.fd = fd; + args.buf = buf; + args.nbytes = nbytes; + + return trap(SYS_read, (uintptr_t)&args); +} + +ssize_t write(int fd, const void *buf, size_t nbytes) +{ + write_args_t args; + + args.fd = fd; + args.buf = (void *)buf; + args.nbytes = nbytes; + + return trap(SYS_write, (uintptr_t)&args); +} + +int close(int fd) { return (int)trap(SYS_close, (ssize_t)fd); } + +int dup(int fd) { return (int)trap(SYS_dup, (ssize_t)fd); } + +int dup2(int ofd, int nfd) +{ + dup2_args_t args; + + args.ofd = ofd; + args.nfd = nfd; + + return (int)trap(SYS_dup2, (uintptr_t)&args); +} + +int mkdir(const char *path, int mode) +{ + mkdir_args_t args; + + args.path.as_len = strlen(path); + args.path.as_str = path; + args.mode = mode; + + return (int)trap(SYS_mkdir, (uintptr_t)&args); +} + +int rmdir(const char *path) +{ + argstr_t args; + args.as_len = strlen(path); + args.as_str = path; + return (int)trap(SYS_rmdir, (uintptr_t)&args); +} + +int unlink(const char *path) +{ + argstr_t args; + args.as_len = strlen(path); + args.as_str = path; + return (int)trap(SYS_unlink, (uintptr_t)&args); +} + +int link(const char *from, const char *to) +{ + link_args_t args; + + args.from.as_len = strlen(from); + args.from.as_str = from; + args.to.as_len = strlen(to); + args.to.as_str = to; + + return (int)trap(SYS_link, (uintptr_t)&args); +} + +int rename(const char *oldpath, const char *newpath) +{ + rename_args_t args; + + args.oldpath.as_len = strlen(oldpath); + args.oldpath.as_str = oldpath; + args.newpath.as_len = strlen(newpath); + args.newpath.as_str = newpath; + + return (int)trap(SYS_rename, (uintptr_t)&args); +} + +int chdir(const char *path) +{ + argstr_t args; + args.as_len = strlen(path); + args.as_str = path; + return (int)trap(SYS_chdir, (uintptr_t)&args); +} + +size_t get_free_mem(void) { return (size_t)trap(SYS_get_free_mem, 0); } + +int execve(const char *filename, char *const argv[], char *const envp[]) +{ + execve_args_t args; + + size_t i; + + args.filename.as_len = strlen(filename); + args.filename.as_str = filename; + + /* Build argv vector */ + for (i = 0; argv[i] != NULL; i++) + ; + args.argv.av_len = i; + args.argv.av_vec = malloc((args.argv.av_len + 1) * sizeof(argstr_t)); + for (i = 0; argv[i] != NULL; i++) + { + args.argv.av_vec[i].as_len = strlen(argv[i]); + args.argv.av_vec[i].as_str = argv[i]; + } + args.argv.av_vec[i].as_len = 0; + args.argv.av_vec[i].as_str = NULL; + + /* Build envp vector */ + for (i = 0; envp[i] != NULL; i++) + ; + args.envp.av_len = i; + args.envp.av_vec = malloc((args.envp.av_len + 1) * sizeof(argstr_t)); + for (i = 0; envp[i] != NULL; i++) + { + args.envp.av_vec[i].as_len = strlen(envp[i]); + args.envp.av_vec[i].as_str = envp[i]; + } + args.envp.av_vec[i].as_len = 0; + args.envp.av_vec[i].as_str = NULL; + + /* Note that we don't need to worry about freeing since we are going to exec + * (so all our memory will be cleaned up) */ + + return (int)trap(SYS_execve, (uintptr_t)&args); +} + +void thr_set_errno(int n) { trap(SYS_set_errno, (ssize_t)n); } + +int thr_errno(void) { return (int)trap(SYS_errno, 0); } + +int getdents(int fd, dirent_t *dir, size_t size) +{ + getdents_args_t args; + + args.fd = fd; + args.dirp = dir; + args.count = size; + + return (int)trap(SYS_getdents, (uintptr_t)&args); +} + +#ifdef __MOUNTING__ +int mount(const char *spec, const char *dir, const char *fstype) +{ + mount_args_t args; + + args.spec.as_len = strlen(spec); + args.spec.as_str = spec; + args.dir.as_len = strlen(dir); + args.dir.as_str = dir; + args.fstype.as_len = strlen(fstype); + args.fstype.as_str = fstype; + + return (int)trap(SYS_mount, (uintptr_t)&args); +} + +int umount(const char *path) +{ + argstr_t argstr; + + argstr.as_len = strlen(path); + argstr.as_str = path; + + return (int)trap(SYS_umount, (uintptr_t)&argstr); +} +#endif /* MOUNTING */ + +int stat(const char *path, stat_t *buf) +{ + stat_args_t args; + + args.path.as_len = strlen(path); + args.path.as_str = path; + args.buf = buf; + + return (int)trap(SYS_stat, (uintptr_t)&args); +} + +int pipe(int pipefd[2]) { return (int)trap(SYS_pipe, (uintptr_t)pipefd); } + +int uname(struct utsname *buf) { return (int)trap(SYS_uname, (uintptr_t)buf); } + +time_t time(time_t *tloc) { return (time_t)trap(SYS_time, (uintptr_t)tloc); } + +long usleep(useconds_t usec) +{ + usleep_args_t args; + args.usec = usec; + return (long)trap(SYS_usleep, (uintptr_t)&args); +}
\ No newline at end of file |