summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Lindqvist <anton@cvs.openbsd.org>2021-10-22 05:00:27 +0000
committerAnton Lindqvist <anton@cvs.openbsd.org>2021-10-22 05:00:27 +0000
commit4b6a4f1ef6c2d0a672ed465689b28134fc20b425 (patch)
tree2f24bc75c76474792df39a62d74a934a7936fb49
parentde369469f2dff362fca8a2479be7527e7160440e (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.c23
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;
}