Fix bug where ftell would inappropriately change the file mark.

ftell would set the mark as if the buffer and putback were being discarded, but not actually discard them. This resulted in characters being reread once the end of the buffer was reached.

Here is an example that illustrates the problem:

#include <stdio.h>
#include <string.h>
char buf[100];
int main(void) {
        FILE *f = fopen("somefile","r"); // a file with some text
        if (!f) return 0;
        setvbuf(f, 0L, _IOFBF, 14); // to see problem sooner
        fgets(buf, 10, f);
        printf("first read : %s\n", buf);
        ftell(f);
        memset(buf, 0, sizeof(buf));
        fgets(buf, 10, f);
        printf("second read: %s\n", buf);]
}
This commit is contained in:
Stephen Heumann 2022-07-02 22:05:40 -05:00
parent 36808404ca
commit 3eb8a9cb55
1 changed files with 19 additions and 14 deletions

View File

@ -378,9 +378,19 @@ fl1a bit #_IORW
beq fl3
bit #_IOREAD if the file is being read then
beq fl2
ph4 <stream use ftell to set the mark
ph4 <stream set the mark to current position
jsl ftell
ldy #FILE_flag
cmp #-1
bne fl1b
cpx #-1
beq fl1c
fl1b sta smPosition
stx smPosition+2
ldy #FILE_file
lda [stream],Y
sta smRefNum
OSSet_Mark sm
fl1c ldy #FILE_flag
lda [stream],Y
fl2 and #$FFFF-_IOWRT-_IOREAD turn off the reading and writing flags
sta [stream],Y
@ -396,6 +406,11 @@ wrDataBuffer ds 4
wrRequestCount ds 4
ds 4
dc i'1'
sm dc i'3' parameter block for OSSet_Mark
smRefNum ds 2
dc i'0'
smPosition ds 4
end
****************************************************************
@ -2014,26 +2029,16 @@ lb1 move4 gmPosition,pos set the position
sta pos+2
ldy #FILE_pbk dec pos by 1 for each char in the
lda [stream],Y putback buffer then
bmi lb2
bmi rts
dec4 pos
ldy #FILE_pbk+2
lda [stream],Y
bmi lb2
bmi rts
dec4 pos
lb2 ldy #FILE_file set the file's mark
lda [stream],Y
sta spRefNum
move4 pos,spPosition
OSSet_Mark sp
rts plb
creturn 4:pos
sp dc i'3' parameter block for OSSet_Mark
spRefNum ds 2
dc i'0'
spPosition ds 4
gm dc i'2' parameter block for OSGetMark
gmRefNum ds 2
gmPosition ds 4