summaryrefslogtreecommitdiff
path: root/Kernel/PTYMultiplexer.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-16 13:36:10 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-16 13:39:32 +0100
commit9dd29f9aa97260c46e28ea40b987e3afb65c7251 (patch)
treea133f43f81edd841ef56acf5cdc4c5a09d469880 /Kernel/PTYMultiplexer.cpp
parentb46ae2bf094f8c1f59f117ded5c224980536de9f (diff)
downloadserenity-9dd29f9aa97260c46e28ea40b987e3afb65c7251.zip
Add a PTY multiplexer (/dev/ptmx) device.
When you open /dev/ptmx, you get a file descriptor pointing to one of the available MasterPTY's. If none are available, you get an EBUSY. This makes it possible to open multiple (up to 4) Terminals. :^) To support this, I also added a CharacterDevice::open() that gets control when VFS is opening a CharacterDevice. This is useful when we want to return a custom FileDescriptor like we do here.
Diffstat (limited to 'Kernel/PTYMultiplexer.cpp')
-rw-r--r--Kernel/PTYMultiplexer.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/Kernel/PTYMultiplexer.cpp b/Kernel/PTYMultiplexer.cpp
new file mode 100644
index 0000000000..26403e898c
--- /dev/null
+++ b/Kernel/PTYMultiplexer.cpp
@@ -0,0 +1,27 @@
+#include "PTYMultiplexer.h"
+#include "MasterPTY.h"
+#include <LibC/errno_numbers.h>
+
+PTYMultiplexer::PTYMultiplexer()
+ : CharacterDevice(5, 2)
+{
+ m_freelist.ensureCapacity(4);
+ for (int i = 4; i > 0; --i)
+ m_freelist.unchecked_append(adopt(*new MasterPTY(i - 1)));
+}
+
+PTYMultiplexer::~PTYMultiplexer()
+{
+}
+
+RetainPtr<FileDescriptor> PTYMultiplexer::open(int& error, int options)
+{
+ LOCKER(m_lock);
+ if (m_freelist.is_empty()) {
+ error = -EBUSY;
+ return nullptr;
+ }
+ auto master = m_freelist.takeLast();
+ dbgprintf("PTYMultiplexer::open: Vending master %u\n", master->index());
+ return VFS::the().open(move(master), error, options);
+}