aboutsummaryrefslogtreecommitdiff
path: root/user/lib/libc/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'user/lib/libc/syscall.c')
-rw-r--r--user/lib/libc/syscall.c391
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