Przeglądaj źródła

Kernel: Implement fchdir syscall

The fchdir() function is equivalent to chdir() except that the
directory that is to be the new current working directory is
specified by a file descriptor.
Mauri de Souza Nunes 5 lat temu
rodzic
commit
7d85fc00e4

+ 13 - 0
Kernel/Process.cpp

@@ -1202,6 +1202,19 @@ int Process::sys$chdir(const char* path)
     return 0;
     return 0;
 }
 }
 
 
+int Process::sys$fchdir(int fd)
+{
+    auto* description = file_description(fd);
+    if (!description)
+        return -EBADF;
+
+    if (!description->is_directory())
+   	return -ENOTDIR;
+
+    m_cwd = description->custody();
+    return 0;
+}
+
 int Process::sys$getcwd(char* buffer, ssize_t size)
 int Process::sys$getcwd(char* buffer, ssize_t size)
 {
 {
     if (size < 0)
     if (size < 0)

+ 1 - 0
Kernel/Process.h

@@ -152,6 +152,7 @@ public:
     ssize_t sys$get_dir_entries(int fd, void*, ssize_t);
     ssize_t sys$get_dir_entries(int fd, void*, ssize_t);
     int sys$getcwd(char*, ssize_t);
     int sys$getcwd(char*, ssize_t);
     int sys$chdir(const char*);
     int sys$chdir(const char*);
+    int sys$fchdir(int fd);
     int sys$sleep(unsigned seconds);
     int sys$sleep(unsigned seconds);
     int sys$usleep(useconds_t usec);
     int sys$usleep(useconds_t usec);
     int sys$gettimeofday(timeval*);
     int sys$gettimeofday(timeval*);

+ 2 - 0
Kernel/Syscall.cpp

@@ -136,6 +136,8 @@ static u32 handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3
         break;
         break;
     case Syscall::SC_chdir:
     case Syscall::SC_chdir:
         return current->process().sys$chdir((const char*)arg1);
         return current->process().sys$chdir((const char*)arg1);
+    case Syscall::SC_fchdir:
+        return current->process().sys$fchdir((int)arg1);
     case Syscall::SC_uname:
     case Syscall::SC_uname:
         return current->process().sys$uname((utsname*)arg1);
         return current->process().sys$uname((utsname*)arg1);
     case Syscall::SC_set_mmap_name:
     case Syscall::SC_set_mmap_name:

+ 1 - 0
Kernel/Syscall.h

@@ -32,6 +32,7 @@ struct timeval;
     __ENUMERATE_SYSCALL(gettimeofday)           \
     __ENUMERATE_SYSCALL(gettimeofday)           \
     __ENUMERATE_SYSCALL(gethostname)            \
     __ENUMERATE_SYSCALL(gethostname)            \
     __ENUMERATE_SYSCALL(chdir)                  \
     __ENUMERATE_SYSCALL(chdir)                  \
+    __ENUMERATE_SYSCALL(fchdir)                 \
     __ENUMERATE_SYSCALL(uname)                  \
     __ENUMERATE_SYSCALL(uname)                  \
     __ENUMERATE_SYSCALL(set_mmap_name)          \
     __ENUMERATE_SYSCALL(set_mmap_name)          \
     __ENUMERATE_SYSCALL(readlink)               \
     __ENUMERATE_SYSCALL(readlink)               \

+ 6 - 0
Libraries/LibC/unistd.cpp

@@ -265,6 +265,12 @@ int chdir(const char* path)
     __RETURN_WITH_ERRNO(rc, rc, -1);
     __RETURN_WITH_ERRNO(rc, rc, -1);
 }
 }
 
 
+int fchdir(int fd)
+{
+    int rc = syscall(SC_fchdir, fd);
+    __RETURN_WITH_ERRNO(rc, rc, -1);
+}
+
 char* getcwd(char* buffer, size_t size)
 char* getcwd(char* buffer, size_t size)
 {
 {
     if (!buffer) {
     if (!buffer) {

+ 1 - 0
Libraries/LibC/unistd.h

@@ -68,6 +68,7 @@ int close(int fd);
 pid_t waitpid(pid_t, int* wstatus, int options);
 pid_t waitpid(pid_t, int* wstatus, int options);
 pid_t wait(int* wstatus);
 pid_t wait(int* wstatus);
 int chdir(const char* path);
 int chdir(const char* path);
+int fchdir(int fd);
 char* getcwd(char* buffer, size_t size);
 char* getcwd(char* buffer, size_t size);
 char* getwd(char* buffer);
 char* getwd(char* buffer);
 int fstat(int fd, struct stat* statbuf);
 int fstat(int fd, struct stat* statbuf);