dosemu2/test/func_ds3_file_access.py
geos_one 91736529d5
Some checks failed
Master / Scheduled (FULL) (push) Has been cancelled
Master / Triggered (push) Has been cancelled
Master / Triggered (ASAN) (push) Has been cancelled
Master / Triggered (FULL) (push) Has been cancelled
New upstream version 2.0pre9.2
2025-08-10 12:35:43 +02:00

152 lines
3.8 KiB
Python

# Opens a file READ/WRITE even on a READONLY filesystem
# fstype = FAT, FATRO, MFS, MFSRO
# optype = READ, WRITE
def ds3_file_access(self, fstype, optype):
testdir = self.mkworkdir('d')
self.mkfile("testit.bat", """\
d:
%s
c:\\fileaccs %s
rem end
""" % ("rem Internal share" if self.version == "FDPP kernel" else "c:\\share", optype), newline="\r\n")
# compile sources
self.mkcom_with_ia16("fileaccs", r"""
#include <dos.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#define FNAME "FOO.DAT"
#define FDATA "0123456789abcdef\n"
char ibuf[32];
void __far __interrupt (*oldint24)(void);
volatile uint16_t int24_ax;
void __far __interrupt __attribute__ ((near_section)) myint24(void); /* Prototype */
__asm (
"myint24:\n"
" pushw %bp\n"
" movw %sp, %bp\n"
" pushw %ds\n"
" pushw 22(%bp)\n" /* int21 caller's DS on stack */
" popw %ds\n"
" movw %ax, int24_ax\n"
" popw %ds\n"
" popw %bp\n"
" movb $0x03, %al\n" /* 0=Ignore, 1=Retry, 2=Terminate, 3=Fail */
" iretw\n"
);
int main(int argc, char *argv[])
{
int handle;
unsigned int ret, num;
if (argc < 2) {
printf("Error: missing optype (READ|WRITE) argument\n");
return -1;
}
// Setup int24 handler
int24_ax = 0;
oldint24 = _dos_getvect(0x24);
_dos_setvect(0x24, myint24);
ret = _dos_open(FNAME, O_RDWR, &handle);
if (ret != 0) {
printf("Error: File Open failed(ret = 0x%02x)\n", ret);
_dos_setvect(0x24, oldint24);
return -1;
}
printf("Info: File Open success\n");
if (strcmp(argv[1], "WRITE") == 0) {
// It's unlikely this write will fail on a write to readonly disk
// due to DOS buffering, so use commit to force the error.
printf("Info: About to write\n");
ret = _dos_write(handle, FDATA, strlen(FDATA), &num);
if (ret != 0) {
printf("Info: File Write failed(ret = 0x%02x)\n", ret);
// The file is in error condition, so _dos_close() causes another int24
_dos_close(handle);
_dos_setvect(0x24, oldint24);
return -1;
}
printf("Info: About to commit\n");
ret = _dos_commit(handle);
if (ret != 0) {
printf("Info: File Commit failed(ret=0x%02x, int24_ax=0x%04x)\n", ret, int24_ax);
// The file is in error condition, so _dos_close() causes another int24
_dos_close(handle);
_dos_setvect(0x24, oldint24);
return -1;
}
printf("Info: File Write/Commit success(num=%u)\n", num);
} else {
ret = _dos_read(handle, ibuf, strlen(FDATA), &num);
if (ret != 0) {
printf("Info: File Read failed(ret = 0x%02x)\n", ret);
_dos_close(handle);
_dos_setvect(0x24, oldint24);
return -1;
}
printf("Info: File Read success(num=%u)\n", num);
}
ret = _dos_close(handle);
if (ret != 0) {
printf("Error: File Close returned(ret = %02x)\n", ret);
_dos_setvect(0x24, oldint24);
return -1;
}
printf("Info: File Close success\n");
_dos_setvect(0x24, oldint24);
return 0;
}
""")
self.mkfile("FOO.DAT", "xxxxxxxx", dname=testdir)
if fstype.startswith("MFS"):
name = "dXXXXs/d"
else:
name = self.mkimage("12", cwd=testdir)
if fstype.endswith("RO"):
name += ":ro"
results = self.runDosemu("testit.bat", config="""\
$_hdimage = "dXXXXs/c:hdtype1 %s +1"
$_floppy_a = ""
""" % name, timeout=10)
self.assertIn("File Open success", results)
if fstype.endswith("RO"):
if optype == "WRITE":
self.assertNotIn("File Write/Commit success", results)
else:
self.assertIn("File Read success", results)
self.assertIn("File Close success", results)
else:
if optype == "WRITE":
self.assertIn("File Write/Commit success", results)
else:
self.assertIn("File Read success", results)
self.assertIn("File Close success", results)