# HG changeset patch # User jfp <jf.pieronne@laposte.net> # Date 1715864547 -7200 # Thu May 16 15:02:27 2024 +0200 # Node ID a2fa6fce86cf6a3f0fdc5505fb8d93297e3ef80b # Parent dfc18f05ce766ea0e6ca248cb744143c56705eda fileqio.py: Add atrdef/fatdef argument to qio access and daccess. Fix bug with mode argument diff --git a/python/local/ovms_module/ovms/fileqio.py b/python/local/ovms_module/ovms/fileqio.py --- a/python/local/ovms_module/ovms/fileqio.py +++ b/python/local/ovms_module/ovms/fileqio.py @@ -4,6 +4,8 @@ from ovms import iosbdef from ovms import fibdef from ovms import rms +from ovms import fatdef +from ovms import atrdef from ovms import starlet from ovms import stsdef from ovms import ast @@ -14,6 +16,8 @@ filename: bytes | str channel: int | None fibdesc: fibdef.FIBDESC | None + fat: fatdef.FAT + atrs: ctypes.Array[atrdef.ATR] def __init__(self, fn: str | bytes, mode: str | None = None) -> None: self.filename = fn @@ -22,12 +26,8 @@ self.fibdesc = None def _open_p1(self, mode: str | None) -> Tuple[int, fibdef.FIBDEF]: - if self.mode is not None: - self.mode = mode - elif mode is None: - self.mode = 'r' - else: - self.mode = mode + if mode is None: + mode = "r" if self.mode is None else self.mode dev = rms.search(self.filename)[1] ifid = rms.getrmsattr(self.filename, rms.RMSATTR_K_FID) @@ -39,7 +39,7 @@ fib = fibdef.FIBDEF() fib.fib_r_fid_fields = fid - if mode == 'w': + if mode == "w": fib.fib_l_acctl = fibdef.FIB_M_NOWRITE | fibdef.FIB_M_WRITE else: fib.fib_l_acctl = 0 @@ -68,6 +68,16 @@ else: c_ast_completion = ctypes.c_uint64(ast.vms_ast_completion) c_ast_param = ctypes.c_uint64(id(astctxt)) + self.fat = fatdef.FAT() + atr1 = atrdef.ATR() + atrdef.set_atr_item( + atr1, + atrdef.ATR_S_RECATTR, + atrdef.ATR_C_RECATTR, + ctypes.pointer(self.fat), + ) + atr2 = atrdef.ATR() # default fill with zeros + self.atrs = (atrdef.ATR * 2)(atr1, atr2) status = qio_call( efn, ichan, @@ -79,29 +89,29 @@ zero64, zero64, zero64, - zero64, + ctypes.byref(self.atrs), zero64, ) if not stsdef.vms_status_success(status): starlet.dassgn(chan) - raise IOError(status, 'qio ACCESS error') + raise IOError(status, "qio ACCESS error") return chan, iosb - def open(self, mode: str | None = None) -> 'FILEQIO': + def open(self, mode: str | None = None) -> "FILEQIO": chan, fib = self._open_p1(mode) chan, iosb = self._open_p2(mode) if not stsdef.vms_status_success(iosb.iosb_w_status): - raise IOError(iosb.iosb_w_status, 'iosb open error') + raise IOError(iosb.iosb_w_status, "iosb open error") self.channel = chan return self - async def aopen(self, mode: str | None = None) -> 'FILEQIO': + async def aopen(self, mode: str | None = None) -> "FILEQIO": astctxt = ast.AstContext() chan, iosb = self._open_p2(mode, astctxt) await ast.wait_completion(astctxt) if not stsdef.vms_status_success(iosb.iosb_w_status): starlet.dassgn(chan) - raise IOError(iosb.iosb_w_status, 'iosb aopen error') + raise IOError(iosb.iosb_w_status, "iosb aopen error") self.channel = chan return self @@ -119,7 +129,6 @@ zero64 = ctypes.c_uint64(0) if astctxt is None: c_ast_completion = None - ast_ctxt = None c_ast_param = zero64 else: c_ast_completion = ctypes.c_uint64(ast.vms_ast_completion) @@ -135,11 +144,11 @@ zero64, zero64, zero64, - zero64, + ctypes.byref(self.atrs), zero64, ) if not stsdef.vms_status_success(status): - raise IOError(status, 'qio DEACCESS error') + raise IOError(status, "qio DEACCESS error") return iosb def close(self) -> None: @@ -147,7 +156,7 @@ if iosb is None: return if not stsdef.vms_status_success(iosb.iosb_w_status): - raise IOError(iosb.iosb_w_status, 'close error') + raise IOError(iosb.iosb_w_status, "close error") starlet.dassgn(self.channel) # type: ignore async def aclose(self) -> None: @@ -157,10 +166,10 @@ return await ast.wait_completion(astctxt) if not stsdef.vms_status_success(iosb.iosb_w_status): - raise IOError(iosb.iosb_w_status, 'aclose error') + raise IOError(iosb.iosb_w_status, "aclose error") starlet.dassgn(self.channel) # type: ignore - def __enter__(self) -> 'FILEQIO': + def __enter__(self) -> "FILEQIO": self.open(self.mode) return self @@ -182,15 +191,15 @@ buff: ctypes.Array[ctypes.c_char] | None = None, ) -> Tuple[iosbdef.IOSB_r_io_64, ctypes.Array[ctypes.c_char]]: if self.channel is None or self.fibdesc is None: - raise ValueError('I/O operation on closed file.') + raise ValueError("I/O operation on closed file.") if buff is None: if sz is None: - raise ValueError('Both sz and buff are None') + raise ValueError("Both sz and buff are None") buff = ctypes.create_string_buffer(sz) elif sz is None: sz = len(buff) elif len(buff) < sz: - raise BufferError('len(buff) < sz') + raise BufferError("len(buff) < sz") qio_call = starlet.vms_qiow if astctxt is None else starlet.vms_qio efn = ctypes.c_uint32(efndef.EFN_C_ENF) ichan = ctypes.c_uint16(self.channel) @@ -202,7 +211,6 @@ csz = ctypes.c_uint64(sz) if astctxt is None: c_ast_completion = None - ast_ctxt = None c_ast_param = zero64 else: c_ast_completion = ctypes.c_uint64(ast.vms_ast_completion) @@ -222,7 +230,7 @@ zero64, ) if not stsdef.vms_status_success(status): - raise IOError(status, 'readvblk error') + raise IOError(status, "readvblk error") return iosb, buff def readblk( @@ -233,7 +241,7 @@ ) -> bytes: iosb, buff = self._readblk(vblk, sz, None, buff)[:2] if not stsdef.vms_status_success(iosb.iosb_w_status): - raise IOError(iosb.iosb_w_status, 'IOSB readblk error') + raise IOError(iosb.iosb_w_status, "IOSB readblk error") return buff.raw def readblk_nowait( @@ -256,14 +264,14 @@ iosb, buff = self._readblk(vblk, sz, astctxt, buff) await ast.wait_completion(astctxt) if not stsdef.vms_status_success(iosb.iosb_w_status): - raise IOError(iosb.iosb_w_status, 'IOSB areadblk error') + raise IOError(iosb.iosb_w_status, "IOSB areadblk error") return buff.raw def _writeblk( self, buff: bytes, vblk: int, astctxt: ast.AstContext | None = None ) -> iosbdef.IOSB_r_io_64: if self.channel is None or self.fibdesc is None: - raise ValueError('I/O operation on closed file.') + raise ValueError("I/O operation on closed file.") qio_call = starlet.vms_qiow if astctxt is None else starlet.vms_qio efn = ctypes.c_uint32(efndef.EFN_C_ENF) ichan = ctypes.c_uint16(self.channel) @@ -294,13 +302,13 @@ zero64, ) if not stsdef.vms_status_success(status): - raise IOError(status, 'writeblk error') + raise IOError(status, "writeblk error") return iosb def writeblk(self, buff: bytes, vblk: int) -> None: iosb = self._writeblk(buff, vblk) if not stsdef.vms_status_success(iosb.iosb_w_status): - raise IOError(iosb.iosb_w_status, 'IOSB writeblk error') + raise IOError(iosb.iosb_w_status, "IOSB writeblk error") def writeblk_nowait( self, buff: bytes, vblk: int, astctxt: ast.AstContext @@ -313,4 +321,4 @@ iosb = self._writeblk(buff, vblk, astctxt) await ast.wait_completion(astctxt) if not stsdef.vms_status_success(iosb.iosb_w_status): - raise IOError(iosb.iosb_w_status, 'IOSB awriteblk error') + raise IOError(iosb.iosb_w_status, "IOSB awriteblk error")