llvm-mos / llvm-mos-sdk

SDK for developing with the llvm-mos compiler
https://www.llvm-mos.org
Other
255 stars 52 forks source link

Port atari Sparta DOS X `lseek` from cc65 #333

Open mysterymath opened 1 month ago

mysterymath commented 1 month ago

The cc65 lseek (and thus, fseek) for atari only works on Sparta DOS X, since the NOTE/POINT system available on other DOS'es are insufficiently expressive to implement it (since they speak Sectors and Byte offsets, rather than offsets from file begin/end). This limits its usefulness compared to the rest of the atari POSIX file compat library.

pfusik commented 2 weeks ago

Idea for a seek compatible with any DOS:

int fseek(FILE *stream, long offset, int origin)
{
    switch (origin) {
    case SEEK_CUR:
        if (offset >= 0)
            SKIP(offset);
        else
           return fseek(stream, current_pos + offset, SEEK_SET);
        break;
    case SEEK_SET:
        rewind(stream); // either POINT or CLOSE+OPEN
        SKIP(offset);
        break;
    case SEEK_END:
        file_size = current_pos + SKIP_UNTIL_EOF();
        if (offset < 0)
            return fseek(stream, file_size + offset, SEEK_SET);
        break;
    }
}

This is of course slow on large files, but standard Atari DOSes read the whole file in order to delete or replace it, so users should be patient enough. :)

One problem is that we cannot SKIP (nor SKIP_UNTIL_EOF) on files open in write-only mode.

mysterymath commented 2 weeks ago

Meh, generally the ethos behind the C library has been to present a standard interface to functionality already present in the underlying system. This is a stretch along those lines, and it would have a dramatically different time complexity than one would typically expect.