diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-02-12 00:22:29 -0500 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-02-12 00:22:29 -0500 |
commit | 0b44a0315b47dd8eced9f3b7f31580cf14bbfc01 (patch) | |
tree | 6eaef0d8a720fa3da580de87b647fff796fe80b3 /src/stdio/__underflow.c | |
download | musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.tar.gz musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.tar.xz musl-0b44a0315b47dd8eced9f3b7f31580cf14bbfc01.zip |
initial check-in, version 0.5.0 v0.5.0
Diffstat (limited to 'src/stdio/__underflow.c')
-rw-r--r-- | src/stdio/__underflow.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/stdio/__underflow.c b/src/stdio/__underflow.c new file mode 100644 index 00000000..b769f4e4 --- /dev/null +++ b/src/stdio/__underflow.c @@ -0,0 +1,38 @@ +#include "stdio_impl.h" + +int __underflow(FILE *f) +{ + ssize_t cnt; + + /* Read from buffer (Do we ever get called when this is true??) */ + if (f->rpos < f->rstop) return *f->rpos; + + /* Initialize if we're not already reading */ + if (!f->rstop) { + /* Fail immediately if unreadable, eof, or error state. */ + if (f->flags & (F_EOF|F_ERR|F_NORD)) return EOF; + + /* Set byte orientation -1,0=>-1; 1=>1 */ + f->mode |= f->mode-1; + + /* Flush any unwritten output; fail on error. */ + if (f->wpos > f->buf && __oflow(f)) return EOF; + + /* Disallow writes to buffer. */ + f->wstop = 0; + } + + /* Perform the underlying read operation */ + if ((cnt=f->read(f, f->buf, f->buf_size)) + 1 <= 1) { + /* Set flags and leave read mode */ + f->flags |= F_EOF | (cnt & F_ERR); + f->rpos = f->rend = f->rstop = 0; + return EOF; + } + + /* Setup buffer pointers for reading from buffer */ + f->rpos = f->buf; + f->rend = f->rstop = f->buf + cnt; + + return *f->rpos; +} |