Fix in-kernel infinite loop in pipe_write() when the reader goes away

at just the wrong time.
This commit is contained in:
dillon 2000-03-24 00:47:37 +00:00
parent 0de2441780
commit b61b444c79

View File

@ -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) {