diff --git a/amitools/vamos/lib/DosLibrary.py b/amitools/vamos/lib/DosLibrary.py index b7f03cc3..4ab46104 100644 --- a/amitools/vamos/lib/DosLibrary.py +++ b/amitools/vamos/lib/DosLibrary.py @@ -766,8 +766,12 @@ def Seek(self, ctx, fh_b_addr, pos, mode): def FGetC(self, ctx, fh_b_addr): fh = self.file_mgr.get_by_b_addr(fh_b_addr, False) ch = fh.getc() - if ch == -1: + if ch == -2: log_dos.info("FGetC(%s) -> EOF (%d)", fh, ch) + # EOF is also -1 + ch = -1 + elif ch == -1: + log_dos.info("FGetC(%s) -> Error (%d)", fh, ch) else: log_dos.info("FGetC(%s) -> '%c' (%d)", fh, ch, ch) return ch diff --git a/amitools/vamos/lib/dos/FileHandle.py b/amitools/vamos/lib/dos/FileHandle.py index 46513c8e..76a14ff7 100644 --- a/amitools/vamos/lib/dos/FileHandle.py +++ b/amitools/vamos/lib/dos/FileHandle.py @@ -25,8 +25,7 @@ def __init__( self.interactive = self.obj.isatty() # tty stuff if self.interactive: - fd = self.obj.fileno() - self.terminal = Terminal(fd) + self.terminal = Terminal(obj) else: self.terminal = None @@ -83,39 +82,64 @@ def wait_for_char(self, timeout): return self.terminal.wait_for_char(timeout) def write(self, data): + """write data + + return -1 on error, 0=EOF, >0 written bytes""" assert isinstance(data, (bytes, bytearray)) - try: - self.obj.write(data) - if self.auto_flush: - self.obj.flush() - return len(data) - except IOError: - return -1 + + # read from terminal or direct + if self.terminal: + got = self.terminal.write(data) + else: + try: + got = self.obj.write(data) + except IOError: + got = -1 + + # do auto flush? + if got > 0 and self.auto_flush: + self.obj.flush() + + # return got bytes + return got def read(self, len): + """read data + + return -1 on error, 0=EOF, >0 written bytes""" + if self.terminal: + return self.terminal.read(len) try: - if self.interactive: - d = self.obj.read1(len) - else: - d = self.obj.read(len) - return d + return self.obj.read(len) except IOError: return -1 def getc(self): + """read character + + return char 0-255 or -1 on Error and -2 on EOF + """ if len(self.unch) > 0: self.ch = self.unch[0] del self.unch[0] else: + # handle NIL: if self.is_nil: return -1 - try: + + # read from terminal or direct + if self.terminal: + d = self.terminal.read(1) + else: d = self.obj.read(1) - if d == b"": - return -1 - self.ch = d[0] - except IOError: + + # -1 on Error + if d == -1: return -1 + # -2 on EOF + elif d == b"": + return -2 + self.ch = d[0] return self.ch def gets(self, len): diff --git a/amitools/vamos/lib/dos/terminal.py b/amitools/vamos/lib/dos/terminal.py index ca549fad..3837f9c4 100644 --- a/amitools/vamos/lib/dos/terminal.py +++ b/amitools/vamos/lib/dos/terminal.py @@ -10,10 +10,11 @@ class Terminal: - def __init__(self, fd): - self.fd = fd + def __init__(self, obj): + self.fd = obj.fileno() + self.obj = obj if termios: - self.tty_state = termios.tcgetattr(fd) + self.tty_state = termios.tcgetattr(self.fd) def close(self): if termios: @@ -54,3 +55,23 @@ def wait_for_char(self, timeout): return self.fd in rx else: return None + + def read(self, size): + """read from terminal and do some covnersions. + + return -1 on Error, or data bytes with len = 0: EOF + """ + try: + return self.obj.read1(size) + except IOError: + return -1 + + def write(self, data): + """write to terminal and do some conversions. + + return -1 on Error, 0 on EOF, and >0 written bytes + """ + try: + return self.obj.write(data) + except IOError: + return -1