Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!ames!ucbcad!ucbvax!DREA-XX.ARPA!DERMOTT From: DERMOTT@DREA-XX.ARPA (Dave Dermott) Newsgroups: comp.sys.atari.st Subject: Re: bug in fopen/getc in Megamax C Message-ID: <12299287148.21.DERMOTT@DREA-XX.ARPA> Date: Sat, 2-May-87 21:22:09 EDT Article-I.D.: DREA-XX.12299287148.21.DERMOTT Posted: Sat May 2 21:22:09 1987 Date-Received: Sun, 3-May-87 08:10:22 EDT Sender: daemon@ucbvax.BERKELEY.EDU Distribution: world Organization: The ARPA Internet Lines: 93 Re: bug in fopen/getc System: ATARI 1040 ST Compiler: Megamax C V1.1 Earlier I noted the problem of attempting to read beyond the end of file with getc() - it extended the length of the file. I tracked the problem down to a call to lseek() in fclose() and fflush(). If one tries to position the file beyond the end of file with lseek() the file is extended. Example: #include #include #define O_RDONLY 0 extern long lseek(); char *filnam; int fd; long ll; main(argc,argv) int argc; char *argv[]; { if(argc < 2){ puts("no filename"); exit(1);} filnam=argv[1]; puts(filnam); fd=open(filnam,O_RDONLY); /* open read only !! */ ll=lseek(fd,0L,2); /* go to end of file */ printf("eof at %ld\n",ll); /*show file position */ ll=lseek(fd,20L,1); /* move forward 20 bytes */ /* ll= Fseek(20L,fd,1); */ /*GEMDOS call $42 works ,returns error code */ printf("after seek %ld\n",ll); /* show new position */ close(fd); } The file gets extended by 20 bytes! The GEMDOS call $42 - ( Fseek() not to be confused with fseek()) does the right thing. It returns a negative error code and doesn't extend the file. Note the argument sequence is different. By disassembling ( I don't have the source of lseek() ) I found lseek() calls Fseek() and then does several other things, including call write() !! The read-only flag seems to be ignored . Seek and Ye shall find! David Dermott P.S. Here is the reconstructed source of fclose/fflush , from decompiling the disassembled object ( I haven't figured out lseek yet) #include extern long lseek(); fclose(fp) register FILE *fp; { if(fflush(fp))return (-1); if(fp->_flag & _BIGBUF)_disposptr(fp->_base); /* ie mfree() */ fp->_flag = 0; if(close(fp->_fd))return (-1); return 0; } fflush(fp) register FILE *fp; { register len; if(!((fp->_flag) & (_READ|_WRITE) ))return (-1); len=fp->_ptr - fp->_base; if((fp->_flag)&_DIRTY){ if(!((fp->_flag) & _WRITE ))return (-1); if((fp->_flag) & _APPEND )lseek(fp->_fd,0L,2); if(write(fp->_fd, fp->_base, len) == -1)return(-1); fp->_flag &= ~ _DIRTY; fp->_mark += len; } else { if((fp->_fd) >0) fp->_mark =lseek(fp->_fd,(long)(-(fp->_cnt)),1); /* if attempt has been made to read past EOF, fp->_cnt <0 so lseek will position beyond EOF */ /* fix by putting in check for fp->cnt < 0 */ } fp->_ptr = fp->_base; fp->_cnt = 0; return (0); } -------