summary refs log tree commit diff stats
path: root/semihosting/arm-compat-semi.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-04-28 12:31:25 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-06-28 04:35:52 +0530
commita2212474301bc354bea46e3bdc6c21e33e0b5b2b (patch)
treef4fcc2215eea0b78cebd2cc7796df2d5e7213f68 /semihosting/arm-compat-semi.c
parent9a89470449a5171eb1bd06f681361e0888d15cf7 (diff)
downloadfocaccia-qemu-a2212474301bc354bea46e3bdc6c21e33e0b5b2b.tar.gz
focaccia-qemu-a2212474301bc354bea46e3bdc6c21e33e0b5b2b.zip
semihosting: Split out semihost_sys_isatty
Split out the non-ARM specific portions of SYS_ISTTY to a
reusable function.  This handles all GuestFD.

Add a common_semi_istty_cb helper to translate the Posix
error return, 0+ENOTTY, to the Arm semihosting not-a-file
success result.

Reviewed-by: Luc Michel <lmichel@kalray.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'semihosting/arm-compat-semi.c')
-rw-r--r--semihosting/arm-compat-semi.c40
1 files changed, 14 insertions, 26 deletions
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index a117d180bc..3cdc2b6efc 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -248,6 +248,19 @@ static void common_semi_rw_cb(CPUState *cs, target_ulong ret, target_ulong err)
 }
 
 /*
+ * Convert from Posix ret+errno to Arm SYS_ISTTY return values.
+ * With gdbstub, err is only ever set for protocol errors to EIO.
+ */
+static void common_semi_istty_cb(CPUState *cs, target_ulong ret,
+                                 target_ulong err)
+{
+    if (err) {
+        ret = (err == ENOTTY ? 0 : -1);
+    }
+    common_semi_cb(cs, ret, err);
+}
+
+/*
  * SYS_SEEK returns 0 on success, not the resulting offset.
  */
 static void common_semi_seek_cb(CPUState *cs, target_ulong ret,
@@ -291,14 +304,8 @@ common_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
  * do the work and return the required return value to the guest
  * via common_semi_cb.
  */
-typedef void sys_isattyfn(CPUState *cs, GuestFD *gf);
 typedef void sys_flenfn(CPUState *cs, GuestFD *gf);
 
-static void host_isattyfn(CPUState *cs, GuestFD *gf)
-{
-    common_semi_cb(cs, isatty(gf->hostfd), 0);
-}
-
 static void host_flenfn(CPUState *cs, GuestFD *gf)
 {
     struct stat buf;
@@ -310,11 +317,6 @@ static void host_flenfn(CPUState *cs, GuestFD *gf)
     }
 }
 
-static void gdb_isattyfn(CPUState *cs, GuestFD *gf)
-{
-    gdb_do_syscall(common_semi_cb, "isatty,%x", gf->hostfd);
-}
-
 static void gdb_flenfn(CPUState *cs, GuestFD *gf)
 {
     gdb_do_syscall(common_semi_flen_cb, "fstat,%x,%x",
@@ -338,32 +340,23 @@ static const uint8_t featurefile_data[] = {
     SH_EXT_EXIT_EXTENDED | SH_EXT_STDOUT_STDERR, /* Feature byte 0 */
 };
 
-static void staticfile_isattyfn(CPUState *cs, GuestFD *gf)
-{
-    common_semi_cb(cs, 0, 0);
-}
-
 static void staticfile_flenfn(CPUState *cs, GuestFD *gf)
 {
     common_semi_cb(cs, gf->staticfile.len, 0);
 }
 
 typedef struct GuestFDFunctions {
-    sys_isattyfn *isattyfn;
     sys_flenfn *flenfn;
 } GuestFDFunctions;
 
 static const GuestFDFunctions guestfd_fns[] = {
     [GuestFDHost] = {
-        .isattyfn = host_isattyfn,
         .flenfn = host_flenfn,
     },
     [GuestFDGDB] = {
-        .isattyfn = gdb_isattyfn,
         .flenfn = gdb_flenfn,
     },
     [GuestFDStatic] = {
-        .isattyfn = staticfile_isattyfn,
         .flenfn = staticfile_flenfn,
     },
 };
@@ -489,12 +482,7 @@ void do_common_semihosting(CPUState *cs)
 
     case TARGET_SYS_ISTTY:
         GET_ARG(0);
-
-        gf = get_guestfd(arg0);
-        if (!gf) {
-            goto do_badf;
-        }
-        guestfd_fns[gf->type].isattyfn(cs, gf);
+        semihost_sys_isatty(cs, common_semi_istty_cb, arg0);
         break;
 
     case TARGET_SYS_SEEK: