Index: sys/kern/sys_pipe.c =================================================================== --- sys/kern/sys_pipe.c +++ sys/kern/sys_pipe.c @@ -724,7 +724,7 @@ rpipe->pipe_map.pos += size; rpipe->pipe_map.cnt -= size; if (rpipe->pipe_map.cnt == 0) { - rpipe->pipe_state &= ~(PIPE_DIRECTW|PIPE_WANTW); + rpipe->pipe_state &= ~PIPE_WANTW; wakeup(rpipe); } #endif @@ -862,6 +862,7 @@ { PIPE_LOCK_ASSERT(wpipe, MA_OWNED); + wpipe->pipe_state &= ~PIPE_DIRECTW; vm_page_unhold_pages(wpipe->pipe_map.ms, wpipe->pipe_map.npages); wpipe->pipe_map.npages = 0; } @@ -925,7 +926,7 @@ pipeunlock(wpipe); goto error1; } - while (wpipe->pipe_state & PIPE_DIRECTW) { + if (wpipe->pipe_state & PIPE_DIRECTW) { if (wpipe->pipe_state & PIPE_WANTR) { wpipe->pipe_state &= ~PIPE_WANTR; wakeup(wpipe); @@ -968,8 +969,7 @@ goto error1; } - error = 0; - while (!error && (wpipe->pipe_state & PIPE_DIRECTW)) { + for (error = 0; error == 0 && wpipe->pipe_map.cnt != 0; ) { if (wpipe->pipe_state & PIPE_EOF) { pipe_destroy_write_buffer(wpipe); pipeselwakeup(wpipe); @@ -991,15 +991,10 @@ if (wpipe->pipe_state & PIPE_EOF) error = EPIPE; - if (wpipe->pipe_state & PIPE_DIRECTW) { - /* - * this bit of trickery substitutes a kernel buffer for - * the process that might be going away. - */ + if (error == EINTR || error == ERESTART) pipe_clone_write_buffer(wpipe); - } else { + else pipe_destroy_write_buffer(wpipe); - } pipeunlock(wpipe); return (error);