Bug in MSVCRT_fseek (with patch)

Erik de Castro Lopo mle+win at mega-nerd.com
Fri Apr 4 06:03:35 CDT 2008


Hi all,

I think I have found a bug in MSVCRT_fseek. If I fread() to the end
of a file, then do fseek (file, 0, SEEK_SET), the feof() function
still returns true.

According to the ISO standard

  A successful call to fseek() shall clear the end-of-file indicator
  for the stream and undo any effects of ungetc() and ungetwc() on
  the same stream. After an fseek() call, the next operation on an
  update stream may be either input or output.

The following patch to dlls/msvcrt/file.c fixes the issue. I also
have a small standalone test program below that fails before the
patch and passes after.

Cheers,
Erik

The patch:
-------------8<-------------8<-------------8<-------------8<-------------
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -918,6 +918,8 @@ int CDECL MSVCRT_fseek(MSVCRT_FILE* file, long offset, int whence)
   if(file->_flag & MSVCRT__IORW) {
         file->_flag &= ~(MSVCRT__IOREAD|MSVCRT__IOWRT);
   }
+  /* Clear end of file */
+  file->_flag &= ~MSVCRT__IOEOF;
   return (_lseek(file->_file,offset,whence) == -1)?-1:0;
 }
 
-------------8<-------------8<-------------8<-------------8<-------------

The test program:
-------------8<-------------8<-------------8<-------------8<-------------
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

static void
error_exit (const char * fmt, ...)
{
	va_list ap ;
	va_start (ap,  fmt) ;
	vprintf (fmt, ap) ;
	va_end (ap) ;

	exit (1) ;
} /* error_exit */

int
main (void)
{	const char * filename = "test.dat" ;
	char buffer [12] ;
	FILE * file ;

	/* Create a short data file. */
	if ((file = fopen (filename, "w")) == NULL)
		error_exit ("Error on line %d : fopen\n", __LINE__) ;
	fputs("abcdefghaiklmnopqrstuvwxyz\n", file) ;
	fclose (file) ;

	/* Now read the file. */
	if ((file = fopen (filename, "r")) == NULL)
		error_exit ("Line %d : fopen\n", __LINE__) ;

	while (fread (buffer, sizeof (buffer), 1, file) > 0)
		(void) 0 ;

	if (! feof (file))
		error_exit ("Error on line %d : feof should return true.\n", __LINE__) ;

	fseek (file, 0, SEEK_SET) ;

	if (feof (file))
		error_exit ("Error on line %d : feof should return false.\n", __LINE__) ;

	fclose (file) ;

	remove (filename) ;

	return 0 ;
} /* main */
-------------8<-------------8<-------------8<-------------8<-------------

-- 
-----------------------------------------------------------------
Erik de Castro Lopo
-----------------------------------------------------------------
"C++ has its place in the history of programming languages. Just
as Caligula has his place in the history of the Roman Empire."
-- Robert Firth



More information about the wine-devel mailing list