# HG changeset patch
# User jfp <jf.pieronne@laposte.net>
# Date 1715947287 -7200
#      Fri May 17 14:01:27 2024 +0200
# Node ID cb0095d1a630e3392c95a28126411e08c0ec6e9f
# Parent  cd899269b2fd2c66c22125276fe39069d3e706d0
Add property closed. Open a file already opened is ignored.

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
@@ -14,20 +14,19 @@
 
 class FILEQIO(object):
     filename: bytes | str
+    mode: 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:
+    def __init__(self, fn: str | bytes, mode: str = "r") -> None:
         self.filename = fn
         self.mode = mode
         self.channel = None
         self.fibdesc = None
 
-    def _open_p1(self, mode: str | None) -> Tuple[int, fibdef.FIBDEF]:
-        if mode is None:
-            mode = "r" if self.mode is None else self.mode
+    def _open_p1(self) -> Tuple[int, fibdef.FIBDEF]:
         dev = rms.search(self.filename)[1]
 
         ifid = rms.getrmsattr(self.filename, rms.RMSATTR_K_FID)
@@ -39,7 +38,7 @@
 
         fib = fibdef.FIBDEF()
         fib.fib_r_fid_fields = fid
-        if mode == "w":
+        if self.mode == "w":
             fib.fib_l_acctl = fibdef.FIB_M_NOWRITE | fibdef.FIB_M_WRITE
         else:
             fib.fib_l_acctl = 0
@@ -47,10 +46,10 @@
         return (chan, fib)
 
     def _open_p2(
-        self, mode: str | None = None, astctxt: ast.AstContext | None = None
+        self, astctxt: ast.AstContext | None = None
     ) -> Tuple[int, iosbdef.IOSB_r_io_64]:
         qio_call = starlet.vms_qiow if astctxt is None else starlet.vms_qio
-        (chan, fib) = self._open_p1(mode)
+        (chan, fib) = self._open_p1()
 
         fibdesc = fibdef.FIBDESC()
         fibdesc.length = ctypes.sizeof(fib)
@@ -97,17 +96,23 @@
             raise IOError(status, "qio ACCESS error")
         return chan, iosb
 
-    def open(self, mode: str | None = None) -> "FILEQIO":
-        chan, fib = self._open_p1(mode)
-        chan, iosb = self._open_p2(mode)
+    def open(self, mode: str = "r") -> "FILEQIO":
+        if self.channel is not None:
+            return self
+        self.mode = mode
+        chan, fib = self._open_p1()
+        chan, iosb = self._open_p2()
         if not stsdef.vms_status_success(iosb.iosb_w_status):
             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 = "r") -> "FILEQIO":
+        if self.channel is not None:
+            return self
+        self.mode = mode
         astctxt = ast.AstContext()
-        chan, iosb = self._open_p2(mode, astctxt)
+        chan, iosb = self._open_p2(astctxt)
         await ast.wait_completion(astctxt)
         if not stsdef.vms_status_success(iosb.iosb_w_status):
             starlet.dassgn(chan)
@@ -153,21 +158,27 @@
 
     def close(self) -> None:
         iosb = self._close()
-        if iosb is None:
-            return
-        if not stsdef.vms_status_success(iosb.iosb_w_status):
-            raise IOError(iosb.iosb_w_status, "close error")
-        starlet.dassgn(self.channel)  # type: ignore
+        if iosb is not None:
+            if not stsdef.vms_status_success(iosb.iosb_w_status):
+                raise IOError(iosb.iosb_w_status, "close error")
+        if self.channel is not None:
+            starlet.dassgn(self.channel)  # type: ignore
+            self.channel = None
 
     async def aclose(self) -> None:
         astctxt = ast.AstContext()
         iosb = self._close(astctxt)
-        if iosb is None:
-            return
-        await ast.wait_completion(astctxt)
-        if not stsdef.vms_status_success(iosb.iosb_w_status):
-            raise IOError(iosb.iosb_w_status, "aclose error")
-        starlet.dassgn(self.channel)  # type: ignore
+        if iosb is not None:
+            await ast.wait_completion(astctxt)
+            if not stsdef.vms_status_success(iosb.iosb_w_status):
+                raise IOError(iosb.iosb_w_status, "aclose error")
+        if self.channel is not None:
+            starlet.dassgn(self.channel)  # type: ignore
+            self.channel = None
+
+    @property
+    def closed(self) -> bool:
+        return self.channel is None
 
     def __enter__(self) -> "FILEQIO":
         self.open(self.mode)