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