在 2025-10-31星期五的 14:23 +0100,Luca Bonissi写道:
> > From 6ddab7d3ba1035b5e2a6016bde4776436267c18b Mon Sep 17 00:00:00
> > 2001
> From: Luca Bonissi <[email protected]>
> Date: Fri, 31 Oct 2025 13:29:19 +0100
> Subject: [PATCH 1/7] Add termios2 support to linux-user
Sorry but this patch does not build on PowerPC hosts:
```
../linux-user/ioctls.h:4:12: error: ‘TCGETS2’ undeclared here (not in a
function); did you mean ‘TCGETS’?
4 | IOCTL(TCGETS2, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios2)))
| ^~~~~~~
../linux-user/syscall.c:5615:23: note: in definition of macro ‘IOCTL’
5615 | { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
| ^~~
../linux-user/ioctls.h:5:12: error: ‘TCSETS2’ undeclared here (not in a
function); did you mean ‘TCSETS’?
5 | IOCTL(TCSETS2, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios2)))
| ^~~~~~~
../linux-user/syscall.c:5615:23: note: in definition of macro ‘IOCTL’
5615 | { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
| ^~~
../linux-user/ioctls.h:6:12: error: ‘TCSETSW2’ undeclared here (not in
a function); did you mean ‘TCSETSW’?
6 | IOCTL(TCSETSW2, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios2)))
| ^~~~~~~~
../linux-user/syscall.c:5615:23: note: in definition of macro ‘IOCTL’
5615 | { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
| ^~~
../linux-user/ioctls.h:7:12: error: ‘TCSETSF2’ undeclared here (not in
a function); did you mean ‘TCSETSF’?
7 | IOCTL(TCSETSF2, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios2)))
| ^~~~~~~~
../linux-user/syscall.c:5615:23: note: in definition of macro ‘IOCTL’
5615 | { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
| ^~~
../linux-user/syscall.c: In function ‘target_to_host_termios2’:
../linux-user/syscall.c:5940:9: error: invalid use of undefined type
‘struct host_termios2’
5940 | host->c_iflag =
| ^~
../linux-user/syscall.c:5942:9: error: invalid use of undefined type
‘struct host_termios2’
5942 | host->c_oflag =
| ^~
../linux-user/syscall.c:5944:9: error: invalid use of undefined type
‘struct host_termios2’
5944 | host->c_cflag =
| ^~
../linux-user/syscall.c:5946:9: error: invalid use of undefined type
‘struct host_termios2’
5946 | host->c_lflag =
| ^~
../linux-user/syscall.c:5948:9: error: invalid use of undefined type
‘struct host_termios2’
5948 | host->c_line = target->c_line;
| ^~
../linux-user/syscall.c:5949:9: error: invalid use of undefined type
‘struct host_termios2’
5949 | host->c_ispeed = tswap32(target->c_ispeed);
| ^~
../linux-user/syscall.c:5950:9: error: invalid use of undefined type
‘struct host_termios2’
5950 | host->c_ospeed = tswap32(target->c_ospeed);
| ^~
../linux-user/syscall.c:5952:16: error: invalid use of undefined type
‘struct host_termios2’
5952 | memset(host->c_cc, 0, sizeof(host->c_cc));
| ^~
../linux-user/syscall.c:5952:38: error: invalid use of undefined type
‘struct host_termios2’
5952 | memset(host->c_cc, 0, sizeof(host->c_cc));
| ^~
../linux-user/syscall.c:5953:9: error: invalid use of undefined type
‘struct host_termios2’
5953 | host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
| ^~
../linux-user/syscall.c:5954:9: error: invalid use of undefined type
‘struct host_termios2’
5954 | host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
| ^~
../linux-user/syscall.c:5955:9: error: invalid use of undefined type
‘struct host_termios2’
5955 | host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
| ^~
../linux-user/syscall.c:5956:9: error: invalid use of undefined type
‘struct host_termios2’
5956 | host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
| ^~
../linux-user/syscall.c:5957:9: error: invalid use of undefined type
‘struct host_termios2’
5957 | host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
| ^~
../linux-user/syscall.c:5958:9: error: invalid use of undefined type
‘struct host_termios2’
5958 | host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
| ^~
../linux-user/syscall.c:5959:9: error: invalid use of undefined type
‘struct host_termios2’
5959 | host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
| ^~
../linux-user/syscall.c:5960:9: error: invalid use of undefined type
‘struct host_termios2’
5960 | host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
| ^~
../linux-user/syscall.c:5961:9: error: invalid use of undefined type
‘struct host_termios2’
5961 | host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
| ^~
../linux-user/syscall.c:5962:9: error: invalid use of undefined type
‘struct host_termios2’
5962 | host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
| ^~
../linux-user/syscall.c:5963:9: error: invalid use of undefined type
‘struct host_termios2’
5963 | host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
| ^~
../linux-user/syscall.c:5964:9: error: invalid use of undefined type
‘struct host_termios2’
5964 | host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
| ^~
../linux-user/syscall.c:5965:9: error: invalid use of undefined type
‘struct host_termios2’
5965 | host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
| ^~
../linux-user/syscall.c:5966:9: error: invalid use of undefined type
‘struct host_termios2’
5966 | host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
| ^~
../linux-user/syscall.c:5967:9: error: invalid use of undefined type
‘struct host_termios2’
5967 | host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
| ^~
../linux-user/syscall.c:5968:9: error: invalid use of undefined type
‘struct host_termios2’
5968 | host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
| ^~
../linux-user/syscall.c:5969:9: error: invalid use of undefined type
‘struct host_termios2’
5969 | host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
| ^~
In file included from ../linux-user/user-internals.h:21,
from ../linux-user/syscall.c:137:
../linux-user/syscall.c: In function ‘host_to_target_termios2’:
../linux-user/syscall.c:5978:44: error: invalid use of undefined type
‘const struct host_termios2’
5978 | tswap32(host_to_target_bitmask(host->c_iflag,
iflag_tbl));
| ^~
/var/cache/acbs/build/acbs.62hveo8z/qemu-
10.1.2/src.user/include/user/thunk.h:209:32: note: in definition of
macro ‘host_to_target_bitmask’
209 | host_to_target_bitmask_len(M, T, ARRAY_SIZE(T))
| ^
../linux-user/syscall.c:5980:44: error: invalid use of undefined type
‘const struct host_termios2’
5980 | tswap32(host_to_target_bitmask(host->c_oflag,
oflag_tbl));
| ^~
/var/cache/acbs/build/acbs.62hveo8z/qemu-
10.1.2/src.user/include/user/thunk.h:209:32: note: in definition of
macro ‘host_to_target_bitmask’
209 | host_to_target_bitmask_len(M, T, ARRAY_SIZE(T))
| ^
../linux-user/syscall.c:5982:44: error: invalid use of undefined type
‘const struct host_termios2’
5982 | tswap32(host_to_target_bitmask(host->c_cflag,
cflag_tbl));
| ^~
/var/cache/acbs/build/acbs.62hveo8z/qemu-
10.1.2/src.user/include/user/thunk.h:209:32: note: in definition of
macro ‘host_to_target_bitmask’
209 | host_to_target_bitmask_len(M, T, ARRAY_SIZE(T))
| ^
../linux-user/syscall.c:5984:44: error: invalid use of undefined type
‘const struct host_termios2’
5984 | tswap32(host_to_target_bitmask(host->c_lflag,
lflag_tbl));
| ^~
/var/cache/acbs/build/acbs.62hveo8z/qemu-
10.1.2/src.user/include/user/thunk.h:209:32: note: in definition of
macro ‘host_to_target_bitmask’
209 | host_to_target_bitmask_len(M, T, ARRAY_SIZE(T))
| ^
../linux-user/syscall.c:5985:26: error: invalid use of undefined type
‘const struct host_termios2’
5985 | target->c_line = host->c_line;
| ^~
../linux-user/syscall.c:5986:36: error: invalid use of undefined type
‘const struct host_termios2’
5986 | target->c_ispeed = tswap32(host->c_ispeed);
| ^~
../linux-user/syscall.c:5987:36: error: invalid use of undefined type
‘const struct host_termios2’
5987 | target->c_ospeed = tswap32(host->c_ospeed);
| ^~
../linux-user/syscall.c:5990:38: error: invalid use of undefined type
‘const struct host_termios2’
5990 | target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
| ^~
../linux-user/syscall.c:5991:38: error: invalid use of undefined type
‘const struct host_termios2’
5991 | target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
| ^~
../linux-user/syscall.c:5992:39: error: invalid use of undefined type
‘const struct host_termios2’
5992 | target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
| ^~
../linux-user/syscall.c:5993:38: error: invalid use of undefined type
‘const struct host_termios2’
5993 | target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
| ^~
../linux-user/syscall.c:5994:37: error: invalid use of undefined type
‘const struct host_termios2’
5994 | target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
| ^~
../linux-user/syscall.c:5995:38: error: invalid use of undefined type
‘const struct host_termios2’
5995 | target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
| ^~
../linux-user/syscall.c:5996:37: error: invalid use of undefined type
‘const struct host_termios2’
5996 | target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
| ^~
../linux-user/syscall.c:5997:38: error: invalid use of undefined type
‘const struct host_termios2’
5997 | target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
| ^~
../linux-user/syscall.c:5998:39: error: invalid use of undefined type
‘const struct host_termios2’
5998 | target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
| ^~
../linux-user/syscall.c:5999:38: error: invalid use of undefined type
‘const struct host_termios2’
5999 | target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
| ^~
../linux-user/syscall.c:6000:38: error: invalid use of undefined type
‘const struct host_termios2’
6000 | target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
| ^~
../linux-user/syscall.c:6001:37: error: invalid use of undefined type
‘const struct host_termios2’
6001 | target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
| ^~
../linux-user/syscall.c:6002:41: error: invalid use of undefined type
‘const struct host_termios2’
6002 | target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
| ^~
../linux-user/syscall.c:6003:41: error: invalid use of undefined type
‘const struct host_termios2’
6003 | target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
| ^~
../linux-user/syscall.c:6004:40: error: invalid use of undefined type
‘const struct host_termios2’
6004 | target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
| ^~
../linux-user/syscall.c:6005:39: error: invalid use of undefined type
‘const struct host_termios2’
6005 | target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
| ^~
../linux-user/syscall.c:6006:38: error: invalid use of undefined type
‘const struct host_termios2’
6006 | target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
| ^~
../linux-user/syscall.c: At top level:
../linux-user/syscall.c:6011:54: error: invalid application of ‘sizeof’
to incomplete type ‘struct host_termios2’
6011 | .size = { sizeof(struct target_termios2), sizeof(struct
host_termios2) },
| ^~~~~~
../linux-user/syscall.c:6012:65: error: invalid application of
‘__alignof__’ to incomplete type ‘struct host_termios2’
6012 | .align = { __alignof__(struct target_termios2),
__alignof__(struct host_termios2) },
|
^~~~~~
```
(The whole patchset rebased onto v10.1.2)
It seems that PowerPC do not have a `termios2` interface in kernel --
the `termios` here is just `termios2` .
>
> Signed-off-by: Luca Bonissi <[email protected]>
> ---
> linux-user/ioctls.h | 6 +++
> linux-user/strace.c | 69 ++++++++++++++++++++++++++++++
> linux-user/syscall.c | 84
> +++++++++++++++++++++++++++++++++++++
> linux-user/syscall_types.h | 3 ++
> linux-user/user-internals.h | 3 ++
> 5 files changed, 165 insertions(+)
>
> diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
> index 2f62fd2cb9..6ecfe6306e 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/strace.c b/linux-user/strace.c
> index 758c5d32b6..7afb94544f 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -1935,6 +1935,75 @@ 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_ispeed = ");
> + print_raw_param("%u", tswap32(target->c_ispeed), 0);
> +
> + qemu_log("c_ospeed = ");
> + print_raw_param("%u", tswap32(target->c_ospeed), 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 8546f48a05..920bf23406 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -86,6 +86,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 */
> @@ -5885,6 +5886,89 @@ 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;
> + host->c_ispeed = tswap32(target->c_ispeed);
> + host->c_ospeed = tswap32(target->c_ospeed);
> +
> + 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;
> + target->c_ispeed = tswap32(host->c_ispeed);
> + target->c_ospeed = tswap32(host->c_ospeed);
> +
> + 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 7099349ec8..067c02bb93 100644
> --- a/linux-user/user-internals.h
> +++ b/linux-user/user-internals.h
> @@ -129,6 +129,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