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<-------------