fclose: close stream even if there is an error flushing buffered data.

This can happen, e.g., if there is an IO error or if there is insufficient free disk space to flush the data. In this case, fclose should return -1 to report an error, but it should still effectively close the stream and deallocate the buffer for it. (This behavior is explicitly specified in the C99 and later standards.)

Previously, ORCA/C effectively left the stream open in these cases. As a result, the buffer was not deallocated. More importantly, this could cause the program to hang at exit, because the stream would never be removed from the list of open files.

Here is an example program that demonstrates the problem:

/*
 * Run this on a volume with less than 1MB of free space, e.g. a floppy.
 * The fclose return value should be -1 (EOF), indicating an error, but
 * the two RealFreeMem values should be close to each other (indicating
 * that the buffer was freed), and the program should not hang on exit.
 */

#include <stdio.h>
#include <stddef.h>
#include <memory.h>

#define BUFFER_SIZE 1000000

int main(void) {
        size_t i;
        int ret;

        printf("At start, RealFreeMem = %lu\n", RealFreeMem());

        FILE *f = fopen("testfile", "wb");
        if (!f)
                return 0;

        setvbuf(f, NULL, _IOFBF, BUFFER_SIZE);

        for (i = 0; i < BUFFER_SIZE; i++) {
                putc('x', f);
        }

        ret = fclose(f);
        printf("fclose return value = %d\n", ret);

        printf("At end, RealFreeMem = %lu (should be close to start value)\n",
                RealFreeMem());
}
This commit is contained in:
Stephen Heumann 2024-02-19 22:30:15 -06:00
parent 9d42552756
commit 16c7952648
1 changed files with 7 additions and 7 deletions

View File

@ -83,16 +83,13 @@ stdfile equ 7 is this a standard file?
phk
plb
lda #EOF assume we will get an error
sta err
ph4 <stream verify that stream exists
jsl ~VerifyStream
jcs rts
jcs rts_err
ph4 <stream do any pending I/O
jsl fflush
tax
jne rts
sta err initialize err to fflush result
stz stdfile not a standard file
lda stream+2 bypass file disposal if the file is
@ -113,7 +110,7 @@ cl0 lla p,stderr+4 find the file record that points to this
cl1 lda [p],Y
tax
ora [p]
jeq rts
jeq rts_err
lda [p]
cmp stream
bne cl2
@ -188,7 +185,10 @@ cl6 lda [p],Y
dey
cpy #2
bne cl6
cl7 stz err no error found
cl7 bra rts no error found
rts_err lda #EOF
sta err
rts plb
creturn 2:err