diff options
author | Chris Johns <chrisj@rtems.org> | 2013-12-10 12:33:22 +1100 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2013-12-10 12:33:22 +1100 |
commit | 9da8740f05cdf5cd6d685c2c0db2350345aa966d (patch) | |
tree | e7a93132c69c05e00402ba76906f17fd9df2ac6a /cpukit/libfs/src/pipe | |
parent | libfs/imfs: Set the FIFO control block. (diff) | |
download | rtems-9da8740f05cdf5cd6d685c2c0db2350345aa966d.tar.bz2 |
PR2159: Have the FIFO driver read follow POSIX standard.
The read call was only returning once the requested buffer was full.
The change returns any available data.
Diffstat (limited to 'cpukit/libfs/src/pipe')
-rw-r--r-- | cpukit/libfs/src/pipe/fifo.c | 84 |
1 files changed, 41 insertions, 43 deletions
diff --git a/cpukit/libfs/src/pipe/fifo.c b/cpukit/libfs/src/pipe/fifo.c index e31ee7c5bf..29f300f151 100644 --- a/cpukit/libfs/src/pipe/fifo.c +++ b/cpukit/libfs/src/pipe/fifo.c @@ -390,54 +390,52 @@ ssize_t pipe_read( if (! PIPE_LOCK(pipe)) return -EINTR; - while (read < count) { - while (PIPE_EMPTY(pipe)) { - /* Not an error */ - if (pipe->Writers == 0) - goto out_locked; - - if (LIBIO_NODELAY(iop)) { - ret = -EAGAIN; - goto out_locked; - } - - /* Wait until pipe is no more empty or no writer exists */ - pipe->waitingReaders ++; - PIPE_UNLOCK(pipe); - if (! PIPE_READWAIT(pipe)) - ret = -EINTR; - if (! PIPE_LOCK(pipe)) { - /* WARN waitingReaders not restored! */ - ret = -EINTR; - goto out_nolock; - } - pipe->waitingReaders --; - if (ret != 0) - goto out_locked; + while (PIPE_EMPTY(pipe)) { + /* Not an error */ + if (pipe->Writers == 0) + goto out_locked; + + if (LIBIO_NODELAY(iop)) { + ret = -EAGAIN; + goto out_locked; } - /* Read chunk bytes */ - chunk = MIN(count - read, pipe->Length); - chunk1 = pipe->Size - pipe->Start; - if (chunk > chunk1) { - memcpy(buffer + read, pipe->Buffer + pipe->Start, chunk1); - memcpy(buffer + read + chunk1, pipe->Buffer, chunk - chunk1); + /* Wait until pipe is no more empty or no writer exists */ + pipe->waitingReaders ++; + PIPE_UNLOCK(pipe); + if (! PIPE_READWAIT(pipe)) + ret = -EINTR; + if (! PIPE_LOCK(pipe)) { + /* WARN waitingReaders not restored! */ + ret = -EINTR; + goto out_nolock; } - else - memcpy(buffer + read, pipe->Buffer + pipe->Start, chunk); - - pipe->Start += chunk; - pipe->Start %= pipe->Size; - pipe->Length -= chunk; - /* For buffering optimization */ - if (PIPE_EMPTY(pipe)) - pipe->Start = 0; - - if (pipe->waitingWriters > 0) - PIPE_WAKEUPWRITERS(pipe); - read += chunk; + pipe->waitingReaders --; + if (ret != 0) + goto out_locked; } + /* Read chunk bytes */ + chunk = MIN(count - read, pipe->Length); + chunk1 = pipe->Size - pipe->Start; + if (chunk > chunk1) { + memcpy(buffer + read, pipe->Buffer + pipe->Start, chunk1); + memcpy(buffer + read + chunk1, pipe->Buffer, chunk - chunk1); + } + else + memcpy(buffer + read, pipe->Buffer + pipe->Start, chunk); + + pipe->Start += chunk; + pipe->Start %= pipe->Size; + pipe->Length -= chunk; + /* For buffering optimization */ + if (PIPE_EMPTY(pipe)) + pipe->Start = 0; + + if (pipe->waitingWriters > 0) + PIPE_WAKEUPWRITERS(pipe); + read += chunk; + out_locked: PIPE_UNLOCK(pipe); |