aboutsummaryrefslogtreecommitdiff
path: root/semihosting/syscalls.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/syscalls.c
parent9a89470449a5171eb1bd06f681361e0888d15cf7 (diff)
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/syscalls.c')
-rw-r--r--semihosting/syscalls.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 9e3eb464b5..1f1baf7e2d 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -121,6 +121,12 @@ static void gdb_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
(target_ulong)gf->hostfd, off, (target_ulong)gdb_whence);
}
+static void gdb_isatty(CPUState *cs, gdb_syscall_complete_cb complete,
+ GuestFD *gf)
+{
+ gdb_do_syscall(complete, "isatty,%x", (target_ulong)gf->hostfd);
+}
+
/*
* Host semihosting syscall implementations.
*/
@@ -246,6 +252,13 @@ static void host_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
complete(cs, ret, err);
}
+static void host_isatty(CPUState *cs, gdb_syscall_complete_cb complete,
+ GuestFD *gf)
+{
+ int ret = isatty(gf->hostfd);
+ complete(cs, ret, ret ? 0 : errno);
+}
+
/*
* Static file semihosting syscall implementations.
*/
@@ -437,3 +450,26 @@ void semihost_sys_lseek(CPUState *cs, gdb_syscall_complete_cb complete,
g_assert_not_reached();
}
}
+
+void semihost_sys_isatty(CPUState *cs, gdb_syscall_complete_cb complete, int fd)
+{
+ GuestFD *gf = get_guestfd(fd);
+
+ if (!gf) {
+ complete(cs, 0, EBADF);
+ return;
+ }
+ switch (gf->type) {
+ case GuestFDGDB:
+ gdb_isatty(cs, complete, gf);
+ break;
+ case GuestFDHost:
+ host_isatty(cs, complete, gf);
+ break;
+ case GuestFDStatic:
+ complete(cs, 0, ENOTTY);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}