summaryrefslogtreecommitdiff
path: root/Kernel/FileSystem/DevPtsFS.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/FileSystem/DevPtsFS.cpp')
-rw-r--r--Kernel/FileSystem/DevPtsFS.cpp172
1 files changed, 145 insertions, 27 deletions
diff --git a/Kernel/FileSystem/DevPtsFS.cpp b/Kernel/FileSystem/DevPtsFS.cpp
index 73c0282651..cb7203d83b 100644
--- a/Kernel/FileSystem/DevPtsFS.cpp
+++ b/Kernel/FileSystem/DevPtsFS.cpp
@@ -3,14 +3,6 @@
#include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/TTY/SlavePTY.h>
-static DevPtsFS* s_the;
-
-DevPtsFS& DevPtsFS::the()
-{
- ASSERT(s_the);
- return *s_the;
-}
-
NonnullRefPtr<DevPtsFS> DevPtsFS::create()
{
return adopt(*new DevPtsFS);
@@ -18,49 +10,175 @@ NonnullRefPtr<DevPtsFS> DevPtsFS::create()
DevPtsFS::DevPtsFS()
{
- s_the = this;
}
DevPtsFS::~DevPtsFS()
{
}
+static HashTable<unsigned>* ptys;
+
bool DevPtsFS::initialize()
{
- SynthFS::initialize();
+ if (ptys == nullptr) {
+ ptys = new HashTable<unsigned>();
+ }
+
+ m_root_inode = adopt(*new DevPtsFSInode(*this, 1));
+ 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;
}
-const char* DevPtsFS::class_name() const
+static unsigned inode_index_to_pty_index(unsigned inode_index)
+{
+ ASSERT(inode_index > 1);
+ return inode_index - 2;
+}
+
+static unsigned pty_index_to_inode_index(unsigned pty_index)
+{
+ return pty_index + 2;
+}
+
+InodeIdentifier DevPtsFS::root_inode() const
+{
+ return { fsid(), 1 };
+}
+
+RefPtr<Inode> DevPtsFS::create_inode(InodeIdentifier, const String&, mode_t, off_t, dev_t, int& error)
+{
+ error = -EROFS;
+ return nullptr;
+}
+
+RefPtr<Inode> DevPtsFS::create_directory(InodeIdentifier, const String&, mode_t, int& error)
{
- return "DevPtsFS";
+ error = -EROFS;
+ return nullptr;
}
-NonnullRefPtr<SynthFSInode> DevPtsFS::create_slave_pty_device_file(unsigned index)
+RefPtr<Inode> DevPtsFS::get_inode(InodeIdentifier inode_id) const
{
- auto file = adopt(*new SynthFSInode(*this, generate_inode_index()));
- file->m_name = String::number(index);
+ if (inode_id.index() == 1)
+ return m_root_inode;
- auto* device = VFS::the().get_device(11, index);
+ unsigned pty_index = inode_index_to_pty_index(inode_id.index());
+ auto* device = VFS::the().get_device(11, pty_index);
ASSERT(device);
- file->m_metadata.size = 0;
- file->m_metadata.uid = device->uid();
- file->m_metadata.gid = device->gid();
- file->m_metadata.mode = 0020644;
- file->m_metadata.major_device = device->major();
- file->m_metadata.minor_device = device->minor();
- file->m_metadata.mtime = mepoch;
- return file;
+ auto inode = adopt(*new DevPtsFSInode(const_cast<DevPtsFS&>(*this), inode_id.index()));
+ 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 = 0020644;
+ 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)
{
- auto inode_id = add_file(create_slave_pty_device_file(slave_pty.index()));
- slave_pty.set_devpts_inode_id(inode_id);
+ ptys->set(slave_pty.index());
}
void DevPtsFS::unregister_slave_pty(SlavePTY& slave_pty)
{
- remove_file(slave_pty.devpts_inode_id().index());
+ ptys->remove(slave_pty.index());
+}
+
+DevPtsFSInode::DevPtsFSInode(DevPtsFS& fs, unsigned index)
+ : Inode(fs, index)
+{
+}
+
+DevPtsFSInode::~DevPtsFSInode()
+{
+}
+
+ssize_t DevPtsFSInode::read_bytes(off_t, ssize_t, u8*, FileDescription*) const
+{
+ ASSERT_NOT_REACHED();
+}
+
+ssize_t DevPtsFSInode::write_bytes(off_t, ssize_t, const u8*, FileDescription*)
+{
+ ASSERT_NOT_REACHED();
+}
+
+InodeMetadata DevPtsFSInode::metadata() const
+{
+ return m_metadata;
+}
+
+bool DevPtsFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry&)> callback) const
+{
+ if (identifier().index() > 1)
+ return false;
+
+ callback({ ".", 1, identifier(), 0 });
+ callback({ "..", 2, identifier(), 0 });
+
+ for (unsigned pty_index : *ptys) {
+ String name = String::number(pty_index);
+ InodeIdentifier identifier = { fsid(), pty_index_to_inode_index(pty_index) };
+ callback({ name.characters(), name.length(), identifier, 0 });
+ }
+
+ return true;
+}
+
+size_t DevPtsFSInode::directory_entry_count() const
+{
+ ASSERT(identifier().index() == 1);
+
+ return 2 + ptys->size();
+}
+
+InodeIdentifier DevPtsFSInode::lookup(StringView name)
+{
+ ASSERT(identifier().index() == 1);
+
+ if (name == "." || name == "..")
+ return identifier();
+
+ bool ok;
+ unsigned pty_index = name.to_uint(ok);
+ if (ok && ptys->contains(pty_index)) {
+ return { fsid(), pty_index_to_inode_index(pty_index) };
+ }
+
+ return {};
+}
+
+void DevPtsFSInode::flush_metadata()
+{
+}
+
+KResult DevPtsFSInode::add_child(InodeIdentifier, const StringView&, mode_t)
+{
+ return KResult(-EROFS);
+}
+
+KResult DevPtsFSInode::remove_child(const StringView&)
+{
+ return KResult(-EROFS);
+}
+
+KResult DevPtsFSInode::chmod(mode_t)
+{
+ return KResult(-EPERM);
+}
+
+KResult DevPtsFSInode::chown(uid_t, gid_t)
+{
+ return KResult(-EPERM);
}