diff --git a/libc/Makefile b/libc/Makefile index 9d7e1740..207d662b 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -139,6 +139,7 @@ _exit.o \ _Exit.o \ exit.o \ faccessat.o \ +fchdir.o \ fchmod.o \ fcloseall.o \ fcntl.o \ diff --git a/libc/fchdir.cpp b/libc/fchdir.cpp new file mode 100644 index 00000000..a516feb4 --- /dev/null +++ b/libc/fchdir.cpp @@ -0,0 +1,33 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2012. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + fchdir.cpp + Changes the current working directory. + +*******************************************************************************/ + +#include +#include + +DEFN_SYSCALL1(int, sys_fchdir, SYSCALL_FCHDIR, int); + +extern "C" int fchdir(int fd) +{ + return sys_fchdir(fd); +} diff --git a/libc/include/unistd.h b/libc/include/unistd.h index 643a756c..db0e1a58 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -92,7 +92,6 @@ size_t confstr(int, char*, size_t); char* crypt(const char*, const char*); char* ctermid(char*); void encrypt(char [64], int); -int fchdir(int); int fchown(int, uid_t, gid_t); int fchownat(int, const char*, uid_t, gid_t, int); int fdatasync(int); @@ -161,6 +160,7 @@ int execve(const char*, char* const [], char* const []); int execvp(const char*, char* const []); pid_t fork(void); int faccessat(int, const char*, int, int); +int fchdir(int); int ftruncate(int, off_t); char* getcwd(char*, size_t); char* get_current_dir_name(void); diff --git a/sortix/include/sortix/syscallnum.h b/sortix/include/sortix/syscallnum.h index 8e67b243..c3a9d310 100644 --- a/sortix/include/sortix/syscallnum.h +++ b/sortix/include/sortix/syscallnum.h @@ -85,6 +85,7 @@ #define SYSCALL_UNLINKAT 61 #define SYSCALL_FACCESSAT 62 #define SYSCALL_MKDIRAT 63 -#define SYSCALL_MAX_NUM 64 /* index of highest constant + 1 */ +#define SYSCALL_FCHDIR 64 +#define SYSCALL_MAX_NUM 65 /* index of highest constant + 1 */ #endif diff --git a/sortix/io.cpp b/sortix/io.cpp index b5994d89..d2b35ebd 100644 --- a/sortix/io.cpp +++ b/sortix/io.cpp @@ -316,6 +316,18 @@ static ssize_t sys_readdirents(int fd, kernel_dirent* dirent, size_t size/*, return desc->readdirents(&ctx, dirent, size, 1 /*maxcount*/); } +static int sys_fchdir(int fd) +{ + Process* process = CurrentProcess(); + Ref desc = process->GetDescriptor(fd); + if ( !desc ) + return -1; + if ( !S_ISDIR(desc->type) ) + return errno = ENOTDIR, -1; + process->SetCWD(desc); + return 0; +} + static int sys_chdir(const char* path) { char* pathcopy = GetStringFromUser(path); @@ -442,6 +454,7 @@ void Init() Syscall::Register(SYSCALL_DUP, (void*) sys_dup); Syscall::Register(SYSCALL_DUP2, (void*) sys_dup2); Syscall::Register(SYSCALL_FACCESSAT, (void*) sys_faccessat); + Syscall::Register(SYSCALL_FCHDIR, (void*) sys_fchdir); Syscall::Register(SYSCALL_FCNTL, (void*) sys_fcntl); Syscall::Register(SYSCALL_FSTATAT, (void*) sys_fstatat); Syscall::Register(SYSCALL_FSTAT, (void*) sys_fstat);