Reading from pipe is allowed to return short count
MODIFY
bin/utest/fd.c
bin/utest/fd.c
@@ -171,12 +171,12 @@ int test_fd_pipe() {
assert(pid >= 0);
if (pid > 0) {
- /* child */
+ /* parent */
assert_close_ok(fd[0]);
assert_write_ok(fd[1], str, strlen(str));
assert_close_ok(fd[1]);
} else {
- /* parent */
+ /* child */
assert_close_ok(fd[1]);
assert_read_equal(fd[0], buf, str);
assert_close_ok(fd[0]);

MODIFY
sys/kern/pipe.c
sys/kern/pipe.c
@@ -77,20 +77,25 @@ static int pipe_read(file_t *f, uio_t *uio) {
assert(!consumer->closed);
+ /* user requested read of 0 bytes */
+ if (uio->uio_resid == 0)
+ return 0;
+
/* no read atomicity for now! */
WITH_MTX_LOCK (&producer->mtx) {
- do {
+ /* pipe empty, no producers, return end-of-file */
+ if (ringbuf_empty(&producer->buf) && producer->closed)
+ return 0;
+
+ /* pipe empty, producer exists, wait for data */
+ while (ringbuf_empty(&producer->buf) && !producer->closed)
+ cv_wait(&producer->nonempty, &producer->mtx);
+
int res = ringbuf_read(&producer->buf, uio);
if (res)
return res;
/* notify producer that free space is available */
cv_broadcast(&producer->nonfull);
- /* nothing left to read? */
- if (uio->uio_resid == 0)
- break;
- /* the buffer is empty so wait for some data to be produced */
- cv_wait(&producer->nonempty, &producer->mtx);
- } while (!producer->closed);
}
return 0;

Reading from pipe is allowed to return short count (#576)