linux-user/alpha/termbits.h | 29 ++++++++++++++ linux-user/hppa/termbits.h | 29 ++++++++++++++ linux-user/ioctls.h | 6 +++ linux-user/mips/termbits.h | 31 ++++++++++++-- linux-user/ppc/termbits.h | 24 +++++++++++ linux-user/sh4/termbits.h | 46 +++++++++++++++------ linux-user/sparc/termbits.h | 28 +++++++++++++ linux-user/strace.c | 63 +++++++++++++++++++++++++++++ linux-user/syscall.c | 80 +++++++++++++++++++++++++++++++++++++ linux-user/syscall_types.h | 3 ++ linux-user/user-internals.h | 3 ++ 11 files changed, 326 insertions(+), 16 deletions(-)
From: Luca Bonissi <qemu@bonslack.org>
Date: Fri, 8 Aug 2025 13:30:19 +0200
Subject: [PATCH] Adding termios2 support
glibc 2.42 switched on some architectures (mips*, sh4, or1k) to termios2
ioctl syscalls (TCGETS2, TCSETS2, TCSETSW2, TCSETSF2).
This patch add support to termios2 structure and releated ioctls.
Fixed also wrong TC*2 definition on mips (missing "target_" from "struct
termios2").
Signed-off-by: Luca Bonissi <qemu@bonslack.org>
---
linux-user/alpha/termbits.h | 29 ++++++++++++++
linux-user/hppa/termbits.h | 29 ++++++++++++++
linux-user/ioctls.h | 6 +++
linux-user/mips/termbits.h | 31 ++++++++++++--
linux-user/ppc/termbits.h | 24 +++++++++++
linux-user/sh4/termbits.h | 46 +++++++++++++++------
linux-user/sparc/termbits.h | 28 +++++++++++++
linux-user/strace.c | 63 +++++++++++++++++++++++++++++
linux-user/syscall.c | 80 +++++++++++++++++++++++++++++++++++++
linux-user/syscall_types.h | 3 ++
linux-user/user-internals.h | 3 ++
11 files changed, 326 insertions(+), 16 deletions(-)
diff --git a/linux-user/alpha/termbits.h b/linux-user/alpha/termbits.h
index 4a4b1e96f2..b7be23ea13 100644
--- a/linux-user/alpha/termbits.h
+++ b/linux-user/alpha/termbits.h
@@ -17,6 +17,29 @@ struct target_termios {
target_speed_t c_ospeed; /* output speed */
};
+struct target_termios2 {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_cc_t c_line; /* line discipline (== c_cc[19]) */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
+struct target_ktermios {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_cc_t c_line; /* line discipline (== c_cc[19]) */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
+
/* c_cc characters */
#define TARGET_VEOF 0
#define TARGET_VEOL 1
@@ -247,6 +270,12 @@ struct target_termios {
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */
+#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct target_termios2)
+#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct target_termios2)
+#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct target_termios2)
+#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct target_termios2)
+#define TARGET_TIOCGRS485 TARGET_IOR('T', 0x2E, struct serial_rs485)
+#define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x2F, struct serial_rs485)
#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty
Number (of pty-mux device) */
#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /* Lock/unlock Pty */
#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) /* Safely open
the slave */
diff --git a/linux-user/hppa/termbits.h b/linux-user/hppa/termbits.h
index 11fd4eed62..645f17bf63 100644
--- a/linux-user/hppa/termbits.h
+++ b/linux-user/hppa/termbits.h
@@ -18,6 +18,29 @@ struct target_termios {
target_cc_t c_cc[TARGET_NCCS]; /* control characters */
};
+struct target_termios2 {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_line; /* line discipline */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
+struct target_ktermios {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_line; /* line discipline */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
+
/* c_iflag bits */
#define TARGET_IGNBRK 0000001
#define TARGET_BRKINT 0000002
@@ -190,6 +213,12 @@ struct target_termios {
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
#define TARGET_TIOCGSID TARGET_IOR('T', 20, int)
+#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct
target_termios2)
+#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct
target_termios2)
+#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct
target_termios2)
+#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct
target_termios2)
+#define TARGET_TIOCGRS485 TARGET_IOR('T', 0x2E, struct serial_rs485)
+#define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x2F, struct serial_rs485)
#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int)
/* Get Pty Number (of pty-mux device) */
#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int)
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 3b41128fd7..0b2deb2824 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -1,5 +1,11 @@
/* emulated ioctl list */
+#ifdef TARGET_TCGETS2
+ IOCTL(TCGETS2, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios2)))
+ IOCTL(TCSETS2, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios2)))
+ IOCTL(TCSETSW2, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios2)))
+ IOCTL(TCSETSF2, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios2)))
+#endif
IOCTL(TCGETS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios)))
IOCTL(TCSETS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
IOCTL(TCSETSF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios)))
diff --git a/linux-user/mips/termbits.h b/linux-user/mips/termbits.h
index e8b4b58d87..27610f7c4d 100644
--- a/linux-user/mips/termbits.h
+++ b/linux-user/mips/termbits.h
@@ -18,6 +18,29 @@ struct target_termios {
target_cc_t c_cc[TARGET_NCCS]; /* control characters */
};
+struct target_termios2 {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_line; /* line discipline */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
+struct target_ktermios {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_line; /* line discipline */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
+
/* c_iflag bits */
#define TARGET_IGNBRK 0000001
#define TARGET_BRKINT 0000002
@@ -227,10 +250,10 @@ struct target_termios {
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
#define TARGET_TIOCGSID 0x7416 /* Return the session ID of FD */
-#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct termios2)
-#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct termios2)
-#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct termios2)
-#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct termios2)
+#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct
target_termios2)
+#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct
target_termios2)
+#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct
target_termios2)
+#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct
target_termios2)
#define TARGET_TIOCGRS485 TARGET_IOR('T', 0x2E, struct serial_rs485)
#define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x2F, struct
serial_rs485)
#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty
Number (of pty-mux device) */
diff --git a/linux-user/ppc/termbits.h b/linux-user/ppc/termbits.h
index eb226e0999..ae6ee8897c 100644
--- a/linux-user/ppc/termbits.h
+++ b/linux-user/ppc/termbits.h
@@ -20,6 +20,28 @@ struct target_termios {
target_speed_t c_ospeed; /* output speed */
};
+struct target_termios2 {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_cc_t c_line; /* line discipline */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
+struct target_ktermios {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_cc_t c_line; /* line discipline */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
/* c_cc character offsets */
#define TARGET_VINTR 0
#define TARGET_VQUIT 1
@@ -225,6 +247,8 @@ struct target_termios {
#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */
#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */
#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */
+#define TARGET_TIOCGRS485 0x542e
+#define TARGET_TIOCSRS485 0x542f
#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty
Number (of pty-mux device) */
#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /* Lock/unlock Pty */
#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) /* Safely open
the slave */
diff --git a/linux-user/sh4/termbits.h b/linux-user/sh4/termbits.h
index 28e79f2c9a..cab6b1299e 100644
--- a/linux-user/sh4/termbits.h
+++ b/linux-user/sh4/termbits.h
@@ -18,6 +18,28 @@ struct target_termios {
target_cc_t c_cc[TARGET_NCCS]; /* control characters */
};
+struct target_termios2 {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_line; /* line discipline */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
+struct target_ktermios {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_line; /* line discipline */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
/* c_cc characters */
#define TARGET_VINTR 0
@@ -251,14 +273,17 @@ struct target_termios {
#define TARGET_TIOCNOTTY TARGET_IO('T', 34) /* 0x5422 */
#define TARGET_TIOCSETD TARGET_IOW('T', 35, int) /* 0x5423 */
#define TARGET_TIOCGETD TARGET_IOR('T', 36, int) /* 0x5424 */
-#define TARGET_TCSBRKP TARGET_IOW('T', 37, int) /* 0x5425 */ /*
Needed for POSIX tcse
-ndbreak() */
+#define TARGET_TCSBRKP TARGET_IOW('T', 37, int) /* 0x5425 */ /*
Needed for POSIX tcsendbreak() */
#define TARGET_TIOCSBRK TARGET_IO('T', 39) /* 0x5427 */ /* BSD
compatibility */
#define TARGET_TIOCCBRK TARGET_IO('T', 40) /* 0x5428 */ /* BSD
compatibility */
-#define TARGET_TIOCGSID TARGET_IOR('T', 41, pid_t) /* 0x5429 */
/* Return the session
-ID of FD */
-#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /*
Get Pty Number (of pty-m
-ux device) */
+#define TARGET_TIOCGSID TARGET_IOR('T', 41, pid_t) /* 0x5429 */
/* Return the session ID of FD */
+#define TARGET_TCGETS2 TARGET_IOR('T', 0x2A, struct
target_termios2)
+#define TARGET_TCSETS2 TARGET_IOW('T', 0x2B, struct
target_termios2)
+#define TARGET_TCSETSW2 TARGET_IOW('T', 0x2C, struct
target_termios2)
+#define TARGET_TCSETSF2 TARGET_IOW('T', 0x2D, struct
target_termios2)
+#define TARGET_TIOCGRS485 TARGET_IOR('T', 0x2E, struct serial_rs485)
+#define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x2F, struct serial_rs485)
+#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /*
Get Pty Number (of pty-mux device) */
#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /*
Lock/unlock Pty */
#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) /* Safely open the
slave */
@@ -270,8 +295,7 @@ ux device) */
#define TARGET_TIOCSLCKTRMIOS 0x5457
#define TARGET_TIOCSERGSTRUCT TARGET_IOR('T', 88, int) /* 0x5458 */
/* For d
ebugging only */
-#define TARGET_TIOCSERGETLSR TARGET_IOR('T', 89, unsigned int) /*
0x5459 */ /* Get line sta
-tus register */
+#define TARGET_TIOCSERGETLSR TARGET_IOR('T', 89, unsigned int) /*
0x5459 */ /* Get line status register */
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
# define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */
#define TARGET_TIOCSERGETMULTI TARGET_IOR('T', 90, int) /* 0x545A
@@ -279,9 +303,7 @@ tus register */
#define TARGET_TIOCSERSETMULTI TARGET_IOW('T', 91, int) /* 0x545B
*/ /* Set multiport config */
-#define TARGET_TIOCMIWAIT TARGET_IO('T', 92) /* 0x545C */ /*
wait for a change on
-serial input line(s) */
-#define TARGET_TIOCGICOUNT TARGET_IOR('T', 93, int) /* 0x545D */ /*
read
-serial port inline interrupt counts */
+#define TARGET_TIOCMIWAIT TARGET_IO('T', 92) /* 0x545C */ /*
wait for a change on serial input line(s) */
+#define TARGET_TIOCGICOUNT TARGET_IOR('T', 93, int) /* 0x545D */ /*
read serial port inline interrupt counts */
#endif
diff --git a/linux-user/sparc/termbits.h b/linux-user/sparc/termbits.h
index 704bee1c42..588d7e8dcd 100644
--- a/linux-user/sparc/termbits.h
+++ b/linux-user/sparc/termbits.h
@@ -18,6 +18,28 @@ struct target_termios {
target_cc_t c_cc[TARGET_NCCS]; /* control characters */
};
+struct target_termios2 {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_line; /* line discipline */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
+struct target_ktermios {
+ target_tcflag_t c_iflag; /* input mode flags */
+ target_tcflag_t c_oflag; /* output mode flags */
+ target_tcflag_t c_cflag; /* control mode flags */
+ target_tcflag_t c_lflag; /* local mode flags */
+ target_cc_t c_line; /* line discipline */
+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */
+ target_speed_t c_ispeed; /* input speed */
+ target_speed_t c_ospeed; /* output speed */
+};
+
/* c_cc characters */
#define TARGET_VINTR 0
@@ -251,6 +273,12 @@ struct target_termios {
#define TARGET_TIOCGPGRP TARGET_IOR('t', 131, int)
#define TARGET_TIOCSCTTY TARGET_IO('t', 132)
#define TARGET_TIOCGSID TARGET_IOR('t', 133, int)
+#define TARGET_TCGETS2 TARGET_IOR('T', 12, struct target_termios2)
+#define TARGET_TCSETS2 TARGET_IOW('T', 13, struct target_termios2)
+#define TARGET_TCSETSW2 TARGET_IOW('T', 14, struct target_termios2)
+#define TARGET_TCSETSF2 TARGET_IOW('T', 15, struct target_termios2)
+#define TARGET_TIOCGRS485 TARGET_IOR('T', 0x41, struct serial_rs485)
+#define TARGET_TIOCSRS485 TARGET_IOWR('T', 0x42, struct serial_rs485)
/* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */
#define TARGET_TIOCGPTN TARGET_IOR('t', 134, unsigned int) /* Get Pty
Number */
#define TARGET_TIOCSPTLCK TARGET_IOW('t', 135, int) /* Lock/unlock PTY */
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 3b744ccd4a..aa7556a802 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1929,6 +1929,69 @@ print_termios(void *arg)
qemu_log("}");
}
+#ifdef TARGET_TCGETS2
+void
+print_termios2(void *arg)
+{
+ const struct target_termios2 *target = arg;
+
+ target_tcflag_t iflags = tswap32(target->c_iflag);
+ target_tcflag_t oflags = tswap32(target->c_oflag);
+ target_tcflag_t cflags = tswap32(target->c_cflag);
+ target_tcflag_t lflags = tswap32(target->c_lflag);
+
+ qemu_log("{");
+
+ qemu_log("c_iflag = ");
+ print_flags(termios_iflags, iflags, 0);
+
+ qemu_log("c_oflag = ");
+ target_tcflag_t oflags_clean = oflags & ~(TARGET_NLDLY |
TARGET_CRDLY |
+ TARGET_TABDLY |
TARGET_BSDLY |
+ TARGET_VTDLY |
TARGET_FFDLY);
+ print_flags(termios_oflags, oflags_clean, 0);
+ if (oflags & TARGET_NLDLY) {
+ print_enums(termios_oflags_NLDLY, oflags & TARGET_NLDLY, 0);
+ }
+ if (oflags & TARGET_CRDLY) {
+ print_enums(termios_oflags_CRDLY, oflags & TARGET_CRDLY, 0);
+ }
+ if (oflags & TARGET_TABDLY) {
+ print_enums(termios_oflags_TABDLY, oflags & TARGET_TABDLY, 0);
+ }
+ if (oflags & TARGET_BSDLY) {
+ print_enums(termios_oflags_BSDLY, oflags & TARGET_BSDLY, 0);
+ }
+ if (oflags & TARGET_VTDLY) {
+ print_enums(termios_oflags_VTDLY, oflags & TARGET_VTDLY, 0);
+ }
+ if (oflags & TARGET_FFDLY) {
+ print_enums(termios_oflags_FFDLY, oflags & TARGET_FFDLY, 0);
+ }
+
+ qemu_log("c_cflag = ");
+ if (cflags & TARGET_CBAUD) {
+ print_enums(termios_cflags_CBAUD, cflags & TARGET_CBAUD, 0);
+ }
+ if (cflags & TARGET_CSIZE) {
+ print_enums(termios_cflags_CSIZE, cflags & TARGET_CSIZE, 0);
+ }
+ target_tcflag_t cflags_clean = cflags & ~(TARGET_CBAUD | TARGET_CSIZE);
+ print_flags(termios_cflags, cflags_clean, 0);
+
+ qemu_log("c_lflag = ");
+ print_flags(termios_lflags, lflags, 0);
+
+ qemu_log("c_cc = ");
+ qemu_log("\"%s\",", target->c_cc);
+
+ qemu_log("c_line = ");
+ print_raw_param("\'%c\'", target->c_line, 1);
+
+ qemu_log("}");
+}
+#endif
+
#undef UNUSED
#ifdef TARGET_NR_accept
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 91360a072c..41ef690e52 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -88,6 +88,7 @@
#endif
#define termios host_termios
+#define termios2 host_termios2
#define winsize host_winsize
#define termio host_termio
#define sgttyb host_sgttyb /* same as target */
@@ -5887,6 +5888,85 @@ static const StructEntry struct_termios_def = {
.print = print_termios,
};
+#ifdef TARGET_TCGETS2
+static void target_to_host_termios2 (void *dst, const void *src)
+{
+ struct host_termios2 *host = dst;
+ const struct target_termios2 *target = src;
+
+ host->c_iflag =
+ target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
+ host->c_oflag =
+ target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
+ host->c_cflag =
+ target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
+ host->c_lflag =
+ target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
+ host->c_line = target->c_line;
+
+ memset(host->c_cc, 0, sizeof(host->c_cc));
+ host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
+ host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
+ host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
+ host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
+ host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
+ host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
+ host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
+ host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
+ host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
+ host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
+ host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
+ host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
+ host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
+ host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
+ host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
+ host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
+ host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
+}
+
+static void host_to_target_termios2 (void *dst, const void *src)
+{
+ struct target_termios2 *target = dst;
+ const struct host_termios2 *host = src;
+
+ target->c_iflag =
+ tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
+ target->c_oflag =
+ tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
+ target->c_cflag =
+ tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
+ target->c_lflag =
+ tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
+ target->c_line = host->c_line;
+
+ memset(target->c_cc, 0, sizeof(target->c_cc));
+ target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
+ target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
+ target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
+ target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
+ target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
+ target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
+ target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
+ target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
+ target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
+ target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
+ target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
+ target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
+ target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
+ target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
+ target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
+ target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
+ target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
+}
+
+static const StructEntry struct_termios2_def = {
+ .convert = { host_to_target_termios2, target_to_host_termios2 },
+ .size = { sizeof(struct target_termios2), sizeof(struct
host_termios2) },
+ .align = { __alignof__(struct target_termios2), __alignof__(struct
host_termios2) },
+ .print = print_termios2,
+};
+#endif
+
/* If the host does not provide these bits, they may be safely
discarded. */
#ifndef MAP_SYNC
#define MAP_SYNC 0
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 6dd7a80ce5..ac45705acf 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -1,4 +1,7 @@
STRUCT_SPECIAL(termios)
+#ifdef TARGET_TCGETS2
+STRUCT_SPECIAL(termios2)
+#endif
STRUCT(winsize,
TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT)
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
index 691b9a1775..191e01c3a8 100644
--- a/linux-user/user-internals.h
+++ b/linux-user/user-internals.h
@@ -127,6 +127,9 @@ static inline uint64_t target_offset64(uint64_t
word0, uint64_t word1)
#endif /* TARGET_ABI_BITS != 32 */
void print_termios(void *arg);
+#ifdef TARGET_TCGETS2
+void print_termios2(void *arg);
+#endif
/* ARM EABI and MIPS expect 64bit types aligned even on pairs or
registers */
#ifdef TARGET_ARM
--
2.50.1
On 8/8/25 22:16, Luca Bonissi wrote: > From: Luca Bonissi <qemu@bonslack.org> > Date: Fri, 8 Aug 2025 13:30:19 +0200 > Subject: [PATCH] Adding termios2 support > > glibc 2.42 switched on some architectures (mips*, sh4, or1k) to termios2 ioctl syscalls > (TCGETS2, TCSETS2, TCSETSW2, TCSETSF2). > This patch add support to termios2 structure and releated ioctls. > > Fixed also wrong TC*2 definition on mips (missing "target_" from "struct termios2"). > > Signed-off-by: Luca Bonissi <qemu@bonslack.org> This looks plausible, but (1) It does too much in one patch, (2) It now needs updating for master, (3) It came through email malformed. You can do all of the generic #ifdef TARGET_TCGETS2 stuff first, then take care of each architecture one by one. r~
© 2016 - 2025 Red Hat, Inc.