aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/sys_pipe.c
diff options
context:
space:
mode:
authorMatthew Dillon <dillon@FreeBSD.org>2000-03-24 00:47:37 +0000
committerMatthew Dillon <dillon@FreeBSD.org>2000-03-24 00:47:37 +0000
commitf1924a54f82340bd3ffe1da32e523a76ed1b3fec (patch)
tree64c8bb6e3d391367d9e1dac950dc50bab8fa150a /sys/kern/sys_pipe.c
parentb541ae06bd1047ad98f175e552cf9e365e4da070 (diff)
downloadsrc-f1924a54f82340bd3ffe1da32e523a76ed1b3fec.tar.gz
src-f1924a54f82340bd3ffe1da32e523a76ed1b3fec.zip
Fix in-kernel infinite loop in pipe_write() when the reader goes away
at just the wrong time.
Notes
Notes: svn path=/head/; revision=58505
Diffstat (limited to 'sys/kern/sys_pipe.c')
-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 b82f91d5e6dd..a181b5a70e49 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) {