mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-07 19:57:45 +03:00
DevPtsFS: Do not assume there is one of it
Unfortunately, that also means it can no longer inherit from SynthFS.
This commit is contained in:
parent
37cc80fb96
commit
66a0a12435
Notes:
sideshowbarker
2024-07-19 12:39:32 +09:00
Author: https://github.com/bugaevc Commit: https://github.com/SerenityOS/serenity/commit/66a0a12435d Pull-request: https://github.com/SerenityOS/serenity/pull/456 Reviewed-by: https://github.com/awesomekling ✅
@ -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)
|
||||
{
|
||||
return "DevPtsFS";
|
||||
ASSERT(inode_index > 1);
|
||||
return inode_index - 2;
|
||||
}
|
||||
|
||||
NonnullRefPtr<SynthFSInode> DevPtsFS::create_slave_pty_device_file(unsigned index)
|
||||
static unsigned pty_index_to_inode_index(unsigned pty_index)
|
||||
{
|
||||
auto file = adopt(*new SynthFSInode(*this, generate_inode_index()));
|
||||
file->m_name = String::number(index);
|
||||
return pty_index + 2;
|
||||
}
|
||||
|
||||
auto* device = VFS::the().get_device(11, index);
|
||||
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)
|
||||
{
|
||||
error = -EROFS;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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 = 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);
|
||||
}
|
||||
|
@ -1,28 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/FileSystem/SyntheticFileSystem.h>
|
||||
#include <Kernel/FileSystem/FileSystem.h>
|
||||
#include <Kernel/FileSystem/Inode.h>
|
||||
|
||||
class Process;
|
||||
class SlavePTY;
|
||||
class DevPtsFSInode;
|
||||
|
||||
class DevPtsFS final : public SynthFS {
|
||||
class DevPtsFS final : public FS {
|
||||
public:
|
||||
static DevPtsFS& the();
|
||||
|
||||
virtual ~DevPtsFS() override;
|
||||
static NonnullRefPtr<DevPtsFS> create();
|
||||
|
||||
virtual bool initialize() override;
|
||||
virtual const char* class_name() const override;
|
||||
virtual const char* class_name() const override { return "DevPtsFS"; }
|
||||
|
||||
void register_slave_pty(SlavePTY&);
|
||||
void unregister_slave_pty(SlavePTY&);
|
||||
virtual InodeIdentifier root_inode() const override;
|
||||
virtual RefPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override;
|
||||
virtual RefPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override;
|
||||
virtual RefPtr<Inode> get_inode(InodeIdentifier) const override;
|
||||
|
||||
static void register_slave_pty(SlavePTY&);
|
||||
static void unregister_slave_pty(SlavePTY&);
|
||||
|
||||
private:
|
||||
DevPtsFS();
|
||||
|
||||
NonnullRefPtr<SynthFSInode> create_slave_pty_device_file(unsigned index);
|
||||
|
||||
HashTable<SlavePTY*> m_slave_ptys;
|
||||
RefPtr<DevPtsFSInode> m_root_inode;
|
||||
};
|
||||
|
||||
class DevPtsFSInode final : public Inode {
|
||||
friend class DevPtsFS;
|
||||
public:
|
||||
virtual ~DevPtsFSInode() override;
|
||||
|
||||
private:
|
||||
DevPtsFSInode(DevPtsFS&, unsigned index);
|
||||
|
||||
// ^Inode
|
||||
virtual ssize_t read_bytes(off_t, ssize_t, u8* buffer, FileDescription*) const override;
|
||||
virtual InodeMetadata metadata() const override;
|
||||
virtual bool traverse_as_directory(Function<bool(const FS::DirectoryEntry&)>) const override;
|
||||
virtual InodeIdentifier lookup(StringView name) override;
|
||||
virtual void flush_metadata() override;
|
||||
virtual ssize_t write_bytes(off_t, ssize_t, const u8* buffer, FileDescription*) override;
|
||||
virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override;
|
||||
virtual KResult remove_child(const StringView& name) override;
|
||||
virtual size_t directory_entry_count() const override;
|
||||
virtual KResult chmod(mode_t) override;
|
||||
virtual KResult chown(uid_t, gid_t) override;
|
||||
|
||||
InodeMetadata m_metadata;
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ SlavePTY::SlavePTY(MasterPTY& master, unsigned index)
|
||||
m_tty_name = String::format("/dev/pts/%u", m_index);
|
||||
set_uid(current->process().uid());
|
||||
set_gid(current->process().gid());
|
||||
DevPtsFS::the().register_slave_pty(*this);
|
||||
DevPtsFS::register_slave_pty(*this);
|
||||
set_size(80, 25);
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ SlavePTY::~SlavePTY()
|
||||
#ifdef SLAVEPTY_DEBUG
|
||||
dbgprintf("~SlavePTY(%u)\n", m_index);
|
||||
#endif
|
||||
DevPtsFS::the().unregister_slave_pty(*this);
|
||||
DevPtsFS::unregister_slave_pty(*this);
|
||||
}
|
||||
|
||||
String SlavePTY::tty_name() const
|
||||
|
@ -12,9 +12,6 @@ public:
|
||||
void on_master_write(const u8*, ssize_t);
|
||||
unsigned index() const { return m_index; }
|
||||
|
||||
InodeIdentifier devpts_inode_id() const { return m_devpts_inode_id; }
|
||||
void set_devpts_inode_id(InodeIdentifier inode_id) { m_devpts_inode_id = inode_id; }
|
||||
|
||||
private:
|
||||
// ^TTY
|
||||
virtual String tty_name() const override;
|
||||
@ -32,6 +29,5 @@ private:
|
||||
|
||||
RefPtr<MasterPTY> m_master;
|
||||
unsigned m_index;
|
||||
InodeIdentifier m_devpts_inode_id;
|
||||
String m_tty_name;
|
||||
};
|
||||
|
@ -122,7 +122,10 @@ VFS* vfs;
|
||||
auto procfs = ProcFS::create();
|
||||
procfs->initialize();
|
||||
vfs->mount(procfs, "/proc");
|
||||
vfs->mount(DevPtsFS::the(), "/dev/pts");
|
||||
|
||||
auto devptsfs = DevPtsFS::create();
|
||||
devptsfs->initialize();
|
||||
vfs->mount(devptsfs, "/dev/pts");
|
||||
|
||||
auto tmpfs = TmpFS::create();
|
||||
if (!tmpfs->initialize())
|
||||
|
Loading…
Reference in New Issue
Block a user