diff options
author | dillon <dillon@FreeBSD.org> | 2000-03-24 00:47:37 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2000-03-24 00:47:37 +0000 |
commit | b61b444c79194d2675cbeba385cb08d69be69e38 (patch) | |
tree | 360e2d61fe4ef6e2e4b848b9e596cb8177f72c3d /sys | |
parent | 0de24417800f025245e0d5b69126cde77c52b276 (diff) | |
download | FreeBSD-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.c | 18 |
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) { |