unbuffered fread() problem

Jason Tishler jason@tishler.net
Tue Oct 26 18:22:00 GMT 2004


While running the Cygwin Python 2.4b1 regression test, I uncovered a
newlib unbuffered fread() problem.  The first attachment, ut.cc, is a
test case that demonstrates the issue:

    $ echo -n 0 >/tmp/foo
    ut /tmp/foo 1
    count = 1023
    buffer = (0$)

Hence, one can see that fread() in unbuffered mode always returns the
specified count instead of the number of elements actually read.

The second attachment is a "patch" that "fixes" the problem.  I'm using
the words "patch" and "fixes" loosely because although the problem is
corrected, this may not be the best approach.  Since I'm not that
familiar with newlib, I'm also concerned this patch may even cause other
unforeseen problems.  Anyway, the patch should at least point one more
familiar with newlib to the specific part of the code that needs rework.

Thanks,
Jason

-- 
PGP/GPG Key: http://www.tishler.net/jason/pubkey.asc or key servers
Fingerprint: 7A73 1405 7F2B E669 C19D  8784 1AFD E4CC ECF4 8EF6
-------------- next part --------------
#include <stdio.h>

int
main(int argc, char* argv[])
{
	const char* filename = argv[1];
	FILE* file = fopen(filename, "r");
	if (!file)
	{
		printf("fopen(%s) failed\n", filename);
		return 1;
	}

	if (argc == 3)
		setvbuf(file, 0, _IONBF, 0);

	char buffer[1024];
	size_t count = fread(buffer, 1, sizeof(buffer) - 1, file);
	if (count == 0)
	{
		printf("fread failed\n");
		return 1;
	}
	buffer[count] = '\0';

	printf("count = %d\n", count);
	printf("buffer = (%s)\n", buffer);

	return 0;
}
-------------- next part --------------
Index: fread.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/fread.c,v
retrieving revision 1.7
diff -u -p -r1.7 fread.c
--- fread.c	24 Sep 2004 09:13:11 -0000	1.7
+++ fread.c	26 Oct 2004 13:00:39 -0000
@@ -167,19 +167,15 @@ _DEFUN(fread, (buf, size, count, fp),
 	  fp->_bf._base = old_base;
 	  fp->_bf._size = old_size;
 	  fp->_p = old_p;
-	  if (rc)
-	    {
-	      /* no more input: return partial result */
 #ifdef __SCLE
-	      if (fp->_flags & __SCLE)
-		{
-		  _funlockfile (fp);
-		  return crlf (fp, buf, total-resid, 1) / size;
-		}
-#endif
+	  if (fp->_flags & __SCLE)
+	    {
 	      _funlockfile (fp);
-	      return (total - resid) / size;
+	      return crlf (fp, buf, total-resid, 1) / size;
 	    }
+#endif
+	  _funlockfile (fp);
+	  return (total - resid) / size;
 	}
     }
   else


More information about the Newlib mailing list