In fflush, reset the mark to account for flushing the buffer even on read-only files.

This is needed to keep the file mark consistent with the state of the buffer. Otherwise, subsequent reads may return data from the wrong place. (Using fflush on a read-only stream is undefined behavior, but other things in stdio call it that way, so it must work consistently with what they expect.)

Here is an example that was affected by this:

#include <stdio.h>
#include <string.h>

char buf[100];

int main(void) {
        FILE *f = fopen("somefile","r");
        if (!f) return 0;

        setvbuf(f, 0L, _IOFBF, 14);

        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);

        fseek(f, 0, SEEK_CUR);
        memset(buf, 0, sizeof(buf));
        fgets(buf, 10, f);
        printf("third read : %s\n", buf);
}
This commit is contained in:
Stephen Heumann 2022-07-02 22:26:23 -05:00
parent 2d6ca8a7b2
commit c877c74b92
1 changed files with 11 additions and 11 deletions

View File

@ -372,27 +372,27 @@ fa4 OSwrite wr write the info
jsr ~ioerror
bra rts
fl1 ldy #FILE_flag if the file is open for read/write then
fl1 ldy #FILE_flag get flags
lda [stream],Y
fl1a bit #_IORW
beq fl3
bit #_IOREAD if the file is being read then
beq fl2
ph4 <stream set the mark to current position
fl1a bit #_IOREAD if the file is being read then
beq fl2a
ph4 <stream set the mark to current position
jsl ftell
cmp #-1
bne fl1b
bne fl2b
cpx #-1
beq fl1c
fl1b sta smPosition
beq fl2
fl2b sta smPosition
stx smPosition+2
ldy #FILE_file
lda [stream],Y
sta smRefNum
OSSet_Mark sm
fl1c ldy #FILE_flag
fl2 ldy #FILE_flag get flags
lda [stream],Y
fl2 and #$FFFF-_IOWRT-_IOREAD turn off the reading and writing flags
fl2a bit #_IORW if the file is open for read/write then
beq fl3
and #$FFFF-_IOWRT-_IOREAD turn off the reading and writing flags
sta [stream],Y
fl3 ph4 <stream prepare file for output
jsl ~InitBuffer