diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index 43bee3f7..8462cd44 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -20,6 +20,7 @@ extern syscall_dup extern syscall_dup2 extern syscall_dup3 extern syscall_fcntl +extern syscall_chdir syscalltab: dq syscall_print dq syscall_mmap @@ -42,7 +43,8 @@ dq syscall_dup dq syscall_dup2 dq syscall_dup3 dq syscall_fcntl -syscallcount equ 21 +dq syscall_chdir +syscallcount equ 22 section .text global arch_syscall_entry ; on entry: diff --git a/kernel-src/sys/syscalls/chdir.c b/kernel-src/sys/syscalls/chdir.c new file mode 100644 index 00000000..319611d7 --- /dev/null +++ b/kernel-src/sys/syscalls/chdir.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include + +syscallret_t syscall_chdir(context_t *, const char *upath) { + syscallret_t ret = { + .ret = -1 + }; + + if (upath > (char *)USERSPACE_END) { + ret.errno = EFAULT; + return ret; + } + + // TODO safe string ops + char *path = alloc(strlen(upath) + 1); + strcpy(path, upath); + + vnode_t *ref = path[0] == '/' ? sched_getroot() : sched_getcwd(); + vnode_t *new = NULL; + + ret.errno = vfs_lookup(&new, ref, path, NULL, 0); + if (ret.errno) + goto cleanup; + + if (new->type != V_TYPE_DIR) { + ret.errno = ENOTDIR; + goto cleanup; + } + + sched_setcwd(new); + + cleanup: + if (new) + VOP_RELEASE(new); + + free(path); + VOP_RELEASE(ref); + + return ret; +} diff --git a/patches/mlibc/jinx-working-patch.patch b/patches/mlibc/jinx-working-patch.patch index dae0ee74..417ff16b 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..74b6be1 +index 0000000..ce76c73 --- /dev/null +++ mlibc-workdir/sysdeps/astral/generic/generic.cpp -@@ -0,0 +1,226 @@ +@@ -0,0 +1,231 @@ +#include +#include +#include @@ -192,6 +192,11 @@ index 0000000..74b6be1 + return 0; + } + ++ int sys_chdir(const char *path) { ++ long ret; ++ return syscall(SYSCALL_CHDIR, &ret, (uint64_t)path); ++ } ++ + int sys_fcntl(int fd, int request, va_list args, int *result) { + long arg = va_arg(args, uint64_t); + long ret; @@ -382,10 +387,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..f884f36 +index 0000000..e768d90 --- /dev/null +++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h -@@ -0,0 +1,44 @@ +@@ -0,0 +1,45 @@ +#ifndef _SYSCALL_H_INCLUDE +#define _SYSCALL_H_INCLUDE + @@ -410,6 +415,7 @@ index 0000000..f884f36 +#define SYSCALL_DUP2 18 +#define SYSCALL_DUP3 19 +#define SYSCALL_FCNTL 20 ++#define SYSCALL_CHDIR 21 + +#include +#include