From b6ed9c1baceab5ecb267a7fb3cc0a6b3e82f9976 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 11 Aug 2024 14:44:53 -0300 Subject: [PATCH] syscalls: mknodat --- kernel-src/arch/x86-64/syscall.asm | 4 +- kernel-src/arch/x86-64/syscalllog.c | 8 ++-- kernel-src/include/kernel/vfs.h | 21 ++++++++++ kernel-src/sys/syscalls/mknodat.c | 58 ++++++++++++++++++++++++++ patches/mlibc/jinx-working-patch.patch | 18 ++++++-- 5 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 kernel-src/sys/syscalls/mknodat.c diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index 9e04d304..8aacea20 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -77,6 +77,7 @@ extern syscall_pause extern syscall_ppoll extern syscall_pread extern syscall_pwrite +extern syscall_mknodat syscalltab: dq syscall_print dq syscall_mmap @@ -156,7 +157,8 @@ dq syscall_pause dq syscall_ppoll dq syscall_pread dq syscall_pwrite -syscallcount equ 78 +dq syscall_mknodat +syscallcount equ 79 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 f20f028a..6f626754 100644 --- a/kernel-src/arch/x86-64/syscalllog.c +++ b/kernel-src/arch/x86-64/syscalllog.c @@ -5,7 +5,7 @@ #ifdef SYSCALL_LOGGING -#define SYSCALL_COUNT 78 +#define SYSCALL_COUNT 79 #define LOGSTR(x) arch_e9_puts(x) static char *name[] = { @@ -86,7 +86,8 @@ static char *name[] = { "pause", "ppoll", "pread", - "pwrite" + "pwrite", + "mknodat" }; static char *args[] = { @@ -165,9 +166,10 @@ static char *args[] = { "fd %d addr %p addrlen %p", // getpeername "path %s", // chroot "N/A", // pause - "fds %p nfds %d timeout %p sigmask %p" // ppoll + "fds %p nfds %d timeout %p sigmask %p", // ppoll "fd %d buffer %p count %lu offset %lu\n", // pread "fd %d buffer %p count %lu offset %lu\n", // pwrite + "dirfd %d path %s mode %o dev %x\n" // mknodat }; #endif diff --git a/kernel-src/include/kernel/vfs.h b/kernel-src/include/kernel/vfs.h index ce60f419..0aa5fc32 100644 --- a/kernel-src/include/kernel/vfs.h +++ b/kernel-src/include/kernel/vfs.h @@ -224,4 +224,25 @@ static inline mode_t vfs_getposixtype(int type) { } } +static inline mode_t vfs_getsystemtype(int type) { + switch (type) { + case TYPE_REGULAR: + return V_TYPE_REGULAR; + case TYPE_DIR: + return V_TYPE_DIR; + case TYPE_CHARDEV: + return V_TYPE_CHDEV; + case TYPE_BLOCKDEV: + return V_TYPE_BLKDEV; + case TYPE_FIFO: + return V_TYPE_FIFO; + case TYPE_LINK: + return V_TYPE_LINK; + case TYPE_SOCKET: + return V_TYPE_SOCKET; + default: + return -1; + } +} + #endif diff --git a/kernel-src/sys/syscalls/mknodat.c b/kernel-src/sys/syscalls/mknodat.c new file mode 100644 index 00000000..f0c0a02a --- /dev/null +++ b/kernel-src/sys/syscalls/mknodat.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include + +syscallret_t syscall_mknodat(context_t *, int dirfd, char *upath, mode_t mode, dev_t dev) { + syscallret_t ret = { + .ret = -1 + }; + + size_t pathlen; + ret.errno = usercopy_strlen(upath, &pathlen); + if (ret.errno) + return ret; + + char *path = alloc(pathlen + 1); + if (path == NULL) { + ret.errno = ENOMEM; + return ret; + } + + ret.errno = usercopy_fromuser(path, upath, pathlen); + if (ret.errno) { + free(path); + return ret; + } + + vnode_t *dirnode = NULL; + file_t *file = NULL; + ret.errno = dirfd_enter(path, dirfd, &file, &dirnode); + if (ret.errno) + goto cleanup; + + int type = vfs_getsystemtype(GETTYPE(mode)); + mode = GETMODE(mode); + + vattr_t attr = { + .mode = UMASK(mode), + .gid = _cpu()->thread->proc->cred.gid, + .uid = _cpu()->thread->proc->cred.uid, + .rdevmajor = (type == V_TYPE_CHDEV || type == V_TYPE_BLKDEV) ? MAJORDEV(dev) : 0, + .rdevminor = (type == V_TYPE_CHDEV || type == V_TYPE_BLKDEV) ? MINORDEV(dev) : 0, + }; + + ret.errno = vfs_create(dirnode, path, &attr, type, NULL); + ret.ret = ret.errno ? -1 : 0; + + cleanup: + + if (dirnode) + dirfd_leave(dirnode, file); + + free(path); + + return ret; +} diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index f37d6a4c..88ee41e9 100644 --- a/patches/mlibc/jinx-working-patch.patch +++ b/patches/mlibc/jinx-working-patch.patch @@ -207,10 +207,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..d6fe6cc +index 0000000..6eb771e --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,948 @@ +@@ -0,0 +1,957 @@ +#include +#include +#include @@ -330,6 +330,15 @@ index 0000000..d6fe6cc + return 0; + } + ++ int sys_mknodat(int dirfd, const char *path, int mode, int dev) { ++ long ret; ++ return syscall(SYSCALL_MKNODAT, &ret, dirfd, (uint64_t)path, mode, dev); ++ } ++ ++ int sys_mkfifoat(int dirfd, const char *path, mode_t mode) { ++ return sys_mknodat(dirfd, path, S_IFIFO | mode, 0); ++ } ++ + int sys_rmdir(const char *path) { + return sys_unlinkat(AT_FDCWD, path, AT_REMOVEDIR); + } @@ -1178,10 +1187,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..144207f +index 0000000..4a93549 --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,101 @@ +@@ -0,0 +1,102 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + @@ -1263,6 +1272,7 @@ index 0000000..144207f +#define SYSCALL_PPOLL 75 +#define SYSCALL_PREAD 76 +#define SYSCALL_PWRITE 77 ++#define SYSCALL_MKNODAT 78 + +#include +#include