From 4cfb83f4fef3b16f0f1119effc3b2e01bcc2ec0c Mon Sep 17 00:00:00 2001 From: Matheus Date: Tue, 9 May 2023 23:25:29 -0300 Subject: [PATCH] syscall: openat --- kernel-src/arch/x86-64/syscall.asm | 4 +- kernel-src/sys/syscalls/open.c | 98 ++++++++++++++++++++++++++ patches/mlibc/jinx-working-patch.patch | 16 +++-- 3 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 kernel-src/sys/syscalls/open.c diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index fabfbfa5..5d9d5ecb 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -1,11 +1,13 @@ section .rodata extern syscall_print extern syscall_mmap +extern syscall_openat syscalltab: dq syscall_print dq syscall_mmap +dq syscall_openat -syscallcount equ 2 +syscallcount equ 3 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/sys/syscalls/open.c b/kernel-src/sys/syscalls/open.c new file mode 100644 index 00000000..65262a75 --- /dev/null +++ b/kernel-src/sys/syscalls/open.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include + +syscallret_t syscall_openat(context_t *context, int dirfd, const char *path, int flags, mode_t mode) { + syscallret_t ret = { + .ret = -1, + .errno = 0 + }; + + // transform O_RDONLY, O_WRONLY, O_RDWR into FILE_READ and FILE_WRITE + ++flags; + + __assert((~FILE_KNOWN_FLAGS & flags) == 0); + + vnode_t *dirnode = NULL; + file_t *dirfile; + + size_t pathsize = strlen(path); // TODO u_strlen + char *pathbuf = alloc(pathsize + 1); + strcpy(pathbuf, path); // TODO u_strcpy + + if (*pathbuf == '/') { + dirnode = sched_getroot(); + dirfile = NULL; + } else if (dirfd == AT_FDCWD) { + dirnode = sched_getcwd(); + dirfile = NULL; + } else { + dirfile = fd_get(dirfd); + if (dirfile == NULL) { + ret.errno = EBADF; + goto cleanup; + } + + dirnode = dirfile->vnode; + if (dirnode->type != V_TYPE_DIR) { + ret.errno = ENOTDIR; + goto cleanup; + } + } + + // TODO pass CLOEXEC to fd + file_t *newfile = NULL; + int newfd; + ret.errno = fd_new(0, &newfile, &newfd); + if (ret.errno) + goto cleanup; + + vnode_t *vnode = NULL; + ret.errno = vfs_open(dirnode, pathbuf, fileflagstovnodeflags(flags), &vnode); + if (ret.errno) + goto cleanup; + + vattr_t attr; + VOP_LOCK(vnode); + ret.errno = VOP_GETATTR(vnode, &attr, &_cpu()->thread->proc->cred); + VOP_UNLOCK(vnode); + if (ret.errno) + goto cleanup; + + // node refcount is already increased by open + newfile->vnode = vnode; + newfile->flags = flags; + newfile->offset = 0; + newfile->mode = attr.mode; + + ret.errno = 0; + ret.ret = newfd; + + cleanup: + if (vnode && ret.errno) { + vfs_close(vnode, fileflagstovnodeflags(flags)); + VOP_RELEASE(vnode); + } + + if (newfile) { + if (ret.errno) { + __assert(fd_close(newfd) == 0); + } else { + fd_release(newfile); + } + } + + if (pathbuf) + free(pathbuf); + + if (dirfile) { + fd_release(dirfile); + } else if (dirnode){ + VOP_RELEASE(dirnode); + } + + return ret; +} diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index 9c820067..d06e4905 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -113,10 +113,10 @@ index 0000000..e5b087a + diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp new file mode 100644 -index 0000000..4d9555e +index 0000000..6715503 --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,138 @@ +@@ -0,0 +1,143 @@ +#include +#include +#include @@ -218,7 +218,12 @@ index 0000000..4d9555e + } + + int sys_open(const char *pathname, int flags, mode_t mode, int *fd) { -+ return ENOSYS; ++ long ret; ++ long err = syscall(SYSCALL_OPENAT, &ret, AT_FDCWD, (uint64_t)pathname, flags, mode); ++ if (err) ++ return err; ++ *fd = ret; ++ return 0; + }; + int sys_read(int fd, void *buff, size_t count, ssize_t *bytes_read) { + return ENOSYS; @@ -274,15 +279,16 @@ index 0000000..990eca0 +#endif diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h new file mode 100644 -index 0000000..8f1ee3c +index 0000000..6ef92cd --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,25 @@ +@@ -0,0 +1,26 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + +#define SYSCALL_PRINT 0 +#define SYSCALL_MMAP 1 ++#define SYSCALL_OPENAT 2 + +#include +#include