diff options
author | Manuel Novoa III <mjn3@codepoet.org> | 2001-07-28 14:51:45 +0000 |
---|---|---|
committer | Manuel Novoa III <mjn3@codepoet.org> | 2001-07-28 14:51:45 +0000 |
commit | b52f66dea69ecc8e8b7d1b89226438f9ce260fb7 (patch) | |
tree | fbfcf9ee76256bf13a81d7ede907ba5b2e2835af /libc/stdio | |
parent | 2940feb06f1a92841121b223063b123c3fae11a0 (diff) |
Back out the changes to _uClibc_fread and loop in fread() if incomplete, to
avoid problems with fgets on tty streams. I actually did some testing this
time. ;-)
Note: there is a difference in behavior between glibc and uClibc here
regarding fread() on a tty stream. glibc's fread() seems to return after
reading all _available_ data even if not at end-of-file, while uClibc's
fread() continues reading until all requested or eof or error. The latter
behavior seems correct w.r.t. the standards.
Diffstat (limited to 'libc/stdio')
-rw-r--r-- | libc/stdio/stdio.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c index 09a1a5571..87c27275a 100644 --- a/libc/stdio/stdio.c +++ b/libc/stdio/stdio.c @@ -368,14 +368,18 @@ size_t size; size_t nelm; FILE *fp; { - off_t bytes; - -#warning TODO: handle possible overflow for bytes - bytes = size * nelm; /* How many bytes do we want? */ + unsigned char *p; + unsigned char *q; - bytes = _uClibc_fread((unsigned char *)buf, bytes, fp); +#warning TODO: handle possible overflow of size * nelm + p = (unsigned char *) buf; + q = p + (size * nelm); - return bytes/size; + while ((p < q) && !EOF_OR_ERROR(fp)) { + fprintf(stderr,"X\n"); + p += _uClibc_fread(p, q - p, fp); + } + return (p - (unsigned char *) buf)/size; } #endif @@ -420,25 +424,20 @@ off_t _uClibc_fread(unsigned char *buf, off_t bytes, FILE *fp) fp->bufpos = fp->bufread = fp->bufstart; /* Reset pointers. */ fp->bufread += _uClibc_fread(fp->bufstart, fp->bufend - fp->bufstart, fp); - if (fp->bufread - fp->bufstart >= bytes) { /* If we read all */ - fp->mode &= ~__MODE_EOF; /* that was requested, make sure */ - } /* EOF flag is clear. */ goto FROM_BUF; } - while (bytes) { - if ((len = read(fp->fd, p, (unsigned) bytes)) < 0) { - if (errno != EINTR) { /* We weren't interrupted, so error. */ - fp->mode |= __MODE_ERR; - break; - } - } else { - if (len == 0) { - fp->mode |= __MODE_EOF; - break; - } - bytes -= len; - p += len; + TRY_READ: + len = read(fp->fd, p, (unsigned) bytes); + if (len < 0) { + if (errno == EINTR) { /* We were interrupted, so try again. */ + goto TRY_READ; + } + fp->mode |= __MODE_ERR; + } else { + p += len; + if (len == 0) { + fp->mode |= __MODE_EOF; } } } |