From b5ffaefa45b7a2057b605500a55a30748f07be43 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 12 Apr 2026 22:13:10 -0300 Subject: [PATCH] pipefs: better nonblocking named fifo open() handling --- kernel-src/fs/pipefs.c | 11 ++++++++--- kernel-src/include/kernel/pipefs.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/kernel-src/fs/pipefs.c b/kernel-src/fs/pipefs.c index d88cfa34..e8120ebd 100644 --- a/kernel-src/fs/pipefs.c +++ b/kernel-src/fs/pipefs.c @@ -40,6 +40,9 @@ int pipefs_close(vnode_t *node, int flags, cred_t *cred) { if (pipenode->writers == 0) poll_event(&pipenode->pollheader, POLLHUP); + if (pipenode->writers == 0 && pipenode->readers == 0) + pipenode->open = false; + INTERNAL_UNLOCK(node); return 0; } @@ -61,8 +64,10 @@ int pipefs_open(vnode_t **node, int flags, cred_t *cred) { int error = 0; - if (pipenode->writers > 0 && pipenode->readers > 0) + if (pipenode->writers > 0 && pipenode->readers > 0) { + pipenode->open = true; goto leave; + } if (flags & V_FFLAGS_NONBLOCKING) { if (flags & V_FFLAGS_READ) { @@ -110,7 +115,7 @@ static int internalpoll(vnode_t *node, polldata_t *data, int events) { if (events & POLLIN) { events |= POLLHUP; - if (pipenode->writers == 0) + if (pipenode->writers == 0 && pipenode->open) revents |= POLLHUP; else if (RINGBUFFER_DATACOUNT(&pipenode->data) > 0) revents |= POLLIN; @@ -118,7 +123,7 @@ static int internalpoll(vnode_t *node, polldata_t *data, int events) { if (events & POLLOUT) { events |= POLLERR; - if (pipenode->readers == 0) + if (pipenode->readers == 0 && pipenode->open) revents |= POLLERR; // poll will only return POLLOUT if an atomic write can be done without blocking // this is undocumented in POSIX but many unices implement it like this diff --git a/kernel-src/include/kernel/pipefs.h b/kernel-src/include/kernel/pipefs.h index 2b95b480..aae5be32 100644 --- a/kernel-src/include/kernel/pipefs.h +++ b/kernel-src/include/kernel/pipefs.h @@ -12,6 +12,7 @@ typedef struct pipenode_t { vattr_t attr; ringbuffer_t data; size_t readers, writers; + bool open; pollheader_t pollheader; eventheader_t readopenevent; eventheader_t writeopenevent;