term: improve decoding of termios and termio structures
This commit is contained in:
@ -283,6 +283,12 @@ AC_CHECK_TYPES([struct stat64, struct __old_kernel_stat],,,
|
||||
[#include <sys/types.h>
|
||||
#include <asm/stat.h>])
|
||||
|
||||
AC_CHECK_TYPES([struct termios2],,,
|
||||
[#include <linux/termios.h>])
|
||||
|
||||
AC_CHECK_MEMBERS([struct termios.c_ispeed, struct termios.c_ospeed],,,
|
||||
[#include <linux/termios.h>])
|
||||
|
||||
AC_CHECK_TYPES([struct user_desc],
|
||||
[AC_CHECK_MEMBERS([struct user_desc.lm],,,
|
||||
[#include <asm/ldt.h>])],,
|
||||
|
279
term.c
279
term.c
@ -18,6 +18,151 @@
|
||||
#include "xlat/baud_options.h"
|
||||
#include "xlat/modem_flags.h"
|
||||
|
||||
#include "xlat/term_cflags.h"
|
||||
#include "xlat/term_cflags_csize.h"
|
||||
#include "xlat/term_iflags.h"
|
||||
#include "xlat/term_lflags.h"
|
||||
#include "xlat/term_oflags.h"
|
||||
#include "xlat/term_oflags_bsdly.h"
|
||||
#include "xlat/term_oflags_crdly.h"
|
||||
#include "xlat/term_oflags_ffdly.h"
|
||||
#include "xlat/term_oflags_nldly.h"
|
||||
#include "xlat/term_oflags_tabdly.h"
|
||||
#include "xlat/term_oflags_vtdly.h"
|
||||
|
||||
#include "xlat/term_line_discs.h"
|
||||
|
||||
#include "xlat/termio_cc.h"
|
||||
#include "xlat/termios_cc.h"
|
||||
|
||||
static void
|
||||
decode_oflag(uint64_t val)
|
||||
{
|
||||
static const struct {
|
||||
const struct xlat *xl;
|
||||
uint64_t mask;
|
||||
const char *dfl;
|
||||
} xlats[] = {
|
||||
{ term_oflags_nldly, NLDLY, "NL?" },
|
||||
{ term_oflags_crdly, CRDLY, "CR?" },
|
||||
{ term_oflags_tabdly, TABDLY, "TAB?" },
|
||||
{ term_oflags_bsdly, BSDLY, "BS?" },
|
||||
{ term_oflags_vtdly, VTDLY, "VT?" },
|
||||
{ term_oflags_ffdly, FFDLY, "FF?" },
|
||||
};
|
||||
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(xlats); i++) {
|
||||
printxval64(xlats[i].xl, val & xlats[i].mask, xlats[i].dfl);
|
||||
tprints("|");
|
||||
|
||||
val &= ~xlats[i].mask;
|
||||
}
|
||||
|
||||
printflags64(term_oflags, val, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_cflag(uint64_t val)
|
||||
{
|
||||
printxval64(baud_options, val & CBAUD, "B???");
|
||||
tprints("|");
|
||||
if (val & CIBAUD) {
|
||||
printxval64(baud_options, (val & CIBAUD) >> IBSHIFT, "B???");
|
||||
tprintf("<<IBSHIFT|");
|
||||
}
|
||||
printxval64(term_cflags_csize, val & CSIZE, "CS?");
|
||||
tprints("|");
|
||||
|
||||
val &= ~(CBAUD | CIBAUD | CSIZE);
|
||||
printflags64(term_cflags, val, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_flags(uint64_t iflag, uint64_t oflag, uint64_t cflag, uint64_t lflag)
|
||||
{
|
||||
tprints("c_iflag=");
|
||||
printflags64(term_iflags, iflag, NULL);
|
||||
tprints(", c_oflag=");
|
||||
decode_oflag(oflag);
|
||||
tprints(", c_cflag=");
|
||||
decode_cflag(cflag);
|
||||
tprints(", c_lflag=");
|
||||
printflags64(term_lflags, lflag, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_line_disc(uint64_t line)
|
||||
{
|
||||
tprints("c_line=");
|
||||
printxval(term_line_discs, line, "N_???");
|
||||
}
|
||||
|
||||
static void
|
||||
print_cc_char(bool *first, const unsigned char *data, const char *s,
|
||||
unsigned idx)
|
||||
{
|
||||
if (*first)
|
||||
*first = false;
|
||||
else
|
||||
tprints(", ");
|
||||
|
||||
if (s)
|
||||
tprintf("[%s] = ", s);
|
||||
else
|
||||
tprintf("[%u] = ", idx);
|
||||
|
||||
tprintf("%#hhx", data[idx]);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_term_cc(const struct xlat *xl, const unsigned char *data, unsigned size)
|
||||
{
|
||||
unsigned i = 0;
|
||||
bool first = true;
|
||||
|
||||
tprints("[");
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
print_cc_char(&first, data, xlookup(xl, i), i);
|
||||
|
||||
tprints("]");
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRUCT_TERMIOS2
|
||||
static void
|
||||
decode_termios2(struct tcb *const tcp, const kernel_ulong_t addr)
|
||||
{
|
||||
struct termios2 tios;
|
||||
|
||||
tprints(", ");
|
||||
if (umove_or_printaddr(tcp, addr, &tios))
|
||||
return;
|
||||
|
||||
tprints("{");
|
||||
decode_flags(tios.c_iflag, tios.c_oflag, tios.c_cflag, tios.c_lflag);
|
||||
tprints(", ");
|
||||
|
||||
if (abbrev(tcp)) {
|
||||
tprints("...");
|
||||
} else {
|
||||
decode_line_disc(tios.c_line);
|
||||
|
||||
if (!(tios.c_lflag & ICANON))
|
||||
tprintf(", c_cc[VMIN]=%u, c_cc[VTIME]=%u",
|
||||
tios.c_cc[VMIN], tios.c_cc[VTIME]);
|
||||
tprints(", c_cc=");
|
||||
/* SPARC has two additional bytes in c_cc. */
|
||||
decode_term_cc(termios_cc, tios.c_cc, sizeof(tios.c_cc));
|
||||
|
||||
tprintf(", c_ispeed=%u", tios.c_ispeed);
|
||||
tprintf(", c_ospeed=%u", tios.c_ospeed);
|
||||
}
|
||||
tprints("}");
|
||||
}
|
||||
#endif /* HAVE_STRUCT_TERMIOS2 */
|
||||
|
||||
static void
|
||||
decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
|
||||
{
|
||||
@ -26,26 +171,38 @@ decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
|
||||
tprints(", ");
|
||||
if (umove_or_printaddr(tcp, addr, &tios))
|
||||
return;
|
||||
|
||||
tprints("{");
|
||||
decode_flags(tios.c_iflag, tios.c_oflag, tios.c_cflag, tios.c_lflag);
|
||||
tprints(", ");
|
||||
|
||||
if (abbrev(tcp)) {
|
||||
tprints("{");
|
||||
printxval(baud_options, tios.c_cflag & CBAUD, "B???");
|
||||
tprintf(" %sopost %sisig %sicanon %secho ...}",
|
||||
(tios.c_oflag & OPOST) ? "" : "-",
|
||||
(tios.c_lflag & ISIG) ? "" : "-",
|
||||
(tios.c_lflag & ICANON) ? "" : "-",
|
||||
(tios.c_lflag & ECHO) ? "" : "-");
|
||||
return;
|
||||
tprints("...");
|
||||
} else {
|
||||
decode_line_disc(tios.c_line);
|
||||
|
||||
if (!(tios.c_lflag & ICANON))
|
||||
tprintf(", c_cc[VMIN]=%u, c_cc[VTIME]=%u",
|
||||
tios.c_cc[VMIN], tios.c_cc[VTIME]);
|
||||
tprints(", c_cc=");
|
||||
/*
|
||||
* Fun fact: MIPS has NCCS defined to 23, SPARC to 17 and
|
||||
* everything else to 19.
|
||||
*/
|
||||
decode_term_cc(termios_cc, tios.c_cc,
|
||||
MIN(NCCS, sizeof(tios.c_cc)));
|
||||
|
||||
/*
|
||||
* alpha and powerpc have those in struct termios instead of
|
||||
* having a separate struct termios2.
|
||||
*/
|
||||
#ifdef HAVE_STRUCT_TERMIOS_C_ISPEED
|
||||
tprintf(", c_ispeed=%u", tios.c_ispeed);
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_TERMIOS_C_OSPEED
|
||||
tprintf(", c_ospeed=%u", tios.c_ospeed);
|
||||
#endif
|
||||
}
|
||||
tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
|
||||
(long) tios.c_iflag, (long) tios.c_oflag);
|
||||
tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
|
||||
(long) tios.c_cflag, (long) tios.c_lflag);
|
||||
tprintf("c_line=%u, ", tios.c_line);
|
||||
if (!(tios.c_lflag & ICANON))
|
||||
tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
|
||||
tios.c_cc[VMIN], tios.c_cc[VTIME]);
|
||||
tprints("c_cc=");
|
||||
print_quoted_string((char *) tios.c_cc, NCCS, QUOTE_FORCE_HEX);
|
||||
tprints("}");
|
||||
}
|
||||
|
||||
@ -53,39 +210,40 @@ static void
|
||||
decode_termio(struct tcb *const tcp, const kernel_ulong_t addr)
|
||||
{
|
||||
struct termio tio;
|
||||
int i;
|
||||
|
||||
tprints(", ");
|
||||
if (umove_or_printaddr(tcp, addr, &tio))
|
||||
return;
|
||||
|
||||
tprints("{");
|
||||
decode_flags(tio.c_iflag, tio.c_oflag, tio.c_cflag, tio.c_lflag);
|
||||
tprints(", ");
|
||||
|
||||
if (abbrev(tcp)) {
|
||||
tprints("{");
|
||||
printxval(baud_options, tio.c_cflag & CBAUD, "B???");
|
||||
tprintf(" %sopost %sisig %sicanon %secho ...}",
|
||||
(tio.c_oflag & OPOST) ? "" : "-",
|
||||
(tio.c_lflag & ISIG) ? "" : "-",
|
||||
(tio.c_lflag & ICANON) ? "" : "-",
|
||||
(tio.c_lflag & ECHO) ? "" : "-");
|
||||
return;
|
||||
}
|
||||
tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
|
||||
(long) tio.c_iflag, (long) tio.c_oflag);
|
||||
tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
|
||||
(long) tio.c_cflag, (long) tio.c_lflag);
|
||||
tprintf("c_line=%u, ", tio.c_line);
|
||||
#ifdef _VMIN
|
||||
if (!(tio.c_lflag & ICANON))
|
||||
tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ",
|
||||
tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
|
||||
tprints("...");
|
||||
} else {
|
||||
decode_line_disc(tio.c_line);
|
||||
|
||||
#ifdef _VMIN /* thanks, alpha and powerpc */
|
||||
if (!(tio.c_lflag & ICANON))
|
||||
tprintf(", c_cc[_VMIN]=%d, c_cc[_VTIME]=%d",
|
||||
tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
|
||||
|
||||
tprints(", c_cc=");
|
||||
decode_term_cc(termio_cc, tio.c_cc,
|
||||
MIN(NCC, sizeof(tio.c_cc)));
|
||||
#else /* !_VMIN */
|
||||
if (!(tio.c_lflag & ICANON))
|
||||
tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
|
||||
tio.c_cc[VMIN], tio.c_cc[VTIME]);
|
||||
if (!(tio.c_lflag & ICANON))
|
||||
tprintf(", c_cc[VMIN]=%d, c_cc[VTIME]=%d",
|
||||
tio.c_cc[VMIN], tio.c_cc[VTIME]);
|
||||
|
||||
tprints(", c_cc=");
|
||||
decode_term_cc(termios_cc, tio.c_cc,
|
||||
MIN(NCC, sizeof(tio.c_cc)));
|
||||
#endif /* !_VMIN */
|
||||
tprints("c_cc=\"");
|
||||
for (i = 0; i < NCC; i++)
|
||||
tprintf("\\x%02x", tio.c_cc[i]);
|
||||
tprints("\"}");
|
||||
}
|
||||
|
||||
tprints("}");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -132,27 +290,36 @@ term_ioctl(struct tcb *const tcp, const unsigned int code,
|
||||
const kernel_ulong_t arg)
|
||||
{
|
||||
switch (code) {
|
||||
#ifdef HAVE_STRUCT_TERMIOS2
|
||||
/* struct termios2 */
|
||||
# ifdef TCGETS2
|
||||
case TCGETS2:
|
||||
# endif
|
||||
if (entering(tcp))
|
||||
return 0;
|
||||
ATTRIBUTE_FALLTHROUGH;
|
||||
# ifdef TCSETS2
|
||||
case TCSETS2:
|
||||
# endif
|
||||
# ifdef TCSETSW2
|
||||
case TCSETSW2:
|
||||
# endif
|
||||
# ifdef TCSETSF2
|
||||
case TCSETSF2:
|
||||
# endif
|
||||
decode_termios2(tcp, arg);
|
||||
break;
|
||||
#endif /* HAVE_STRUCT_TERMIOS2 */
|
||||
|
||||
/* struct termios */
|
||||
case TCGETS:
|
||||
#ifdef TCGETS2
|
||||
case TCGETS2:
|
||||
#endif
|
||||
case TIOCGLCKTRMIOS:
|
||||
if (entering(tcp))
|
||||
return 0;
|
||||
ATTRIBUTE_FALLTHROUGH;
|
||||
case TCSETS:
|
||||
#ifdef TCSETS2
|
||||
case TCSETS2:
|
||||
#endif
|
||||
case TCSETSW:
|
||||
#ifdef TCSETSW2
|
||||
case TCSETSW2:
|
||||
#endif
|
||||
case TCSETSF:
|
||||
#ifdef TCSETSF2
|
||||
case TCSETSF2:
|
||||
#endif
|
||||
case TIOCSLCKTRMIOS:
|
||||
decode_termios(tcp, arg);
|
||||
break;
|
||||
|
@ -15,11 +15,15 @@ B9600
|
||||
B19200
|
||||
B38400
|
||||
B57600
|
||||
B76800
|
||||
B115200
|
||||
B153600
|
||||
B230400
|
||||
B307200
|
||||
B460800
|
||||
B500000
|
||||
B576000
|
||||
B614400
|
||||
B921600
|
||||
B1000000
|
||||
B1152000
|
||||
@ -31,3 +35,4 @@ B3500000
|
||||
B4000000
|
||||
EXTA
|
||||
EXTB
|
||||
BOTHER
|
||||
|
9
xlat/term_cflags.in
Normal file
9
xlat/term_cflags.in
Normal file
@ -0,0 +1,9 @@
|
||||
CSTOPB
|
||||
CREAD
|
||||
PARENB
|
||||
PARODD
|
||||
HUPCL
|
||||
CLOCAL
|
||||
CTVB /* VisioBraille Terminal flow control */
|
||||
CMSPAR /* mark or space (stick) parity */
|
||||
CRTSCTS /* flow control */
|
4
xlat/term_cflags_csize.in
Normal file
4
xlat/term_cflags_csize.in
Normal file
@ -0,0 +1,4 @@
|
||||
CS5
|
||||
CS6
|
||||
CS7
|
||||
CS8
|
15
xlat/term_iflags.in
Normal file
15
xlat/term_iflags.in
Normal file
@ -0,0 +1,15 @@
|
||||
IGNBRK /* Ignore break condition. */
|
||||
BRKINT /* Signal interrupt on break. */
|
||||
IGNPAR /* Ignore characters with parity errors. */
|
||||
PARMRK /* Mark parity and framing errors. */
|
||||
INPCK /* Enable input parity check. */
|
||||
ISTRIP /* Strip 8th bit off characters. */
|
||||
INLCR /* Map NL to CR on input. */
|
||||
IGNCR /* Ignore CR. */
|
||||
ICRNL /* Map CR to NL on input. */
|
||||
IUCLC /* Map upper case to lower case on input. */
|
||||
IXON /* Enable start/stop output control. */
|
||||
IXANY /* Any character will restart after stop. */
|
||||
IXOFF /* Enable start/stop input control. */
|
||||
IMAXBEL /* Ring bell when input queue is full. */
|
||||
IUTF8 /* Input is UTF-8 */
|
18
xlat/term_lflags.in
Normal file
18
xlat/term_lflags.in
Normal file
@ -0,0 +1,18 @@
|
||||
ISIG /* Enable signals. */
|
||||
ICANON /* Do erase and kill processing. */
|
||||
XCASE
|
||||
ECHO /* Enable echo. */
|
||||
ECHOE /* Visual erase for ERASE. */
|
||||
ECHOK /* Echo NL after KILL. */
|
||||
ECHONL /* Echo NL even if ECHO is off. */
|
||||
NOFLSH /* Disable flush after interrupt. */
|
||||
IEXTEN /* Enable DISCARD and LNEXT. */
|
||||
ECHOCTL /* Echo control characters as ^X. */
|
||||
ECHOPRT /* Hardcopy visual erase. */
|
||||
ECHOKE /* Visual erase for KILL. */
|
||||
FLUSHO
|
||||
PENDIN /* Retype pending input (state). */
|
||||
TOSTOP /* Send SIGTTOU for background output. */
|
||||
EXTPROC /* External processing on pty */
|
||||
|
||||
DEFECHO /* SUNOS thing, what is it? */
|
28
xlat/term_line_discs.in
Normal file
28
xlat/term_line_discs.in
Normal file
@ -0,0 +1,28 @@
|
||||
N_TTY 0
|
||||
N_SLIP 1
|
||||
N_MOUSE 2
|
||||
N_PPP 3
|
||||
N_STRIP 4
|
||||
N_AX25 5
|
||||
N_X25 6 /* X.25 async */
|
||||
N_6PACK 7
|
||||
N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
|
||||
N_R3964 9 /* Reserved for Simatic R3964 module */
|
||||
N_PROFIBUS_FDL 10 /* Reserved for Profibus */
|
||||
N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */
|
||||
N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */
|
||||
N_HDLC 13 /* synchronous HDLC */
|
||||
N_SYNC_PPP 14 /* synchronous PPP */
|
||||
N_HCI 15 /* Bluetooth HCI UART */
|
||||
N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */
|
||||
N_SLCAN 17 /* Serial / USB serial CAN Adaptors */
|
||||
N_PPS 18 /* Pulse per Second */
|
||||
N_V253 19 /* Codec control over voice modem */
|
||||
N_CAIF 20 /* CAIF protocol for talking to modems */
|
||||
N_GSM0710 21 /* GSM 0710 Mux */
|
||||
N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */
|
||||
N_TRACESINK 23 /* Trace data routing for MIPI P1149.7 */
|
||||
N_TRACEROUTER 24 /* Trace data routing for MIPI P1149.7 */
|
||||
N_NCI 25 /* NFC NCI UART */
|
||||
N_SPEAKUP 26 /* Speakup communication with synths */
|
||||
N_NULL 27 /* Null ldisc used for error handling */
|
15
xlat/term_oflags.in
Normal file
15
xlat/term_oflags.in
Normal file
@ -0,0 +1,15 @@
|
||||
#ifdef ALPHA
|
||||
XTABS /* required by POSIX to == TAB3; but not on Alpha! */
|
||||
#endif
|
||||
|
||||
OPOST /* Perform output processing. */
|
||||
OLCUC /* Map lower case to upper case on output. */
|
||||
ONLCR /* Map NL to CR-NL on output. */
|
||||
OCRNL
|
||||
ONOCR
|
||||
ONLRET
|
||||
OFILL
|
||||
OFDEL
|
||||
|
||||
PAGEOUT /* SUNOS specific */
|
||||
WRAP /* SUNOS specific */
|
2
xlat/term_oflags_bsdly.in
Normal file
2
xlat/term_oflags_bsdly.in
Normal file
@ -0,0 +1,2 @@
|
||||
BS1
|
||||
BS0
|
4
xlat/term_oflags_crdly.in
Normal file
4
xlat/term_oflags_crdly.in
Normal file
@ -0,0 +1,4 @@
|
||||
CR0
|
||||
CR1
|
||||
CR2
|
||||
CR3
|
2
xlat/term_oflags_ffdly.in
Normal file
2
xlat/term_oflags_ffdly.in
Normal file
@ -0,0 +1,2 @@
|
||||
FF0
|
||||
FF1
|
4
xlat/term_oflags_nldly.in
Normal file
4
xlat/term_oflags_nldly.in
Normal file
@ -0,0 +1,4 @@
|
||||
NL0
|
||||
NL1
|
||||
NL2
|
||||
NL3
|
8
xlat/term_oflags_tabdly.in
Normal file
8
xlat/term_oflags_tabdly.in
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef ALPHA
|
||||
XTABS /* required by POSIX to == TAB3; but not on Alpha! */
|
||||
#endif
|
||||
|
||||
TAB0
|
||||
TAB1
|
||||
TAB2
|
||||
TAB3
|
2
xlat/term_oflags_vtdly.in
Normal file
2
xlat/term_oflags_vtdly.in
Normal file
@ -0,0 +1,2 @@
|
||||
VT0
|
||||
VT1
|
10
xlat/termio_cc.in
Normal file
10
xlat/termio_cc.in
Normal file
@ -0,0 +1,10 @@
|
||||
_VINTR
|
||||
_VQUIT
|
||||
_VERASE
|
||||
_VKILL
|
||||
_VEOF
|
||||
_VMIN
|
||||
_VEOL
|
||||
_VTIME
|
||||
_VEOL2
|
||||
_VSWTC
|
18
xlat/termios_cc.in
Normal file
18
xlat/termios_cc.in
Normal file
@ -0,0 +1,18 @@
|
||||
VINTR /* Interrupt character [ISIG]. */
|
||||
VQUIT /* Quit character [ISIG]. */
|
||||
VERASE /* Erase character [ICANON]. */
|
||||
VKILL /* Kill-line character [ICANON]. */
|
||||
VEOL2 /* Second EOL character [ICANON]. */
|
||||
VSWTC /* ??? */
|
||||
VSTART /* Start (X-ON) character [IXON, IXOFF]. */
|
||||
VSTOP /* Stop (X-OFF) character [IXON, IXOFF]. */
|
||||
VSUSP /* Suspend character [ISIG]. */
|
||||
VDSUSP /* Delayed suspend character [ISIG]. */
|
||||
VREPRINT /* Reprint-line character [ICANON]. */
|
||||
VDISCARD /* Discard character [IEXTEN]. */
|
||||
VWERASE /* Word-erase character [ICANON]. */
|
||||
VLNEXT /* Literal-next character [IEXTEN]. */
|
||||
VEOF /* End-of-file character [ICANON]. */
|
||||
VEOL /* End-of-line character [ICANON]. */
|
||||
VMIN /* Minimum number of bytes read at once [!ICANON]. */
|
||||
VTIME /* Time-out value (tenths of a second) [!ICANON]. */
|
Reference in New Issue
Block a user