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:
parent
68739dc43e
commit
7a7956a595
24 changed files with 251 additions and 103 deletions
|
@ -6,5 +6,5 @@ CharacterDevice::~CharacterDevice()
|
|||
|
||||
OwnPtr<FileHandle> CharacterDevice::open(int options)
|
||||
{
|
||||
//VirtualFileSystem::the().open()
|
||||
return VirtualFileSystem::the().open(*this, options);
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue