فهرست منبع

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 سال پیش
والد
کامیت
b52f66dea6
1فایلهای تغییر یافته به همراه21 افزوده شده و 22 حذف شده
  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;
 			}
 		}
 	}