diff options
author | Anton Lindqvist <anton@cvs.openbsd.org> | 2021-10-22 05:00:27 +0000 |
---|---|---|
committer | Anton Lindqvist <anton@cvs.openbsd.org> | 2021-10-22 05:00:27 +0000 |
commit | 4b6a4f1ef6c2d0a672ed465689b28134fc20b425 (patch) | |
tree | 2f24bc75c76474792df39a62d74a934a7936fb49 | |
parent | de369469f2dff362fca8a2479be7527e7160440e (diff) |
Preserve pipe select(2) semantics when the other end of the pipe is gone.
In preparation for implementing select(2) on top of kqueue.
ok mpi@
-rw-r--r-- | sys/kern/sys_pipe.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index f9bae89aa46..fa855710712 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_pipe.c,v 1.126 2020/12/30 17:02:32 visa Exp $ */ +/* $OpenBSD: sys_pipe.c,v 1.127 2021/10/22 05:00:26 anton Exp $ */ /* * Copyright (c) 1996 John S. Dyson @@ -890,16 +890,27 @@ pipe_kqfilter(struct file *fp, struct knote *kn) kn->kn_hook = rpipe; klist_insert_locked(&rpipe->pipe_sel.si_note, kn); break; - case EVFILT_WRITE: + case EVFILT_WRITE: { + struct pipe *kpipe = wpipe; + if (wpipe == NULL) { /* other end of pipe has been closed */ - error = EPIPE; - break; + if (kn->kn_flags & __EV_POLL) { + /* + * select(2) semantics requires the pipe to + * become ready only to deliver EPIPE. + */ + kpipe = rpipe; + } else { + error = EPIPE; + break; + } } kn->kn_fop = &pipe_wfiltops; - kn->kn_hook = wpipe; - klist_insert_locked(&wpipe->pipe_sel.si_note, kn); + kn->kn_hook = kpipe; + klist_insert_locked(&kpipe->pipe_sel.si_note, kn); break; + } default: error = EINVAL; } |