From 7a1d09ef1a79f43ae39bc11f3c529cf420699c76 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Fri, 30 Apr 2021 10:33:33 +0200 Subject: [PATCH] Kernel: Closing a file descriptor should not always close the file When there is more than one file descriptor for a file closing one of them should not close the underlying file. Previously this relied on the file's ref_count() but at least for sockets this didn't work reliably. --- Kernel/FileSystem/File.cpp | 11 +++++++++++ Kernel/FileSystem/File.h | 7 +++++-- Kernel/FileSystem/FileDescription.cpp | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Kernel/FileSystem/File.cpp b/Kernel/FileSystem/File.cpp index 0502174c45..2ca225a0df 100644 --- a/Kernel/FileSystem/File.cpp +++ b/Kernel/FileSystem/File.cpp @@ -43,4 +43,15 @@ KResultOr File::mmap(Process&, FileDescription&, const Range&, u64, int return ENODEV; } +KResult File::attach(FileDescription&) +{ + m_attach_count++; + return KSuccess; +} + +void File::detach(FileDescription&) +{ + m_attach_count--; +} + } diff --git a/Kernel/FileSystem/File.h b/Kernel/FileSystem/File.h index 4f8173aefa..fade38d7a7 100644 --- a/Kernel/FileSystem/File.h +++ b/Kernel/FileSystem/File.h @@ -82,8 +82,8 @@ public: virtual bool can_read(const FileDescription&, size_t) const = 0; virtual bool can_write(const FileDescription&, size_t) const = 0; - virtual KResult attach(FileDescription&) { return KSuccess; } - virtual void detach(FileDescription&) { } + virtual KResult attach(FileDescription&); + virtual void detach(FileDescription&); virtual void did_seek(FileDescription&, off_t) { } virtual KResultOr read(FileDescription&, u64, UserOrKernelBuffer&, size_t) = 0; virtual KResultOr write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) = 0; @@ -112,6 +112,8 @@ public: virtual FileBlockCondition& block_condition() { return m_block_condition; } + size_t attach_count() const { return m_attach_count; } + protected: File(); @@ -138,6 +140,7 @@ private: } FileBlockCondition m_block_condition; + size_t m_attach_count { 0 }; }; } diff --git a/Kernel/FileSystem/FileDescription.cpp b/Kernel/FileSystem/FileDescription.cpp index 9ea9f23842..4918f5f83d 100644 --- a/Kernel/FileSystem/FileDescription.cpp +++ b/Kernel/FileSystem/FileDescription.cpp @@ -288,7 +288,7 @@ MasterPTY* FileDescription::master_pty() KResult FileDescription::close() { - if (m_file->ref_count() > 1) + if (m_file->attach_count() > 0) return KSuccess; return m_file->close(); }