diff --git a/Kernel/FileSystem/Inode.h b/Kernel/FileSystem/Inode.h index adaf01dc7c..7cd5adb8aa 100644 --- a/Kernel/FileSystem/Inode.h +++ b/Kernel/FileSystem/Inode.h @@ -61,6 +61,8 @@ public: bool bind_socket(LocalSocket&); bool unbind_socket(); + virtual FileDescription* preopen_fd() { return nullptr; }; + bool is_metadata_dirty() const { return m_metadata_dirty; } virtual int set_atime(time_t); diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index a9703fd6fb..56da6e9984 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -230,6 +230,9 @@ KResultOr> VFS::open(StringView path, int options return KResult(-EACCES); } + if (auto preopen_fd = inode.preopen_fd()) + return *preopen_fd; + if (metadata.is_device()) { if (custody.mount_flags() & MS_NODEV) return KResult(-EACCES); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index e10d5405e2..ff8522e75a 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1908,8 +1908,14 @@ int Process::sys$open(const Syscall::SC_open_params* user_params) if (result.is_error()) return result.error(); auto description = result.value(); - description->set_rw_mode(options); - description->set_file_flags(options); + if (description->file_flags()) { + // We already have file flags set on this description, so + // it must be a preopen description (probably, /proc/pid/fd). + // So don't reset its flags and r/w mode. + } else { + description->set_rw_mode(options); + description->set_file_flags(options); + } u32 fd_flags = (options & O_CLOEXEC) ? FD_CLOEXEC : 0; m_fds[fd].set(move(description), fd_flags); return fd;