Skip to content

Commit 4af0789

Browse files
committed
Support TCGETS2 and TCSETS2.
Fixes #2430
1 parent 447d762 commit 4af0789

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

src/record_syscall.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,23 @@
103103

104104
using namespace std;
105105

106+
// The kernel header that defines this conflicts badly with glibc headers
107+
// so we define it ourselves.
108+
// NB: We need this struct defined so that the preprocessor macro for
109+
// TCGETS2 will evaluate. But we use IOCTL_MASK_SIZE on it and we use
110+
// the size from the tracee to determine how many bytes to record, so
111+
// we don't actually depend on this being *accurate*.
112+
struct termios2 {
113+
tcflag_t c_iflag;
114+
tcflag_t c_oflag;
115+
tcflag_t c_cflag;
116+
tcflag_t c_lflag;
117+
cc_t c_line;
118+
cc_t c_cc[19];
119+
speed_t c_ispeed;
120+
speed_t c_ospeed;
121+
};
122+
106123
namespace rr {
107124

108125
union _semun {
@@ -1943,6 +1960,7 @@ static Switchable prepare_ioctl(RecordTask* t,
19431960
case IOCTL_MASK_SIZE(TUNSETIFINDEX):
19441961
case IOCTL_MASK_SIZE(TUNSETVNETLE):
19451962
case IOCTL_MASK_SIZE(TUNSETVNETBE):
1963+
case IOCTL_MASK_SIZE(TCSETS2):
19461964
return PREVENT_SWITCH;
19471965
case IOCTL_MASK_SIZE(USBDEVFS_GETDRIVER):
19481966
// Reads and writes its parameter despite not having the _IOC_READ bit.
@@ -2078,6 +2096,7 @@ static Switchable prepare_ioctl(RecordTask* t,
20782096
case IOCTL_MASK_SIZE(OTPGETREGIONINFO):
20792097
case IOCTL_MASK_SIZE(ECCGETLAYOUT):
20802098
case IOCTL_MASK_SIZE(ECCGETSTATS):
2099+
case IOCTL_MASK_SIZE(TCGETS2):
20812100
syscall_state.reg_parameter(3, size);
20822101
return PREVENT_SWITCH;
20832102

src/test/ioctl_tty.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,26 @@
22

33
#include "util.h"
44

5+
/* We have to define termios2 ourselves. See
6+
* https://github.com/npat-efault/picocom/blob/1acf1ddabaf3576b4023c4f6f09c5a3e4b086fb8/termios2.txt
7+
* for the long explanation.
8+
*/
9+
struct termios2 {
10+
tcflag_t c_iflag;
11+
tcflag_t c_oflag;
12+
tcflag_t c_cflag;
13+
tcflag_t c_lflag;
14+
cc_t c_line;
15+
cc_t c_cc[19];
16+
speed_t c_ispeed;
17+
speed_t c_ospeed;
18+
};
19+
520
int main(void) {
621
int fd;
722
int ret;
823
struct termios* tc;
24+
struct termios2* tc2;
925
struct termio* tio;
1026
pid_t* pgrp;
1127
int* navail;
@@ -94,6 +110,19 @@ int main(void) {
94110
VERIFY_GUARD(nread);
95111
atomic_printf("FIONREAD returned nread=%d\n", *nread);
96112

113+
ALLOCATE_GUARD(tc2, 'i');
114+
test_assert(0 == ioctl(fd, TCGETS2, tc));
115+
VERIFY_GUARD(tc2);
116+
atomic_printf("TCGETS2 returned { iflag=0x%x, oflag=0x%x, cflag=0x%x, "
117+
"lflag=0x%x, ispeed=%d, ospeed=%d }\n",
118+
tc2->c_iflag, tc2->c_oflag, tc2->c_cflag, tc2->c_lflag,
119+
tc2->c_ispeed, tc2->c_ospeed);
120+
test_assert(0 == ioctl(fd, TCSETS2, tc2));
121+
122+
// NB: leaving the TCSETS2 as the last word seems to mess up the terminal,
123+
// so fix it.
124+
test_assert(0 == ioctl(fd, TCSETS, tc));
125+
97126
atomic_puts("EXIT-SUCCESS");
98127
return 0;
99128
}

0 commit comments

Comments
 (0)