[PATCH 3/3] term: improve decoding of termios and termio structures

Eugene Syromyatnikov evgsyr at gmail.com
Wed Sep 13 19:57:50 UTC 2017


---
 term.c                     | 145 ++++++++++++++++++++++++++++++++++++++-------
 xlat/term_cflags.in        |   9 +++
 xlat/term_cflags_csize.in  |   4 ++
 xlat/term_iflags.in        |  15 +++++
 xlat/term_lflags.in        |  17 ++++++
 xlat/term_oflags.in        |  15 +++++
 xlat/term_oflags_bsdly.in  |   2 +
 xlat/term_oflags_crdly.in  |   4 ++
 xlat/term_oflags_ffdly.in  |   2 +
 xlat/term_oflags_nldly.in  |   4 ++
 xlat/term_oflags_tabdly.in |   8 +++
 xlat/term_oflags_vtdly.in  |   2 +
 xlat/termio_cc.in          |  10 ++++
 xlat/termios_cc.in         |  18 ++++++
 14 files changed, 234 insertions(+), 21 deletions(-)
 create mode 100644 xlat/term_cflags.in
 create mode 100644 xlat/term_cflags_csize.in
 create mode 100644 xlat/term_iflags.in
 create mode 100644 xlat/term_lflags.in
 create mode 100644 xlat/term_oflags.in
 create mode 100644 xlat/term_oflags_bsdly.in
 create mode 100644 xlat/term_oflags_crdly.in
 create mode 100644 xlat/term_oflags_ffdly.in
 create mode 100644 xlat/term_oflags_nldly.in
 create mode 100644 xlat/term_oflags_tabdly.in
 create mode 100644 xlat/term_oflags_vtdly.in
 create mode 100644 xlat/termio_cc.in
 create mode 100644 xlat/termios_cc.in

diff --git a/term.c b/term.c
index 28f562f..25497b9 100644
--- a/term.c
+++ b/term.c
@@ -38,6 +38,121 @@
 #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/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_bsdly,  BSDLY,  "BS?"  },
+		{ term_oflags_crdly,  CRDLY,  "CR?"  },
+		{ term_oflags_ffdly,  FFDLY,  "FF?"  },
+		{ term_oflags_nldly,  NLDLY,  "NL?"  },
+		{ term_oflags_tabdly, TABDLY, "TAB?" },
+		{ term_oflags_vtdly,  VTDLY,  "VT?"  },
+	};
+
+	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("|");
+	printxval64(baud_options, (val & CIBAUD) >> IBSHIFT, "B???");
+	tprintf("<<IBSHIFT|");
+	printxval64(term_cflags_csize, val & CSIZE, "CS?");
+	tprints("|");
+
+	val &= ~(CBAUD | CIBAUD | CSIZE);
+	printxval64(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
+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)
+{
+	uint64_t not_printed = (1ULL << size) - 1;
+	unsigned i = 0;
+	bool first = true;
+
+	tprints("{");
+
+	for (; xl->str; xl++) {
+		if (xl->val >= size)
+			continue;
+
+		print_cc_char(&first, data, xl->str, xl->val);
+		not_printed &= ~(1 << xl->val);
+	}
+
+	while (not_printed) {
+		if (not_printed & 1)
+			print_cc_char(&first, data, NULL, i);
+
+		not_printed >>= 1;
+		i++;
+	}
+
+	tprints("}");
+}
+
 static void
 decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
 {
@@ -56,16 +171,14 @@ decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
 			(tios.c_lflag & ECHO) ? "" : "-");
 		return;
 	}
-	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);
+	tprints("{");
+	decode_flags(tios.c_iflag, tios.c_oflag, tios.c_cflag, 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);
+	decode_term_cc(termios_cc, tios.c_cc, NCCS);
 	tprints("}");
 }
 
@@ -87,22 +200,12 @@ decode_termio(struct tcb *const tcp, const kernel_ulong_t addr)
 			(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]);
-#else /* !_VMIN */
-	if (!(tio.c_lflag & ICANON))
-		tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
-			tio.c_cc[VMIN], tio.c_cc[VTIME]);
-#endif /* !_VMIN */
+	tprints("{");
+	decode_flags(tio.c_iflag, tio.c_oflag, tio.c_cflag, tio.c_lflag);
+	tprintf(", c_line=%u, ", tio.c_line);
+
 	tprints("c_cc=");
-	print_quoted_string((char *) tio.c_cc, NCC, QUOTE_FORCE_HEX);
+	decode_term_cc(termio_cc, tio.c_cc, NCC);
 	tprints("}");
 }
 
diff --git a/xlat/term_cflags.in b/xlat/term_cflags.in
new file mode 100644
index 0000000..b664e76
--- /dev/null
+++ b/xlat/term_cflags.in
@@ -0,0 +1,9 @@
+CSTOPB
+CREAD
+PARENB
+PARODD
+HUPCL
+CLOCAL
+CMSPAR    /* mark or space (stick) parity */
+CRTSCTS   /* flow control */
+CTVB      /* VisioBraille Terminal flow control */
diff --git a/xlat/term_cflags_csize.in b/xlat/term_cflags_csize.in
new file mode 100644
index 0000000..20f23c5
--- /dev/null
+++ b/xlat/term_cflags_csize.in
@@ -0,0 +1,4 @@
+CS5
+CS6
+CS7
+CS8
diff --git a/xlat/term_iflags.in b/xlat/term_iflags.in
new file mode 100644
index 0000000..6da15f3
--- /dev/null
+++ b/xlat/term_iflags.in
@@ -0,0 +1,15 @@
+BRKINT   /* Signal interrupt on break.  */
+ICRNL    /* Map CR to NL on input.  */
+IGNBRK   /* Ignore break condition.  */
+IGNCR    /* Ignore CR.  */
+IGNPAR   /* Ignore characters with parity errors.  */
+IMAXBEL  /* Ring bell when input queue is full.  */
+INLCR    /* Map NL to CR on input.  */
+INPCK    /* Enable input parity check.  */
+ISTRIP   /* Strip 8th bit off characters.  */
+IUCLC    /* Map upper case to lower case on input.  */
+IUTF8    /* Input is UTF-8 */
+IXANY    /* Any character will restart after stop.  */
+IXOFF    /* Enable start/stop input control.  */
+IXON     /* Enable start/stop output control.  */
+PARMRK   /* Mark parity and framing errors.  */
diff --git a/xlat/term_lflags.in b/xlat/term_lflags.in
new file mode 100644
index 0000000..19b1ef6
--- /dev/null
+++ b/xlat/term_lflags.in
@@ -0,0 +1,17 @@
+DEFECHO      /* SUNOS thing, what is it? */
+ECHO         /* Enable echo.  */
+ECHOCTL      /* Echo control characters as ^X.  */
+ECHOE        /* Visual erase for ERASE.  */
+ECHOK        /* Echo NL after KILL.  */
+ECHOKE       /* Visual erase for KILL.  */
+ECHONL       /* Echo NL even if ECHO is off.  */
+ECHOPRT      /* Hardcopy visual erase.  */
+EXTPROC      /* External processing on pty */
+FLUSHO
+ICANON       /* Do erase and kill processing.  */
+IEXTEN       /* Enable DISCARD and LNEXT.  */
+ISIG         /* Enable signals.  */
+NOFLSH       /* Disable flush after interrupt.  */
+PENDIN       /* Retype pending input (state).  */
+TOSTOP       /* Send SIGTTOU for background output.  */
+XCASE
diff --git a/xlat/term_oflags.in b/xlat/term_oflags.in
new file mode 100644
index 0000000..5ab523e
--- /dev/null
+++ b/xlat/term_oflags.in
@@ -0,0 +1,15 @@
+#ifdef ALPHA
+XTABS   /* required by POSIX to == TAB3; but not on Alpha! */
+#endif
+
+OCRNL
+OFDEL
+OFILL
+OLCUC   /* Map lower case to upper case on output.  */
+ONLCR   /* Map NL to CR-NL on output.  */
+ONLRET
+ONOCR
+OPOST   /* Perform output processing.  */
+
+PAGEOUT /* SUNOS specific */
+WRAP    /* SUNOS specific */
diff --git a/xlat/term_oflags_bsdly.in b/xlat/term_oflags_bsdly.in
new file mode 100644
index 0000000..b748f73
--- /dev/null
+++ b/xlat/term_oflags_bsdly.in
@@ -0,0 +1,2 @@
+BS1
+BS0
diff --git a/xlat/term_oflags_crdly.in b/xlat/term_oflags_crdly.in
new file mode 100644
index 0000000..a5d3b18
--- /dev/null
+++ b/xlat/term_oflags_crdly.in
@@ -0,0 +1,4 @@
+CR0
+CR1
+CR2
+CR3
diff --git a/xlat/term_oflags_ffdly.in b/xlat/term_oflags_ffdly.in
new file mode 100644
index 0000000..4b61019
--- /dev/null
+++ b/xlat/term_oflags_ffdly.in
@@ -0,0 +1,2 @@
+FF0
+FF1
diff --git a/xlat/term_oflags_nldly.in b/xlat/term_oflags_nldly.in
new file mode 100644
index 0000000..4e6d5d3
--- /dev/null
+++ b/xlat/term_oflags_nldly.in
@@ -0,0 +1,4 @@
+NL0
+NL1
+NL2
+NL3
diff --git a/xlat/term_oflags_tabdly.in b/xlat/term_oflags_tabdly.in
new file mode 100644
index 0000000..01e3773
--- /dev/null
+++ b/xlat/term_oflags_tabdly.in
@@ -0,0 +1,8 @@
+#ifndef ALPHA
+XTABS /* required by POSIX to == TAB3; but not on Alpha! */
+#endif
+
+TAB0
+TAB1
+TAB2
+TAB3
diff --git a/xlat/term_oflags_vtdly.in b/xlat/term_oflags_vtdly.in
new file mode 100644
index 0000000..210ac80
--- /dev/null
+++ b/xlat/term_oflags_vtdly.in
@@ -0,0 +1,2 @@
+VT0
+VT1
diff --git a/xlat/termio_cc.in b/xlat/termio_cc.in
new file mode 100644
index 0000000..5798239
--- /dev/null
+++ b/xlat/termio_cc.in
@@ -0,0 +1,10 @@
+_VINTR
+_VQUIT
+_VERASE
+_VKILL
+_VEOF
+_VMIN
+_VEOL
+_VTIME
+_VEOL2
+_VSWTC
diff --git a/xlat/termios_cc.in b/xlat/termios_cc.in
new file mode 100644
index 0000000..920be95
--- /dev/null
+++ b/xlat/termios_cc.in
@@ -0,0 +1,18 @@
+VINTR    /* Interrupt character [ISIG].  */
+VQUIT    /* Quit character [ISIG].  */
+VERASE   /* Erase character [ICANON].  */
+VKILL    /* Kill-line character [ICANON].  */
+VMIN     /* Minimum number of bytes read at once [!ICANON].  */
+VTIME    /* Time-out value (tenths of a second) [!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].  */
-- 
2.1.4





More information about the Strace-devel mailing list