summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2000-03-24 00:47:37 +0000
committerdillon <dillon@FreeBSD.org>2000-03-24 00:47:37 +0000
commitb61b444c79194d2675cbeba385cb08d69be69e38 (patch)
tree360e2d61fe4ef6e2e4b848b9e596cb8177f72c3d /sys
parent0de24417800f025245e0d5b69126cde77c52b276 (diff)
downloadFreeBSD-src-b61b444c79194d2675cbeba385cb08d69be69e38.zip
FreeBSD-src-b61b444c79194d2675cbeba385cb08d69be69e38.tar.gz
Fix in-kernel infinite loop in pipe_write() when the reader goes away
at just the wrong time.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_pipe.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index b82f91d..a181b5a 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -766,6 +766,9 @@ pipe_write(fp, uio, cred, flags, p)
* we do process-to-process copies directly.
* If the write is non-blocking, we don't use the
* direct write mechanism.
+ *
+ * The direct write mechanism will detect the reader going
+ * away on us.
*/
if ((uio->uio_iov->iov_len >= PIPE_MINDIRECT) &&
(fp->f_flag & FNONBLOCK) == 0 &&
@@ -783,7 +786,8 @@ pipe_write(fp, uio, cred, flags, p)
* Pipe buffered writes cannot be coincidental with
* direct writes. We wait until the currently executing
* direct write is completed before we start filling the
- * pipe buffer.
+ * pipe buffer. We break out if a signal occurs or the
+ * reader goes away.
*/
retrywrite:
while (wpipe->pipe_state & PIPE_DIRECTW) {
@@ -791,11 +795,16 @@ pipe_write(fp, uio, cred, flags, p)
wpipe->pipe_state &= ~PIPE_WANTR;
wakeup(wpipe);
}
- error = tsleep(wpipe,
- PRIBIO|PCATCH, "pipbww", 0);
+ error = tsleep(wpipe, PRIBIO|PCATCH, "pipbww", 0);
+ if (wpipe->pipe_state & PIPE_EOF)
+ break;
if (error)
break;
}
+ if (wpipe->pipe_state & PIPE_EOF) {
+ error = EPIPE;
+ break;
+ }
space = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt;
@@ -818,6 +827,9 @@ pipe_write(fp, uio, cred, flags, p)
/*
* If a process blocked in uiomove, our
* value for space might be bad.
+ *
+ * XXX will we be ok if the reader has gone
+ * away here?
*/
if (space > wpipe->pipe_buffer.size -
wpipe->pipe_buffer.cnt) {
OpenPOWER on IntegriCloud