Serenity Operating System
at master 122 lines 3.0 kB view raw
1/* 2 * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> 3 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include <Kernel/Devices/DeviceManagement.h> 9#include <Kernel/FileSystem/DevPtsFS/Inode.h> 10 11namespace Kernel { 12 13static InodeIndex pty_index_to_inode_index(unsigned pty_index) 14{ 15 return pty_index + 2; 16} 17 18DevPtsFSInode::DevPtsFSInode(DevPtsFS& fs, InodeIndex index, SlavePTY* pty) 19 : Inode(fs, index) 20{ 21 if (pty) 22 m_pty = *pty; 23} 24 25DevPtsFSInode::~DevPtsFSInode() = default; 26 27ErrorOr<size_t> DevPtsFSInode::read_bytes_locked(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const 28{ 29 VERIFY_NOT_REACHED(); 30} 31 32ErrorOr<size_t> DevPtsFSInode::write_bytes_locked(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) 33{ 34 VERIFY_NOT_REACHED(); 35} 36 37InodeMetadata DevPtsFSInode::metadata() const 38{ 39 if (auto pty = m_pty.strong_ref()) { 40 auto metadata = m_metadata; 41 metadata.mtime = Time::from_timespec({ pty->time_of_last_write(), 0 }); 42 return metadata; 43 } 44 return m_metadata; 45} 46 47ErrorOr<void> DevPtsFSInode::traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const 48{ 49 if (identifier().index() > 1) 50 return ENOTDIR; 51 52 TRY(callback({ "."sv, identifier(), 0 })); 53 TRY(callback({ ".."sv, identifier(), 0 })); 54 55 return SlavePTY::all_instances().with([&](auto& list) -> ErrorOr<void> { 56 StringBuilder builder; 57 for (SlavePTY& slave_pty : list) { 58 builder.clear(); 59 TRY(builder.try_appendff("{}", slave_pty.index())); 60 TRY(callback({ builder.string_view(), { fsid(), pty_index_to_inode_index(slave_pty.index()) }, 0 })); 61 } 62 return {}; 63 }); 64} 65 66ErrorOr<NonnullRefPtr<Inode>> DevPtsFSInode::lookup(StringView name) 67{ 68 VERIFY(identifier().index() == 1); 69 70 if (name == "." || name == "..") 71 return *this; 72 73 auto pty_index = name.to_uint(); 74 if (!pty_index.has_value()) 75 return ENOENT; 76 77 return SlavePTY::all_instances().with([&](auto& list) -> ErrorOr<NonnullRefPtr<Inode>> { 78 for (SlavePTY& slave_pty : list) { 79 if (slave_pty.index() != pty_index.value()) 80 continue; 81 return fs().get_inode({ fsid(), pty_index_to_inode_index(pty_index.value()) }); 82 } 83 return ENOENT; 84 }); 85} 86 87ErrorOr<void> DevPtsFSInode::flush_metadata() 88{ 89 return {}; 90} 91 92ErrorOr<void> DevPtsFSInode::add_child(Inode&, StringView, mode_t) 93{ 94 return EROFS; 95} 96 97ErrorOr<NonnullRefPtr<Inode>> DevPtsFSInode::create_child(StringView, mode_t, dev_t, UserID, GroupID) 98{ 99 return EROFS; 100} 101 102ErrorOr<void> DevPtsFSInode::remove_child(StringView) 103{ 104 return EROFS; 105} 106 107ErrorOr<void> DevPtsFSInode::replace_child(StringView, Inode&) 108{ 109 return EROFS; 110} 111 112ErrorOr<void> DevPtsFSInode::chmod(mode_t) 113{ 114 return EROFS; 115} 116 117ErrorOr<void> DevPtsFSInode::chown(UserID, GroupID) 118{ 119 return EROFS; 120} 121 122}