summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/MasterPTY.cpp9
-rw-r--r--Kernel/MasterPTY.h15
-rw-r--r--Kernel/SlavePTY.cpp14
-rw-r--r--Kernel/SlavePTY.h2
4 files changed, 33 insertions, 7 deletions
diff --git a/Kernel/MasterPTY.cpp b/Kernel/MasterPTY.cpp
index f1a88103d3..40511ac501 100644
--- a/Kernel/MasterPTY.cpp
+++ b/Kernel/MasterPTY.cpp
@@ -69,3 +69,12 @@ bool MasterPTY::can_write_from_slave() const
{
return m_buffer.bytes_in_write_buffer() < 4096;
}
+
+void MasterPTY::close()
+{
+ if (retain_count() == 2) {
+ // After the closing FileDescriptor dies, slave is the only thing keeping me alive.
+ // From this point, let's consider ourselves closed.
+ m_closed = true;
+ }
+}
diff --git a/Kernel/MasterPTY.h b/Kernel/MasterPTY.h
index 29d7106927..7f2ebbaf02 100644
--- a/Kernel/MasterPTY.h
+++ b/Kernel/MasterPTY.h
@@ -11,24 +11,25 @@ public:
explicit MasterPTY(unsigned index);
virtual ~MasterPTY() override;
- // ^CharacterDevice
- virtual ssize_t read(Process&, byte*, size_t) override;
- virtual ssize_t write(Process&, const byte*, size_t) override;
- virtual bool can_read(Process&) const override;
- virtual bool can_write(Process&) const override;
- virtual bool is_master_pty() const override { return true; }
-
unsigned index() const { return m_index; }
String pts_name() const;
void on_slave_write(const byte*, size_t);
bool can_write_from_slave() const;
void notify_slave_closed(Badge<SlavePTY>);
+ bool is_closed() const { return m_closed; }
private:
// ^CharacterDevice
+ virtual ssize_t read(Process&, byte*, size_t) override;
+ virtual ssize_t write(Process&, const byte*, size_t) override;
+ virtual bool can_read(Process&) const override;
+ virtual bool can_write(Process&) const override;
+ virtual void close() override;
+ virtual bool is_master_pty() const override { return true; }
virtual const char* class_name() const override { return "MasterPTY"; }
RetainPtr<SlavePTY> m_slave;
unsigned m_index;
+ bool m_closed { false };
DoubleBuffer m_buffer;
};
diff --git a/Kernel/SlavePTY.cpp b/Kernel/SlavePTY.cpp
index f5c0b1872a..651c4d82cf 100644
--- a/Kernel/SlavePTY.cpp
+++ b/Kernel/SlavePTY.cpp
@@ -43,6 +43,20 @@ bool SlavePTY::can_write(Process&) const
return m_master->can_write_from_slave();
}
+bool SlavePTY::can_read(Process& process) const
+{
+ if (m_master->is_closed())
+ return true;
+ return TTY::can_read(process);
+}
+
+ssize_t SlavePTY::read(Process& process, byte* buffer, size_t size)
+{
+ if (m_master->is_closed())
+ return 0;
+ return TTY::read(process, buffer, size);
+}
+
void SlavePTY::close()
{
m_master->notify_slave_closed(Badge<SlavePTY>());
diff --git a/Kernel/SlavePTY.h b/Kernel/SlavePTY.h
index 4768a707a5..9aae22e373 100644
--- a/Kernel/SlavePTY.h
+++ b/Kernel/SlavePTY.h
@@ -20,6 +20,8 @@ private:
virtual void on_tty_write(const byte*, size_t) override;
// ^CharacterDevice
+ virtual bool can_read(Process&) const override;
+ virtual ssize_t read(Process&, byte*, size_t) override;
virtual bool can_write(Process&) const override;
virtual const char* class_name() const override { return "SlavePTY"; }
virtual void close() override;