diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-02-05 12:27:32 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-02-05 12:27:32 +0100 |
commit | 378e20c535a3f8b7f6f5519a1a3fe6b1c4949a12 (patch) | |
tree | ccc97448aafbcf3fd4aeb03fd7d90bef70d9ca34 | |
parent | 3accdb0e93eeb90898b3fd1b15e733163461d29b (diff) | |
download | serenity-378e20c535a3f8b7f6f5519a1a3fe6b1c4949a12.zip |
Kernel: Reading from a slave PTY should give EOF if master PTY is closed.
-rw-r--r-- | Kernel/MasterPTY.cpp | 9 | ||||
-rw-r--r-- | Kernel/MasterPTY.h | 15 | ||||
-rw-r--r-- | Kernel/SlavePTY.cpp | 14 | ||||
-rw-r--r-- | Kernel/SlavePTY.h | 2 | ||||
-rw-r--r-- | Userland/sh.cpp | 2 |
5 files changed, 35 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; diff --git a/Userland/sh.cpp b/Userland/sh.cpp index 0fc4ee4642..0e49297420 100644 --- a/Userland/sh.cpp +++ b/Userland/sh.cpp @@ -410,6 +410,8 @@ int main(int argc, char** argv) for (;;) { char keybuf[16]; ssize_t nread = read(0, keybuf, sizeof(keybuf)); + if (nread == 0) + return 0; if (nread < 0) { if (errno == EINTR) { ASSERT(g->was_interrupted); |