Kernel: Reading from a slave PTY should give EOF if master PTY is closed.

This commit is contained in:
Andreas Kling 2019-02-05 12:27:32 +01:00
parent 3accdb0e93
commit 378e20c535
Notes: sideshowbarker 2024-07-19 15:51:29 +09:00
5 changed files with 35 additions and 7 deletions

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -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>());

View File

@ -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;

View File

@ -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);