From 8642a7046cf74e6ac79934cab0edacd83645d445 Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Wed, 15 Jan 2020 14:03:14 +0300 Subject: [PATCH] Kernel: Let inodes provide pre-open file descriptions Some magical inodes, such as /proc/pid/fd/fileno, are going to want to open() to a custom FileDescription, so add a hook for that. --- Kernel/FileSystem/Inode.h | 2 ++ Kernel/FileSystem/VirtualFileSystem.cpp | 3 +++ Kernel/Process.cpp | 10 ++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) 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;