1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 23:17:45 +00:00

Kernel: Add Device base class for CharacterDevice.

..to prepare for adding a BlockDevice class.
This commit is contained in:
Andreas Kling 2019-02-16 00:47:20 +01:00
parent c6ca6522fc
commit 994279d56c
11 changed files with 113 additions and 94 deletions

View file

@ -1,20 +1,7 @@
#include "CharacterDevice.h"
#include <LibC/errno_numbers.h>
#pragma once
#include <Kernel/CharacterDevice.h>
CharacterDevice::~CharacterDevice()
{
}
RetainPtr<FileDescriptor> CharacterDevice::open(int& error, int options)
{
return VFS::the().open(*this, error, options);
}
void CharacterDevice::close()
{
}
int CharacterDevice::ioctl(Process&, unsigned, unsigned)
{
return -ENOTTY;
}

View file

@ -1,48 +1,11 @@
#pragma once
#include <AK/Retainable.h>
#include <AK/Types.h>
#include "Limits.h"
#include "FileDescriptor.h"
#include <Kernel/Device.h>
class Process;
class CharacterDevice : public Retainable<CharacterDevice> {
class CharacterDevice : public Device {
public:
virtual ~CharacterDevice();
InodeMetadata metadata() const { return { }; }
virtual RetainPtr<FileDescriptor> open(int& error, int options);
virtual void close();
virtual bool can_read(Process&) const = 0;
virtual bool can_write(Process&) const = 0;
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) = 0;
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) = 0;
unsigned major() const { return m_major; }
unsigned minor() const { return m_minor; }
virtual bool is_tty() const { return false; }
virtual bool is_master_pty() const { return false; }
virtual int ioctl(Process&, unsigned request, unsigned arg);
virtual const char* class_name() const = 0;
uid_t uid() const { return m_uid; }
uid_t gid() const { return m_gid; }
virtual ~CharacterDevice() override;
protected:
CharacterDevice(unsigned major, unsigned minor) : m_major(major), m_minor(minor) { }
void set_uid(uid_t uid) { m_uid = uid; }
void set_gid(gid_t gid) { m_gid = gid; }
private:
unsigned m_major { 0 };
unsigned m_minor { 0 };
uid_t m_uid { 0 };
gid_t m_gid { 0 };
CharacterDevice(unsigned major, unsigned minor) : Device(major, minor) { }
};

20
Kernel/Device.cpp Normal file
View file

@ -0,0 +1,20 @@
#include "CharacterDevice.h"
#include <LibC/errno_numbers.h>
Device::~Device()
{
}
RetainPtr<FileDescriptor> Device::open(int& error, int options)
{
return VFS::the().open(*this, error, options);
}
void Device::close()
{
}
int Device::ioctl(Process&, unsigned, unsigned)
{
return -ENOTTY;
}

48
Kernel/Device.h Normal file
View file

@ -0,0 +1,48 @@
#pragma once
#include <AK/Retainable.h>
#include <AK/Types.h>
#include "Limits.h"
#include "FileDescriptor.h"
class Process;
class Device : public Retainable<Device> {
public:
virtual ~Device();
InodeMetadata metadata() const { return { }; }
virtual RetainPtr<FileDescriptor> open(int& error, int options);
virtual void close();
virtual bool can_read(Process&) const = 0;
virtual bool can_write(Process&) const = 0;
virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) = 0;
virtual ssize_t write(Process&, const byte* buffer, size_t bufferSize) = 0;
unsigned major() const { return m_major; }
unsigned minor() const { return m_minor; }
virtual bool is_tty() const { return false; }
virtual bool is_master_pty() const { return false; }
virtual int ioctl(Process&, unsigned request, unsigned arg);
virtual const char* class_name() const = 0;
uid_t uid() const { return m_uid; }
uid_t gid() const { return m_gid; }
protected:
Device(unsigned major, unsigned minor) : m_major(major), m_minor(minor) { }
void set_uid(uid_t uid) { m_uid = uid; }
void set_gid(gid_t gid) { m_gid = gid; }
private:
unsigned m_major { 0 };
unsigned m_minor { 0 };
uid_t m_uid { 0 };
gid_t m_gid { 0 };
};

View file

@ -14,7 +14,7 @@ RetainPtr<FileDescriptor> FileDescriptor::create(RetainPtr<Inode>&& inode)
return adopt(*new FileDescriptor(move(inode)));
}
RetainPtr<FileDescriptor> FileDescriptor::create(RetainPtr<CharacterDevice>&& device)
RetainPtr<FileDescriptor> FileDescriptor::create(RetainPtr<Device>&& device)
{
return adopt(*new FileDescriptor(move(device)));
}
@ -39,7 +39,7 @@ FileDescriptor::FileDescriptor(RetainPtr<Inode>&& inode)
{
}
FileDescriptor::FileDescriptor(RetainPtr<CharacterDevice>&& device)
FileDescriptor::FileDescriptor(RetainPtr<Device>&& device)
: m_device(move(device))
{
}

View file

@ -18,7 +18,7 @@ public:
static RetainPtr<FileDescriptor> create(RetainPtr<Socket>&&, SocketRole = SocketRole::None);
static RetainPtr<FileDescriptor> create(RetainPtr<Inode>&&);
static RetainPtr<FileDescriptor> create(RetainPtr<CharacterDevice>&&);
static RetainPtr<FileDescriptor> create(RetainPtr<Device>&&);
static RetainPtr<FileDescriptor> create_pipe_writer(FIFO&);
static RetainPtr<FileDescriptor> create_pipe_reader(FIFO&);
~FileDescriptor();
@ -44,8 +44,8 @@ public:
bool is_directory() const;
bool is_character_device() const { return m_device.ptr(); }
CharacterDevice* character_device() { return m_device.ptr(); }
const CharacterDevice* character_device() const { return m_device.ptr(); }
Device* character_device() { return m_device.ptr(); }
const Device* character_device() const { return m_device.ptr(); }
bool is_tty() const;
const TTY* tty() const;
@ -84,11 +84,11 @@ private:
friend class VFS;
FileDescriptor(RetainPtr<Socket>&&, SocketRole);
explicit FileDescriptor(RetainPtr<Inode>&&);
explicit FileDescriptor(RetainPtr<CharacterDevice>&&);
explicit FileDescriptor(RetainPtr<Device>&&);
FileDescriptor(FIFO&, FIFO::Direction);
RetainPtr<Inode> m_inode;
RetainPtr<CharacterDevice> m_device;
RetainPtr<Device> m_device;
off_t m_current_offset { 0 };

View file

@ -37,6 +37,7 @@ KERNEL_OBJS = \
VFS_OBJS = \
DiskDevice.o \
Device.o \
CharacterDevice.o \
NullDevice.o \
FullDevice.o \

View file

@ -10,7 +10,7 @@ SlavePTY::SlavePTY(MasterPTY& master, unsigned index)
{
set_uid(current->uid());
set_gid(current->gid());
VFS::the().register_character_device(*this);
VFS::the().register_device(*this);
DevPtsFS::the().register_slave_pty(*this);
set_size(80, 25);
}
@ -19,7 +19,7 @@ SlavePTY::~SlavePTY()
{
dbgprintf("~SlavePTY(%u)\n", m_index);
DevPtsFS::the().unregister_slave_pty(*this);
VFS::the().unregister_character_device(*this);
VFS::the().unregister_device(*this);
}
String SlavePTY::tty_name() const

View file

@ -122,7 +122,7 @@ void VFS::traverse_directory_inode(Inode& dir_inode, Function<bool(const FS::Dir
});
}
RetainPtr<FileDescriptor> VFS::open(RetainPtr<CharacterDevice>&& device, int& error, int options)
RetainPtr<FileDescriptor> VFS::open(RetainPtr<Device>&& device, int& error, int options)
{
// FIXME: Respect options.
(void) options;
@ -146,9 +146,9 @@ RetainPtr<FileDescriptor> VFS::open(const String& path, int& error, int options,
return nullptr;
auto metadata = inode->metadata();
if (!(options & O_DONT_OPEN_DEVICE) && metadata.is_character_device()) {
auto it = m_character_devices.find(encoded_device(metadata.major_device, metadata.minor_device));
if (it == m_character_devices.end()) {
kprintf("VFS::open: no such character device %u,%u\n", metadata.major_device, metadata.minor_device);
auto it = m_devices.find(encoded_device(metadata.major_device, metadata.minor_device));
if (it == m_devices.end()) {
kprintf("VFS::open: no such device %u,%u\n", metadata.major_device, metadata.minor_device);
return nullptr;
}
auto descriptor = (*it).value->open(error, options);
@ -516,20 +516,20 @@ VFS::Mount::Mount(InodeIdentifier host, RetainPtr<FS>&& guest_fs)
{
}
void VFS::register_character_device(CharacterDevice& device)
void VFS::register_device(Device& device)
{
m_character_devices.set(encoded_device(device.major(), device.minor()), &device);
m_devices.set(encoded_device(device.major(), device.minor()), &device);
}
void VFS::unregister_character_device(CharacterDevice& device)
void VFS::unregister_device(Device& device)
{
m_character_devices.remove(encoded_device(device.major(), device.minor()));
m_devices.remove(encoded_device(device.major(), device.minor()));
}
CharacterDevice* VFS::get_device(unsigned major, unsigned minor)
Device* VFS::get_device(unsigned major, unsigned minor)
{
auto it = m_character_devices.find(encoded_device(major, minor));
if (it == m_character_devices.end())
auto it = m_devices.find(encoded_device(major, minor));
if (it == m_devices.end())
return nullptr;
return (*it).value;
}

View file

@ -26,7 +26,7 @@
#define O_NOFOLLOW_NOERROR 0x4000000
#define O_DONT_OPEN_DEVICE 0x8000000
class CharacterDevice;
class Device;
class FileDescriptor;
inline constexpr dword encoded_device(unsigned major, unsigned minor)
@ -62,7 +62,7 @@ public:
bool mount_root(RetainPtr<FS>&&);
bool mount(RetainPtr<FS>&&, const String& path);
RetainPtr<FileDescriptor> open(RetainPtr<CharacterDevice>&&, int& error, int options);
RetainPtr<FileDescriptor> open(RetainPtr<Device>&&, int& error, int options);
RetainPtr<FileDescriptor> open(const String& path, int& error, int options, mode_t mode, Inode& base);
RetainPtr<FileDescriptor> create(const String& path, int& error, int options, mode_t mode, Inode& base);
bool mkdir(const String& path, mode_t mode, Inode& base, int& error);
@ -70,8 +70,8 @@ public:
bool rmdir(const String& path, Inode& base, int& error);
bool chmod(const String& path, mode_t, Inode& base, int& error);
void register_character_device(CharacterDevice&);
void unregister_character_device(CharacterDevice&);
void register_device(Device&);
void unregister_device(Device&);
size_t mount_count() const { return m_mounts.size(); }
void for_each_mount(Function<void(const Mount&)>) const;
@ -85,7 +85,7 @@ public:
void sync();
CharacterDevice* get_device(unsigned major, unsigned minor);
Device* get_device(unsigned major, unsigned minor);
private:
friend class FileDescriptor;
@ -103,6 +103,6 @@ private:
RetainPtr<Inode> m_root_inode;
Vector<OwnPtr<Mount>> m_mounts;
HashMap<dword, CharacterDevice*> m_character_devices;
HashMap<dword, Device*> m_devices;
};

View file

@ -66,25 +66,25 @@ VFS* vfs;
Syscall::initialize();
auto dev_zero = make<ZeroDevice>();
vfs->register_character_device(*dev_zero);
vfs->register_device(*dev_zero);
vfs->register_character_device(*dev_null);
vfs->register_device(*dev_null);
auto dev_full = make<FullDevice>();
vfs->register_character_device(*dev_full);
vfs->register_device(*dev_full);
auto dev_random = make<RandomDevice>();
vfs->register_character_device(*dev_random);
vfs->register_device(*dev_random);
auto dev_ptmx = make<PTYMultiplexer>();
vfs->register_character_device(*dev_ptmx);
vfs->register_device(*dev_ptmx);
vfs->register_character_device(*keyboard);
vfs->register_character_device(*ps2mouse);
vfs->register_character_device(*tty0);
vfs->register_character_device(*tty1);
vfs->register_character_device(*tty2);
vfs->register_character_device(*tty3);
vfs->register_device(*keyboard);
vfs->register_device(*ps2mouse);
vfs->register_device(*tty0);
vfs->register_device(*tty1);
vfs->register_device(*tty2);
vfs->register_device(*tty3);
auto dev_hd0 = IDEDiskDevice::create();
auto e2fs = Ext2FS::create(dev_hd0.copy_ref());