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

Virtual consoles kinda work!

We now make three VirtualConsoles at boot: tty0, tty1, and tty2.
We launch an instance of /bin/sh in each one.
You switch between them with Alt+1/2/3

How very very cool :^)
This commit is contained in:
Andreas Kling 2018-10-30 15:33:37 +01:00
parent 68739dc43e
commit 7a7956a595
24 changed files with 251 additions and 103 deletions

View file

@ -6,5 +6,5 @@ CharacterDevice::~CharacterDevice()
OwnPtr<FileHandle> CharacterDevice::open(int options)
{
//VirtualFileSystem::the().open()
return VirtualFileSystem::the().open(*this, options);
}

View file

@ -101,6 +101,16 @@ Unix::ssize_t FileHandle::read(byte* buffer, Unix::size_t count)
return nread;
}
Unix::ssize_t FileHandle::write(const byte* data, Unix::size_t size)
{
if (m_vnode->isCharacterDevice()) {
// FIXME: What should happen to m_currentOffset?
return m_vnode->characterDevice()->write(data, size);
}
// FIXME: Implement non-device writes.
ASSERT_NOT_REACHED();
}
bool FileHandle::hasDataAvailableForRead()
{
if (m_vnode->isCharacterDevice())

View file

@ -10,7 +10,8 @@ public:
~FileHandle();
Unix::off_t seek(Unix::off_t, int whence);
Unix::ssize_t read(byte* buffer, Unix::size_t count);
Unix::ssize_t read(byte*, Unix::size_t);
Unix::ssize_t write(const byte* data, Unix::size_t);
int stat(Unix::stat*);
bool hasDataAvailableForRead();

View file

@ -89,6 +89,21 @@ auto VirtualFileSystem::makeNode(InodeIdentifier inode) -> RetainPtr<Node>
return vnode;
}
auto VirtualFileSystem::makeNode(CharacterDevice& device) -> RetainPtr<Node>
{
auto vnode = allocateNode();
ASSERT(vnode);
#ifdef VFS_DEBUG
kprintf("makeNode: device=%p (%u,%u)\n", &device, device.major(), device.minor());
#endif
m_device2vnode.set(encodedDevice(device.major(), device.minor()), vnode.ptr());
vnode->m_characterDevice = &device;
return vnode;
}
auto VirtualFileSystem::getOrCreateNode(InodeIdentifier inode) -> RetainPtr<Node>
{
auto it = m_inode2vnode.find(inode);
@ -97,6 +112,14 @@ auto VirtualFileSystem::getOrCreateNode(InodeIdentifier inode) -> RetainPtr<Node
return makeNode(inode);
}
auto VirtualFileSystem::getOrCreateNode(CharacterDevice& device) -> RetainPtr<Node>
{
auto it = m_device2vnode.find(encodedDevice(device.major(), device.minor()));
if (it != m_device2vnode.end())
return (*it).value;
return makeNode(device);
}
bool VirtualFileSystem::mount(RetainPtr<FileSystem>&& fileSystem, const String& path)
{
ASSERT(fileSystem);
@ -161,10 +184,15 @@ void VirtualFileSystem::freeNode(Node* node)
{
ASSERT(node);
ASSERT(node->inUse());
m_inode2vnode.remove(node->inode);
node->inode.fileSystem()->release();
node->inode = InodeIdentifier();
node->m_characterDevice = nullptr;
if (node->inode.isValid()) {
m_inode2vnode.remove(node->inode);
node->inode.fileSystem()->release();
node->inode = InodeIdentifier();
}
if (node->m_characterDevice) {
m_device2vnode.remove(encodedDevice(node->m_characterDevice->major(), node->m_characterDevice->minor()));
node->m_characterDevice = nullptr;
}
m_nodeFreeList.append(move(node));
}
@ -361,6 +389,14 @@ bool VirtualFileSystem::touch(const String& path)
return inode.fileSystem()->setModificationTime(inode, ktime(nullptr));
}
OwnPtr<FileHandle> VirtualFileSystem::open(CharacterDevice& device, int options)
{
auto vnode = getOrCreateNode(device);
if (!vnode)
return nullptr;
return make<FileHandle>(move(vnode));
}
OwnPtr<FileHandle> VirtualFileSystem::open(const String& path, int& error, int options, InodeIdentifier base)
{
auto inode = resolvePath(path, error, base, options);

View file

@ -51,7 +51,7 @@ public:
InodeIdentifier inode;
const InodeMetadata& metadata() const;
bool inUse() const { return inode.isValid(); }
bool inUse() const { return inode.isValid() || m_characterDevice; }
bool isCharacterDevice() const { return m_characterDevice; }
CharacterDevice* characterDevice() { return m_characterDevice; }
@ -91,6 +91,7 @@ public:
bool mountRoot(RetainPtr<FileSystem>&&);
bool mount(RetainPtr<FileSystem>&&, const String& path);
OwnPtr<FileHandle> open(CharacterDevice&, int options);
OwnPtr<FileHandle> open(const String& path, int& error, int options = 0, InodeIdentifier base = InodeIdentifier());
OwnPtr<FileHandle> create(const String& path, InodeIdentifier base = InodeIdentifier());
OwnPtr<FileHandle> mkdir(const String& path, InodeIdentifier base = InodeIdentifier());
@ -117,7 +118,9 @@ private:
void freeNode(Node*);
RetainPtr<Node> makeNode(InodeIdentifier);
RetainPtr<Node> makeNode(CharacterDevice&);
RetainPtr<Node> getOrCreateNode(InodeIdentifier);
RetainPtr<Node> getOrCreateNode(CharacterDevice&);
Mount* findMountForHost(InodeIdentifier);
Mount* findMountForGuest(InodeIdentifier);