[PATCH] Adding termios2 support

Luca Bonissi posted 1 patch 3 months, 1 week ago
Failed in applying to current master (apply log)
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(-)
[PATCH] Adding termios2 support
Posted by Luca Bonissi 3 months, 1 week ago
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
Re: [PATCH] Adding termios2 support
Posted by Richard Henderson 2 months, 2 weeks ago
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~