Article View: comp.sys.atari.st
Article #26598Re: bug in fopen/getc in Megamax C
From: Dave Dermott
Date: Sun, 03 May 1987 01:22
Date: Sun, 03 May 1987 01:22
93 lines
3180 bytes
3180 bytes
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 <stdio.h>
#include <osbind.h>
#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 <stdio.h>
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);
}
-------
Technical Details
Message-ID:
<12299287148.21.DERMOTT@DREA-XX.ARPA>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!seismo!rutgers!ames!ucbcad!ucbvax!DREA-XX.ARPA!DERMOTTShow Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!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