diff --git a/Kernel/FileSystem/Inode.h b/Kernel/FileSystem/Inode.h index c078d836082..971a2f57ac2 100644 --- a/Kernel/FileSystem/Inode.h +++ b/Kernel/FileSystem/Inode.h @@ -23,7 +23,8 @@ namespace Kernel { -class Inode : public ListedRefCounted { +class Inode : public ListedRefCounted + , public Weakable { friend class VirtualFileSystem; friend class FileSystem; diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index f5dc0cc9f4e..74dd109598c 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -131,12 +131,13 @@ KResult LocalSocket::bind(Userspace user_address, socklen_t add } auto file = move(result.value()); + auto inode = file->inode(); - VERIFY(file->inode()); - if (!file->inode()->bind_socket(*this)) + VERIFY(inode); + if (!inode->bind_socket(*this)) return set_so_error(EADDRINUSE); - m_file = move(file); + m_inode = inode; m_path = move(path); m_bound = true; @@ -168,10 +169,12 @@ KResult LocalSocket::connect(OpenFileDescription& description, Userspaceview(), O_RDWR, 0, Process::current().current_directory())); + auto file = SOCKET_TRY(VirtualFileSystem::the().open(path->view(), O_RDWR, 0, Process::current().current_directory())); + auto inode = file->inode(); + m_inode = inode; - VERIFY(m_file->inode()); - if (!m_file->inode()->socket()) + VERIFY(inode); + if (!inode->socket()) return set_so_error(ECONNREFUSED); m_path = move(path); @@ -179,7 +182,7 @@ KResult LocalSocket::connect(OpenFileDescription& description, Userspaceinode()->socket(); + auto peer = file->inode()->socket(); auto result = peer->queue_connection_from(*this); if (result.is_error()) { set_connect_side_role(Role::None); @@ -244,6 +247,12 @@ void LocalSocket::detach(OpenFileDescription& description) } else { VERIFY(m_accept_side_fd_open); m_accept_side_fd_open = false; + + if (m_bound) { + auto inode = m_inode.strong_ref(); + if (inode) + inode->unbind_socket(); + } } evaluate_block_conditions(); @@ -425,8 +434,9 @@ KResult LocalSocket::ioctl(OpenFileDescription& description, unsigned request, U KResult LocalSocket::chmod(OpenFileDescription&, mode_t mode) { - if (m_file) - return m_file->chmod(mode); + auto inode = m_inode.strong_ref(); + if (inode) + return inode->chmod(mode); m_prebind_mode = mode & 0777; return KSuccess; @@ -434,8 +444,9 @@ KResult LocalSocket::chmod(OpenFileDescription&, mode_t mode) KResult LocalSocket::chown(OpenFileDescription&, UserID uid, GroupID gid) { - if (m_file) - return m_file->chown(uid, gid); + auto inode = m_inode.strong_ref(); + if (inode) + return inode->chown(uid, gid); auto& current_process = Process::current(); if (!current_process.is_superuser() && (current_process.euid() != uid || !current_process.in_group(gid))) diff --git a/Kernel/Net/LocalSocket.h b/Kernel/Net/LocalSocket.h index f1327944e06..00e8a4b4ff6 100644 --- a/Kernel/Net/LocalSocket.h +++ b/Kernel/Net/LocalSocket.h @@ -71,8 +71,8 @@ private: KResult try_set_path(StringView); - // An open socket file on the filesystem. - RefPtr m_file; + // The inode this socket is bound to. + WeakPtr m_inode; UserID m_prebind_uid { 0 }; GroupID m_prebind_gid { 0 };