From cabd9d7e4b013f4ad1e1ef49c0627b7bddf05b92 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sat, 13 May 2023 23:14:26 -0300 Subject: [PATCH] kernel: stat syscall family --- kernel-src/arch/x86-64/syscall.asm | 6 +- kernel-src/include/kernel/abi.h | 24 ++++++ kernel-src/sys/syscalls/stat.c | 114 +++++++++++++++++++++++++ patches/mlibc/jinx-working-patch.patch | 25 +++++- 4 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 kernel-src/sys/syscalls/stat.c diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index 1ac411c8..8d49e4d6 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -8,6 +8,8 @@ extern syscall_close extern syscall_archctl extern syscall_write extern syscall_getpid +extern syscall_fstat +extern syscall_fstatat syscalltab: dq syscall_print dq syscall_mmap @@ -18,7 +20,9 @@ dq syscall_close dq syscall_archctl dq syscall_write dq syscall_getpid -syscallcount equ 9 +dq syscall_fstat +dq syscall_fstatat +syscallcount equ 11 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/include/kernel/abi.h b/kernel-src/include/kernel/abi.h index 2a507a18..336dd031 100644 --- a/kernel-src/include/kernel/abi.h +++ b/kernel-src/include/kernel/abi.h @@ -1,6 +1,8 @@ #ifndef _ABI_H #define _ABI_H +#include + typedef int pid_t; typedef int tid_t; typedef int gid_t; @@ -8,6 +10,10 @@ typedef int uid_t; typedef unsigned int mode_t; typedef uint64_t ino_t; typedef long off_t; +typedef uint64_t dev_t; +typedef unsigned long nlink_t; +typedef long blksize_t; +typedef uint64_t blkcnt_t; #define POLLIN 0x1 #define POLLPRI 0x2 @@ -20,4 +26,22 @@ typedef long off_t; #define POLLWRNORM 0x100 #define POLLRDHUP 0x2000 +typedef struct { + dev_t dev; + ino_t ino; + nlink_t nlink; + mode_t mode; + uid_t uid; + gid_t gid; + unsigned int __pad0; + dev_t rdev; + off_t size; + blksize_t blksize; + blkcnt_t blocks; + timespec_t atim; + timespec_t mtim; + timespec_t ctim; + long __unused[3]; +} stat_t; + #endif diff --git a/kernel-src/sys/syscalls/stat.c b/kernel-src/sys/syscalls/stat.c new file mode 100644 index 00000000..31afce03 --- /dev/null +++ b/kernel-src/sys/syscalls/stat.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include +#include + +static int dostat(vnode_t *vnode, stat_t *stat) { + vattr_t attr; + VOP_LOCK(vnode); + int e = VOP_GETATTR(vnode, &attr, &_cpu()->thread->proc->cred); + VOP_UNLOCK(vnode); + if (e) + return e; + + + // TODO dev rdev + stat->ino = attr.inode; + stat->nlink = attr.nlinks; + stat->mode = attr.mode; + stat->uid = attr.uid; + stat->gid = attr.gid; + stat->size = attr.size; + stat->blksize = attr.fsblocksize; + stat->blocks = attr.blocksused; + stat->atim = attr.atime; + stat->mtim = attr.mtime; + stat->ctim = attr.ctime; + + return 0; +} + +syscallret_t syscall_fstat(context_t *ctx, int fd, stat_t *ustat) { + syscallret_t ret = { + .ret = -1 + }; + file_t *file = fd_get(fd); + if (file == NULL) { + ret.errno = EBADF; + return ret; + } + + stat_t buf; + ret.errno = dostat(file->vnode, &buf); + if (ret.errno) + goto cleanup; + + // TODO safe memcpy + *ustat = buf; + + cleanup: + fd_release(file); + return ret; +} + +#define AT_SYMLINK_NOFOLLOW 0x100 + +syscallret_t syscall_fstatat(context_t *ctx, int dirfd, char *upath, stat_t *ustat, int flags) { + syscallret_t ret = { + .ret = -1 + }; + + char *path = alloc(strlen(upath) + 1); + if (path == NULL) { + ret.errno = ENOMEM; + return ret; + } + strcpy(path, upath); + + vnode_t *dirnode = NULL; + file_t *file = NULL; + 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; + } + } + + vnode_t *node = NULL; + ret.errno = vfs_lookup(&node, dirnode, upath, NULL, flags & AT_SYMLINK_NOFOLLOW ? VFS_LOOKUP_NOLINK : 0); + if (ret.errno) + goto cleanup; + + stat_t buf; + ret.errno = dostat(node, &buf); + if (ret.errno) + goto cleanup; + + // TODO safe memcpy + *ustat = buf; + + cleanup: + if (node) + VOP_RELEASE(node); + + if (file) + fd_release(file); + else + VOP_RELEASE(dirnode); + return ret; +} diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index abe5fd36..aaa37933 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..81ba749 +index 0000000..dc6bd0e --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,163 @@ +@@ -0,0 +1,178 @@ +#include +#include +#include @@ -200,6 +200,21 @@ index 0000000..81ba749 + return 0; + } + ++ int sys_stat(fsfd_target fsfdt, int fd, const char *path, int flags, struct stat *statbuf) { ++ long ret; ++ switch (fsfdt) { ++ case fsfd_target::path: ++ return syscall(SYSCALL_FSTATAT, &ret, AT_FDCWD, (uint64_t)path, (uint64_t)statbuf, 0); ++ case fsfd_target::fd: ++ return syscall(SYSCALL_FSTAT, &ret, fd, (uint64_t)statbuf); ++ case fsfd_target::fd_path: ++ return syscall(SYSCALL_FSTATAT, &ret, fd, (uint64_t)path, (uint64_t)statbuf, flags); ++ default: ++ mlibc::infoLogger() << "mlibc: stat: Unknown fsfd_target: " << (int)fsfdt << frg::endlog; ++ return ENOSYS; ++ } ++ } ++ + pid_t sys_getpid() { + long ret; + syscall(SYSCALL_GETPID, &ret); @@ -319,10 +334,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..fe5ea34 +index 0000000..fde482a --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,32 @@ +@@ -0,0 +1,34 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + @@ -335,6 +350,8 @@ index 0000000..fe5ea34 +#define SYSCALL_ARCHCTL 6 +#define SYSCALL_WRITE 7 +#define SYSCALL_GETPID 8 ++#define SYSCALL_FSTAT 9 ++#define SYSCALL_FSTATAT 10 + +#include +#include