linux-user: Add termios2 support
Signed-off-by: Luca Bonissi <qemu@bonslack.org> Link: https://lore.kernel.org/qemu-devel/745f18b6-ee62-4903-9a56-dcb903b610cf@bonslack.org Reviewed-by: Helge Deller <deller@gmx.de> Tested-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> (cherry picked from commit e9a8a10e84c1bf6e2e8be000e4dd5c83ba0d8470) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
parent
ba3581de79
commit
5380228f7f
5 changed files with 165 additions and 0 deletions
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -5888,6 +5889,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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
STRUCT_SPECIAL(termios)
|
||||
#ifdef TARGET_TCGETS2
|
||||
STRUCT_SPECIAL(termios2)
|
||||
#endif
|
||||
|
||||
STRUCT(winsize,
|
||||
TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue