diff --git a/src/arch/x86_64/syscall.asm b/src/arch/x86_64/syscall.asm index 24af9504..b00ffdba 100644 --- a/src/arch/x86_64/syscall.asm +++ b/src/arch/x86_64/syscall.asm @@ -23,7 +23,8 @@ extern syscall_fcntl extern syscall_getpid extern syscall_getdirent extern syscall_ioctl -func_count equ 22 +extern syscall_chdir +func_count equ 23 func_table: @@ -49,6 +50,7 @@ func_table: dq syscall_getpid dq syscall_getdirent dq syscall_ioctl + dq syscall_chdir section .text global asm_syscall_entry diff --git a/src/sys/syscalls/chdir.c b/src/sys/syscalls/chdir.c new file mode 100644 index 00000000..33ec04a4 --- /dev/null +++ b/src/sys/syscalls/chdir.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +syscallret syscall_chdir(const char* path){ + syscallret retv; + + retv.ret = -1; + + if(path > USER_SPACE_END){ + retv.errno = EFAULT; + return retv; + } + + size_t len = strlen(path); + char buff[len+1]; + + strcpy(buff, path); + + proc_t* proc = arch_getcls()->thread->proc; + + vnode_t* node; + + retv.errno = vfs_open(&node, buff[0] == '/' ? proc->root : proc->cwd, buff); + + if(retv.errno) + return retv; + + if(GETTYPE(node->st.st_mode) != TYPE_DIR){ + vfs_close(node); + retv.errno = ENOTDIR; + return retv; + } + + vnode_t* old = proc->cwd; + proc->cwd = node; + + vfs_close(old); + + retv.ret = 0; + + return retv; + + +}