10 years, 5 months ago.

LocalFileSystem fseek bug

I have run into a problem with fseek.

I am using fseek with SEEK_SET. Sometimes, the fseek appears to be ignored (with no error indication) resulting in incorrect bytes then being returned from file by fgetc (or incorrectly getting EOF).

I have not worked out the exact circumstances, but I first encountered it when I did the following:

fseek(fp,12,SEEK_SET );

fgetc(fp); correctly gave byte from offset 12 in file

fseek(fp,12,SEEK_SET ); reposition to offset 12

fgetc(fp); incorrectly gave byte from offset 13 in file

Where it seems like the second fseek was ignored. If, instead of reading only one byte after the first fseek, I read two bytes (say) then I did not see the problem. If the one byte read by the first fgetc happened to be the last byte of the file, then the second fgetc was returning EOF even though the second fseek tried to move elsewhere.

If it matters, this is on LPC11U24.

Test program:

main.cpp

include "mbed.h"

LocalFileSystem SeqFile("Local");

FILE    *fp;

void fseeker(int o,int n)
{
  int8_t i,j,k;
  for (i=0; i<2; i++)
    {
      if ( fseek(fp,o,SEEK_SET ) )  printf( "fseeker: fseek  failed\r\n" );
      printf("fseek to offset %d and fgetc returns:",o);
      for (j=0; j<n; j++) 
        {
          k=fgetc(fp);
          printf(" %d",k);
          if ( k != (o+j) && !( k == EOF && o+j > 15) ) printf("(wrong!)");
        }  
      printf("\r\n");
    }  
}  

int main()
{

    int8_t  i,j;

    // create small test file
        fp = fopen( "/Local/ftest.bin", "wb" );
    if ( !fp )
      {
        printf( "fopen w error\r\n" );
            exit( 1 );
      }
    for (i=0; i<16; i++) fputc(i,fp);
    fclose(fp);

    // re-open test file for reading
    fp = fopen( "/Local/ftest.bin", "rb" );
    if ( !fp )
      {
        printf( "fopen r error\r\n" );
        exit( 1 );
      }

    // first check file is as expected
    for (i=0; i<16; i++)
      {
        j=fgetc(fp);
        if ( i!=j )
          {
            printf( "file mismatch %d at %d\r\n",j,i );
            exit( 1 );
          }
      }

    fseeker(12,1); fseeker(12,2); fseeker(12,3); 
    fseeker(15,1); fseeker(15,1);fseeker(14,2);
    fseeker(5,1); fseeker(5,2); fseeker(5,3); 
    fseeker(12,1); fseeker(5,2); 
       
    fclose(fp);
    
    printf( "All tests run\r\n" );
    while ( 1 );     // spin 

 }
Be the first to answer this question.