From 0dd7b0c3a5204ac96ae6067f3d48cbfc4f62ec05 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Thu, 25 Jan 2024 09:12:46 +0100 Subject: [PATCH] Implement __sysremove for sim65 This will allow using unlink()/remove() in sim65 programs Use it to unlink fgets' test output file --- libsrc/sim6502/paravirt.s | 5 ++++ src/sim65/paravirt.c | 43 ++++++++++++++++++++++++++++-- src/sim65/paravirt.h | 6 ++--- test/ref/test_fgets.c | 2 ++ test/val/remove.c | 55 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 test/val/remove.c diff --git a/libsrc/sim6502/paravirt.s b/libsrc/sim6502/paravirt.s index 0d8e528b17..3bd40fbe4d 100644 --- a/libsrc/sim6502/paravirt.s +++ b/libsrc/sim6502/paravirt.s @@ -8,10 +8,15 @@ ; .export exit, args, _open, _close, _read, _write + .export __sysremove, ___osmaperrno +__sysremove := $FFF2 +___osmaperrno := $FFF3 _open := $FFF4 _close := $FFF5 _read := $FFF6 _write := $FFF7 args := $FFF8 exit := $FFF9 + + ; $FFFA-FFFF are hardware vectors, extend before not after! diff --git a/src/sim65/paravirt.c b/src/sim65/paravirt.c index 2e52d6e7e0..141bcd2bdd 100644 --- a/src/sim65/paravirt.c +++ b/src/sim65/paravirt.c @@ -163,7 +163,7 @@ static void PVArgs (CPURegs* Regs) static void PVOpen (CPURegs* Regs) { - char Path[PVOPEN_PATH_SIZE]; + char Path[PV_PATH_SIZE]; int OFlag = O_INITIAL; int OMode = 0; unsigned RetVal, I = 0; @@ -184,7 +184,7 @@ static void PVOpen (CPURegs* Regs) break; } ++I; - if (I >= PVOPEN_PATH_SIZE) { + if (I >= PV_PATH_SIZE) { Error("PVOpen path too long at address $%04X",Name); } } @@ -253,6 +253,35 @@ static void PVClose (CPURegs* Regs) +static void PVSysRemove (CPURegs* Regs) +{ + char Path[PV_PATH_SIZE]; + unsigned RetVal, I = 0; + + unsigned Name = GetAX (Regs); + + Print (stderr, 2, "PVSysRemove ($%04X)\n", Name); + + do { + if (!(Path[I] = MemReadByte ((Name + I) & 0xFFFF))) { + break; + } + ++I; + if (I >= PV_PATH_SIZE) { + Error("PVSysRemove path too long at address $%04X", Name); + } + } + while (1); + + Print (stderr, 2, "PVSysRemove (\"%s\")\n", Path); + + RetVal = remove (Path); + + SetAX (Regs, RetVal); +} + + + static void PVRead (CPURegs* Regs) { unsigned char* Data; @@ -305,7 +334,17 @@ static void PVWrite (CPURegs* Regs) +static void PVOSMapErrno (CPURegs* Regs) +{ + unsigned err = GetAX(Regs); + SetAX (Regs, err != 0 ? -1 : 0); +} + + + static const PVFunc Hooks[] = { + PVSysRemove, + PVOSMapErrno, PVOpen, PVClose, PVRead, diff --git a/src/sim65/paravirt.h b/src/sim65/paravirt.h index 3badb50eac..f3281705ed 100644 --- a/src/sim65/paravirt.h +++ b/src/sim65/paravirt.h @@ -44,11 +44,11 @@ -#define PARAVIRT_BASE 0xFFF4 +#define PARAVIRT_BASE 0xFFF2 /* Lowest address used by a paravirtualization hook */ -#define PVOPEN_PATH_SIZE 1024 -/* Maximum path size supported by PVOpen */ +#define PV_PATH_SIZE 1024 +/* Maximum path size supported by PVOpen/PVSysRemove */ diff --git a/test/ref/test_fgets.c b/test/ref/test_fgets.c index 72ea308ddd..0529b1651e 100644 --- a/test/ref/test_fgets.c +++ b/test/ref/test_fgets.c @@ -10,6 +10,7 @@ #include #include #include +#include FILE *in, *out; char buf[32]; @@ -34,6 +35,7 @@ int main(int argc,char **argv) printf("Error: file pointer should be in error state\n"); } fclose(out); + unlink(outfile_path); in = fopen(INFILE, "rb"); if (in == NULL) { diff --git a/test/val/remove.c b/test/val/remove.c new file mode 100644 index 0000000000..eecf8be8f3 --- /dev/null +++ b/test/val/remove.c @@ -0,0 +1,55 @@ +#include +#include +#include + +int fails = 0; + + +static void create_out_file(const char *outfile_path) { + FILE *out; + + + out = fopen(outfile_path, "wb"); + if (out == NULL) { + printf("Could not create %s\n", outfile_path); + fails++; + return; + } + fclose(out); +} + +int main (int argc, char **argv) +{ + int r; + static char outfile_path[FILENAME_MAX+1]; + + sprintf(outfile_path, "%s.test.out", argv[0]); + + create_out_file(outfile_path); + r = remove(outfile_path); + if (r != 0) { + printf("could not remove() %s\n", outfile_path); + fails++; + } + + create_out_file(outfile_path); + r = unlink(outfile_path); + if (r != 0) { + printf("could not unlink() %s\n", outfile_path); + fails++; + } + + r = remove("klsdfjqlsjdflkqjdsoizu"); + if (r == 0) { + printf("remove()ing non-existent file succeeded\n"); + fails++; + } + + r = unlink("klsdfjqlsjdflkqjdsoizu"); + if (r == 0) { + printf("unlink()ing non-existent file succeeded\n"); + fails++; + } + + return fails; +}