Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 29 Dec 2002 01:54:15 -0800
From:      Jordan Hubbard <jkh@apple.com>
To:        FreeBSD Hackers <hackers@FreeBSD.ORG>
Subject:   Anyone like obscure stdio problems?
Message-ID:  <7D91340A-1B13-11D7-A2B1-000393BB9222@apple.com>

next in thread | raw e-mail | index | archive | help
I have no problem admitting that I've traced through the innards of 
_fseeko a few times now and am no closer to finding out exactly where 
the problem is, though I have a suspicion it has to do with when the 
file pointer's buffer is allocated and initially populated.  In any 
case, here's a particularly weird one from the Apple Files that also 
occurs on FreeBSD

The following program, also available from 
http://narcissus.queasyweasel.com/fump.c, demonstrates the problem.

If you change the top #define of FIRST_SEEK to 0 instead of 1, the 
program will work.  If you leave it at 1, the initial (and 
theoretically redundant and no-op) fseek on readMidFP will bugger up 
stdio's internal state somehow.

If anyone with more stdio-fu than me would like to poke at it, I'd be 
interested in hearing what you find out.  If this is breaking some 
undocumented rule of stdio I'd like to know that too so that I can 
document it both in FreeBSD and Mac OS X.  Thanks.

- Jordan

#include <stdio.h>

#define SIZE 40
#define NBS   5

#define FIRST_SEEK 1

int main( void ) {

	FILE *writeFP ;
	FILE *readMidFP ;
	int err , i , n = 0 , count , SizeOfFile , nerr = 0 ;
	char ch ;
	
	writeFP = fopen( "test_fseek_outfile" , "w" ) ;
	if ( writeFP == NULL ) {
		fprintf( stderr , "open for write failed.\n" ) ;
		exit( 1 ) ;
	}
	
	readMidFP = fopen( "test_fseek_outfile" , "r" ) ;	
	if ( readMidFP == NULL ) {
		fprintf( stderr , "open readMidFP for read failed.\n" ) ;
		exit( 1 ) ;
	}


         /* write SIZE a's to output file. */
	SizeOfFile = SIZE ;
	for ( count = 0 ; ( count <= SizeOfFile ) && ( n != -1 ) ; count++ ) {
		n = fprintf( writeFP , "a" ) ;
		if ( n == -1 )
                     break ;
	}
	fflush( writeFP ) ;

         /* seek to middle of file. */
         //	THIS IS CRUCIAL TO MAKING IT FAIL
         //	REMOVE THIS fseek() AND THE PROGRAM SUCCEEDS
#if FIRST_SEEK
	err = fseek( readMidFP , (long) (SizeOfFile / 2) , SEEK_SET ) ;
         if ( err != 0 ) {
             fprintf( stderr , "first fseek() to middle of file on 
readMidFP failed.\n" ) ;
             exit( 1 ) ;
         }
#endif
	
         /* seek to middle of file. */
	err = fseek( writeFP , (long) (SizeOfFile / 2) , SEEK_SET ) ;
         if ( err != 0 ) {
             fprintf( stderr , "first fseek() to middle of file on 
writeFP failed.\n" ) ;
             exit( 1 ) ;
         }
	
         /* write NBS b's. */
         for ( i = 0 ; i < NBS ; i++ )
             fprintf( writeFP , "b" ) ;
	fflush( writeFP ) ;


         /* seek to middle of file.  should be NBS b's there. */
	err = fseek( readMidFP , (long) (SizeOfFile / 2) , SEEK_SET ) ;
         if ( err != 0 ) {
             fprintf( stderr , "second fseek() to middle of file on 
readMidFP failed.\n" ) ;
             exit( 1 ) ;
         }
	
	for ( i = 0 ; i < NBS ; i++ ) {
		fscanf( readMidFP , "%c" , &ch ) ;
		if ( ch != 'b' ) {
                     fprintf( stderr , "** ERROR ** \'%c\' at position: 
%d\n" , ch , (SizeOfFile / 2)+i ) ;
                     nerr++ ;
                 }
	}

         if ( nerr == 0 )
             fprintf( stderr , "Program was succesful.\n" ) ;
         else
             fprintf( stderr , "Program failed.\n" ) ;
	
	return( 0 ) ;

}


--
Jordan K. Hubbard
Engineering Manager, BSD technology group
Apple Computer


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?7D91340A-1B13-11D7-A2B1-000393BB9222>