123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /*
- * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #include <AK/Singleton.h>
- #include <AK/StringBuilder.h>
- #include <AK/StringView.h>
- #include <Kernel/FileSystem/DevPtsFS.h>
- #include <Kernel/FileSystem/VirtualFileSystem.h>
- #include <Kernel/TTY/SlavePTY.h>
- namespace Kernel {
- NonnullRefPtr<DevPtsFS> DevPtsFS::create()
- {
- return adopt_ref(*new DevPtsFS);
- }
- DevPtsFS::DevPtsFS()
- {
- }
- DevPtsFS::~DevPtsFS()
- {
- }
- static AK::Singleton<HashTable<unsigned>> s_ptys;
- bool DevPtsFS::initialize()
- {
- m_root_inode = adopt_ref(*new DevPtsFSInode(*this, 1, nullptr));
- m_root_inode->m_metadata.inode = { fsid(), 1 };
- m_root_inode->m_metadata.mode = 0040555;
- m_root_inode->m_metadata.uid = 0;
- m_root_inode->m_metadata.gid = 0;
- m_root_inode->m_metadata.size = 0;
- m_root_inode->m_metadata.mtime = mepoch;
- return true;
- }
- static unsigned inode_index_to_pty_index(InodeIndex inode_index)
- {
- VERIFY(inode_index > 1);
- return inode_index.value() - 2;
- }
- static InodeIndex pty_index_to_inode_index(unsigned pty_index)
- {
- return pty_index + 2;
- }
- NonnullRefPtr<Inode> DevPtsFS::root_inode() const
- {
- return *m_root_inode;
- }
- RefPtr<Inode> DevPtsFS::get_inode(InodeIdentifier inode_id) const
- {
- if (inode_id.index() == 1)
- return m_root_inode;
- unsigned pty_index = inode_index_to_pty_index(inode_id.index());
- auto* device = Device::get_device(201, pty_index);
- VERIFY(device);
- auto inode = adopt_ref(*new DevPtsFSInode(const_cast<DevPtsFS&>(*this), inode_id.index(), static_cast<SlavePTY*>(device)));
- inode->m_metadata.inode = inode_id;
- inode->m_metadata.size = 0;
- inode->m_metadata.uid = device->uid();
- inode->m_metadata.gid = device->gid();
- inode->m_metadata.mode = 0020600;
- inode->m_metadata.major_device = device->major();
- inode->m_metadata.minor_device = device->minor();
- inode->m_metadata.mtime = mepoch;
- return inode;
- }
- void DevPtsFS::register_slave_pty(SlavePTY& slave_pty)
- {
- s_ptys->set(slave_pty.index());
- }
- void DevPtsFS::unregister_slave_pty(SlavePTY& slave_pty)
- {
- s_ptys->remove(slave_pty.index());
- }
- DevPtsFSInode::DevPtsFSInode(DevPtsFS& fs, InodeIndex index, SlavePTY* pty)
- : Inode(fs, index)
- {
- if (pty)
- m_pty = *pty;
- }
- DevPtsFSInode::~DevPtsFSInode()
- {
- }
- ssize_t DevPtsFSInode::read_bytes(off_t, ssize_t, UserOrKernelBuffer&, FileDescription*) const
- {
- VERIFY_NOT_REACHED();
- }
- ssize_t DevPtsFSInode::write_bytes(off_t, ssize_t, const UserOrKernelBuffer&, FileDescription*)
- {
- VERIFY_NOT_REACHED();
- }
- InodeMetadata DevPtsFSInode::metadata() const
- {
- if (auto pty = m_pty.strong_ref()) {
- auto metadata = m_metadata;
- metadata.mtime = pty->time_of_last_write();
- return metadata;
- }
- return m_metadata;
- }
- KResult DevPtsFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)> callback) const
- {
- if (identifier().index() > 1)
- return ENOTDIR;
- callback({ ".", identifier(), 0 });
- callback({ "..", identifier(), 0 });
- for (unsigned pty_index : *s_ptys) {
- String name = String::number(pty_index);
- InodeIdentifier identifier = { fsid(), pty_index_to_inode_index(pty_index) };
- callback({ name, identifier, 0 });
- }
- return KSuccess;
- }
- KResultOr<size_t> DevPtsFSInode::directory_entry_count() const
- {
- VERIFY(identifier().index() == 1);
- return 2 + s_ptys->size();
- }
- RefPtr<Inode> DevPtsFSInode::lookup(StringView name)
- {
- VERIFY(identifier().index() == 1);
- if (name == "." || name == "..")
- return this;
- auto& fs = static_cast<DevPtsFS&>(this->fs());
- auto pty_index = name.to_uint();
- if (pty_index.has_value() && s_ptys->contains(pty_index.value())) {
- return fs.get_inode({ fsid(), pty_index_to_inode_index(pty_index.value()) });
- }
- return {};
- }
- void DevPtsFSInode::flush_metadata()
- {
- }
- KResult DevPtsFSInode::add_child(Inode&, const StringView&, mode_t)
- {
- return EROFS;
- }
- KResultOr<NonnullRefPtr<Inode>> DevPtsFSInode::create_child(const String&, mode_t, dev_t, uid_t, gid_t)
- {
- return EROFS;
- }
- KResult DevPtsFSInode::remove_child(const StringView&)
- {
- return EROFS;
- }
- KResult DevPtsFSInode::chmod(mode_t)
- {
- return EPERM;
- }
- KResult DevPtsFSInode::chown(uid_t, gid_t)
- {
- return EPERM;
- }
- }
|