summaryrefslogtreecommitdiff
path: root/libc/stdio/stdio.c
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2001-07-28 14:51:45 +0000
committerManuel Novoa III <mjn3@codepoet.org>2001-07-28 14:51:45 +0000
commitb52f66dea69ecc8e8b7d1b89226438f9ce260fb7 (patch)
treefbfcf9ee76256bf13a81d7ede907ba5b2e2835af /libc/stdio/stdio.c
parent2940feb06f1a92841121b223063b123c3fae11a0 (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/stdio.c')
-rw-r--r--libc/stdio/stdio.c43
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;
}
}
}