From 54e85957cf30c39f05ef0bcf83f05578b7645274 Mon Sep 17 00:00:00 2001 From: Matheus Date: Wed, 5 Jul 2023 00:36:29 -0300 Subject: [PATCH] syscalls: unlinkat --- kernel-src/arch/x86-64/syscall.asm | 4 +- kernel-src/arch/x86-64/syscalllog.c | 6 +- kernel-src/sys/syscalls/unlinkat.c | 78 ++++++++++++++++++++++++++ patches/mlibc/jinx-working-patch.patch | 14 +++-- 4 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 kernel-src/sys/syscalls/unlinkat.c diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index 5e3c80c0..f6d5f7c0 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -24,6 +24,7 @@ extern syscall_chdir extern syscall_pipe2 extern syscall_isatty extern syscall_faccessat +extern syscall_unlinkat syscalltab: dq syscall_print dq syscall_mmap @@ -50,7 +51,8 @@ dq syscall_chdir dq syscall_pipe2 dq syscall_isatty dq syscall_faccessat -syscallcount equ 25 +dq syscall_unlinkat +syscallcount equ 26 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/arch/x86-64/syscalllog.c b/kernel-src/arch/x86-64/syscalllog.c index 24000f99..b12b1ab0 100644 --- a/kernel-src/arch/x86-64/syscalllog.c +++ b/kernel-src/arch/x86-64/syscalllog.c @@ -30,7 +30,8 @@ static char *name[] = { "chdir", "pipe2", "isatty", - "faccessat" + "faccessat", + "unlinkat" }; static char *args[] = { @@ -58,7 +59,8 @@ static char *args[] = { "path %s", // chdir "flags %d", // pipe2 "fd %d", // isatty - "dirfd %d pathname %s mode %d flags %d" // faccessat + "dirfd %d pathname %s mode %d flags %d", // faccessat + "dirfd %d pathname %d flags %d" // unlinkat }; __attribute__((no_caller_saved_registers)) void arch_syscall_log(int syscall, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5, uint64_t a6) { diff --git a/kernel-src/sys/syscalls/unlinkat.c b/kernel-src/sys/syscalls/unlinkat.c new file mode 100644 index 00000000..a7519159 --- /dev/null +++ b/kernel-src/sys/syscalls/unlinkat.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include + +#define AT_SYMLINK_NOFOLLOW 0x100 + +syscallret_t syscall_unlinkat(context_t *, int dirfd, const char *upath, int flags) { + syscallret_t ret = { + .ret = -1 + }; + + size_t pathlen = strlen(upath) + 1; + char *path = alloc(pathlen); + if (path == NULL) { + ret.errno = ENOMEM; + return ret; + } + + // TODO safe strcopy + strcpy(path, upath); + + vnode_t *dirnode = NULL; + file_t *file = NULL; + + char *component = alloc(pathlen); + if (component == NULL) { + ret.errno = ENOMEM; + goto cleanup; + } + + if (*path == '/') { + dirnode = sched_getroot(); + } else if (dirfd == AT_FDCWD) { + dirnode = sched_getcwd(); + } else { + file = fd_get(dirfd); + if (file == NULL) { + ret.errno = EBADF; + goto cleanup; + } + + dirnode = file->vnode; + + if (dirnode->type != V_TYPE_DIR) { + ret.errno = ENOTDIR; + goto cleanup; + } + } + + // TODO rmdir flag + + vnode_t *node = NULL; + ret.errno = vfs_lookup(&node, dirnode, path, component, VFS_LOOKUP_NOLINK | VFS_LOOKUP_PARENT); + if (ret.errno) + goto cleanup; + + ret.errno = VOP_UNLINK(node, component, &_cpu()->thread->proc->cred); + ret.ret = ret.errno ? -1 : 0; + + cleanup: + if (component) + free(component); + + if (node) + VOP_RELEASE(node); + + if (file) + fd_release(file); + else + VOP_RELEASE(dirnode); + + free(path); + + return ret; +} diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index c94e4004..c72c9c5c 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -133,10 +133,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..f931e99 +index 0000000..f72940e --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,255 @@ +@@ -0,0 +1,260 @@ +#include +#include +#include @@ -192,6 +192,11 @@ index 0000000..f931e99 + return 0; + } + ++ int sys_unlinkat(int fd, const char *path, int flags) { ++ long ret; ++ return syscall(SYSCALL_UNLINKAT, &ret, fd, (uint64_t)path, flags); ++ } ++ + int sys_faccessat(int dirfd, const char *pathname, int mode, int flags){ + long ret; + return syscall(SYSCALL_FACCESSAT, &ret, dirfd, (uint64_t)pathname, mode, flags); @@ -411,10 +416,10 @@ 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..3a71f84 +index 0000000..89e809e --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,48 @@ +@@ -0,0 +1,49 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + @@ -443,6 +448,7 @@ index 0000000..3a71f84 +#define SYSCALL_PIPE2 22 +#define SYSCALL_ISATTY 23 +#define SYSCALL_FACCESSAT 24 ++#define SYSCALL_UNLINKAT 25 + +#include +#include