Browse Source

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.

Manuel Novoa III 24 năm trước cách đây
mục cha
commit
b52f66dea6
1 tập tin đã thay đổi với 21 bổ sung22 xóa
  1. 21 22
      libc/stdio/stdio.c

+ 21 - 22
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;
 			}
 		}
 	}