diff --git a/kernel/src/net/Socket.h b/kernel/src/net/Socket.h index 5b980958..47c66807 100644 --- a/kernel/src/net/Socket.h +++ b/kernel/src/net/Socket.h @@ -69,6 +69,8 @@ class Socket : public VFS::FileInode virtual bool can_read_data() const = 0; + virtual bool peer_disconnected() const = 0; + virtual ~Socket() = default; protected: diff --git a/kernel/src/net/UnixSocket.h b/kernel/src/net/UnixSocket.h index 9ec88000..953947d6 100644 --- a/kernel/src/net/UnixSocket.h +++ b/kernel/src/net/UnixSocket.h @@ -27,6 +27,11 @@ class UnixSocket : public Socket return !m_listen_queue.is_empty(); } + bool peer_disconnected() const override + { + return m_state == Reset; + } + Result send(const u8*, usize, int) override; Result recv(u8*, usize, int) const override; diff --git a/kernel/src/sys/poll.cpp b/kernel/src/sys/poll.cpp index 7eab125a..38719fbe 100644 --- a/kernel/src/sys/poll.cpp +++ b/kernel/src/sys/poll.cpp @@ -48,6 +48,9 @@ Result sys_poll(Registers*, SyscallArgs args) if (kfds[i].events & POLLIN) { + fds_with_events++; + kfds[i].revents |= POLLIN; + if (inode->type() == VFS::InodeType::Socket) { auto socket = (Socket*)inode.ptr(); @@ -56,6 +59,11 @@ Result sys_poll(Registers*, SyscallArgs args) fds_with_events++; kfds[i].revents |= POLLIN; } + if (socket->peer_disconnected()) + { + fds_with_events++; + kfds[i].revents |= POLLHUP; + } } else { diff --git a/libc/include/bits/poll.h b/libc/include/bits/poll.h index 35600ed8..e0c6b84a 100644 --- a/libc/include/bits/poll.h +++ b/libc/include/bits/poll.h @@ -8,6 +8,7 @@ #define POLLIN (1 << 0) #define POLLERR (1 << 1) #define POLLNVAL (1 << 2) +#define POLLHUP (1 << 3) typedef __u64_t nfds_t;