aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/stty.c527
1 files changed, 376 insertions, 151 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c
index 849f61540..ade2468a8 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -133,18 +133,27 @@ enum {
#define REV 4 /* Can be turned off by prepending '-' */
#define OMIT 8 /* Don't display value */
-/* Each mode */
+
+/* Each mode.
+ * This structure should be kept as small as humanly possible.
+ */
struct mode_info {
- const char name[9]; /* Name given on command line */
- const unsigned char type; /* Which structure element to change */
- const unsigned char flags; /* Setting and display options */
- /* were using short here, but ppc32 was unhappy: */
+ const uint8_t type; /* Which structure element to change */
+ const uint8_t flags; /* Setting and display options */
+ /* only these values are ever used, so... */
+#if (CSIZE | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY) < 0x100
+ const uint8_t mask;
+#elif (CSIZE | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY) < 0x10000
+ const uint16_t mask;
+#else
const tcflag_t mask; /* Other bits to turn off for this mode */
+#endif
+ /* was using short here, but ppc32 was unhappy */
const tcflag_t bits; /* Bits to set for this mode */
};
enum {
- /* Must match mode_info[] order! */
+ /* Must match mode_name[] and mode_info[] order! */
IDX_evenp = 0,
IDX_parity,
IDX_oddp,
@@ -170,151 +179,302 @@ enum {
#endif
};
-#define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B }
+#define MI_ENTRY(N,T,F,B,M) N "\0"
+
+/* Mode names given on command line */
+static const char mode_name[] =
+ MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("parity", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("nl", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("ek", combination, OMIT, 0, 0 )
+ MI_ENTRY("sane", combination, OMIT, 0, 0 )
+ MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("raw", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("litout", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("crt", combination, OMIT, 0, 0 )
+ MI_ENTRY("dec", combination, OMIT, 0, 0 )
+#ifdef IXANY
+ MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 )
+#endif
+#if defined(TABDLY) || defined(OXTABS)
+ MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 )
+#endif
+#if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
+ MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 )
+#endif
+ MI_ENTRY("parenb", control, REV, PARENB, 0 )
+ MI_ENTRY("parodd", control, REV, PARODD, 0 )
+ MI_ENTRY("cs5", control, 0, CS5, CSIZE)
+ MI_ENTRY("cs6", control, 0, CS6, CSIZE)
+ MI_ENTRY("cs7", control, 0, CS7, CSIZE)
+ MI_ENTRY("cs8", control, 0, CS8, CSIZE)
+ MI_ENTRY("hupcl", control, REV, HUPCL, 0 )
+ MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 )
+ MI_ENTRY("cstopb", control, REV, CSTOPB, 0 )
+ MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 )
+ MI_ENTRY("clocal", control, REV, CLOCAL, 0 )
+#ifdef CRTSCTS
+ MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 )
+#endif
+ MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 )
+ MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 )
+ MI_ENTRY("ignpar", input, REV, IGNPAR, 0 )
+ MI_ENTRY("parmrk", input, REV, PARMRK, 0 )
+ MI_ENTRY("inpck", input, REV, INPCK, 0 )
+ MI_ENTRY("istrip", input, REV, ISTRIP, 0 )
+ MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 )
+ MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 )
+ MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 )
+ MI_ENTRY("ixon", input, REV, IXON, 0 )
+ MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 )
+ MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 )
+#ifdef IUCLC
+ MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 )
+#endif
+#ifdef IXANY
+ MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 )
+#endif
+#ifdef IMAXBEL
+ MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 )
+#endif
+ MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 )
+#ifdef OLCUC
+ MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 )
+#endif
+#ifdef OCRNL
+ MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 )
+#endif
+#ifdef ONLCR
+ MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 )
+#endif
+#ifdef ONOCR
+ MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 )
+#endif
+#ifdef ONLRET
+ MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 )
+#endif
+#ifdef OFILL
+ MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 )
+#endif
+#ifdef OFDEL
+ MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 )
+#endif
+#ifdef NLDLY
+ MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY)
+ MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY)
+#endif
+#ifdef CRDLY
+ MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY)
+ MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY)
+ MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY)
+ MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY)
+#endif
+
+#ifdef TABDLY
+ MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY)
+ MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY)
+ MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY)
+ MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY)
+#else
+# ifdef OXTABS
+ MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 )
+# endif
+#endif
+
+#ifdef BSDLY
+ MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY)
+ MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY)
+#endif
+#ifdef VTDLY
+ MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY)
+ MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY)
+#endif
+#ifdef FFDLY
+ MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY)
+ MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY)
+#endif
+ MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 )
+ MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 )
+#ifdef IEXTEN
+ MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
+#endif
+ MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
+ MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 )
+ MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 )
+ MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
+ MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 )
+ MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 )
+#ifdef XCASE
+ MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 )
+#endif
+#ifdef TOSTOP
+ MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 )
+#endif
+#ifdef ECHOPRT
+ MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 )
+ MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 )
+#endif
+#ifdef ECHOCTL
+ MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 )
+ MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 )
+#endif
+#ifdef ECHOKE
+ MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 )
+ MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 )
+#endif
+ ;
+
+#undef MI_ENTRY
+#define MI_ENTRY(N,T,F,B,M) { T, F, M, B },
static const struct mode_info mode_info[] = {
- MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("parity", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("nl", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("ek", combination, OMIT, 0, 0 ),
- MI_ENTRY("sane", combination, OMIT, 0, 0 ),
- MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("raw", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("litout", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("crt", combination, OMIT, 0, 0 ),
- MI_ENTRY("dec", combination, OMIT, 0, 0 ),
+ /* This should be verbatim cut-n-paste copy of the above MI_ENTRYs */
+ MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("parity", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("nl", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("ek", combination, OMIT, 0, 0 )
+ MI_ENTRY("sane", combination, OMIT, 0, 0 )
+ MI_ENTRY("cooked", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("raw", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("pass8", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("litout", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("crt", combination, OMIT, 0, 0 )
+ MI_ENTRY("dec", combination, OMIT, 0, 0 )
#ifdef IXANY
- MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 )
#endif
#if defined(TABDLY) || defined(OXTABS)
- MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 ),
+ MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 )
#endif
#if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
- MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 ),
- MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 ),
-#endif
- MI_ENTRY("parenb", control, REV, PARENB, 0 ),
- MI_ENTRY("parodd", control, REV, PARODD, 0 ),
- MI_ENTRY("cs5", control, 0, CS5, CSIZE),
- MI_ENTRY("cs6", control, 0, CS6, CSIZE),
- MI_ENTRY("cs7", control, 0, CS7, CSIZE),
- MI_ENTRY("cs8", control, 0, CS8, CSIZE),
- MI_ENTRY("hupcl", control, REV, HUPCL, 0 ),
- MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 ),
- MI_ENTRY("cstopb", control, REV, CSTOPB, 0 ),
- MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 ),
- MI_ENTRY("clocal", control, REV, CLOCAL, 0 ),
+ MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 )
+ MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 )
+#endif
+ MI_ENTRY("parenb", control, REV, PARENB, 0 )
+ MI_ENTRY("parodd", control, REV, PARODD, 0 )
+ MI_ENTRY("cs5", control, 0, CS5, CSIZE)
+ MI_ENTRY("cs6", control, 0, CS6, CSIZE)
+ MI_ENTRY("cs7", control, 0, CS7, CSIZE)
+ MI_ENTRY("cs8", control, 0, CS8, CSIZE)
+ MI_ENTRY("hupcl", control, REV, HUPCL, 0 )
+ MI_ENTRY("hup", control, REV | OMIT, HUPCL, 0 )
+ MI_ENTRY("cstopb", control, REV, CSTOPB, 0 )
+ MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 )
+ MI_ENTRY("clocal", control, REV, CLOCAL, 0 )
#ifdef CRTSCTS
- MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 ),
-#endif
- MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 ),
- MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 ),
- MI_ENTRY("ignpar", input, REV, IGNPAR, 0 ),
- MI_ENTRY("parmrk", input, REV, PARMRK, 0 ),
- MI_ENTRY("inpck", input, REV, INPCK, 0 ),
- MI_ENTRY("istrip", input, REV, ISTRIP, 0 ),
- MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 ),
- MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 ),
- MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 ),
- MI_ENTRY("ixon", input, REV, IXON, 0 ),
- MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 ),
- MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 ),
+ MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 )
+#endif
+ MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 )
+ MI_ENTRY("brkint", input, SANE_SET | REV, BRKINT, 0 )
+ MI_ENTRY("ignpar", input, REV, IGNPAR, 0 )
+ MI_ENTRY("parmrk", input, REV, PARMRK, 0 )
+ MI_ENTRY("inpck", input, REV, INPCK, 0 )
+ MI_ENTRY("istrip", input, REV, ISTRIP, 0 )
+ MI_ENTRY("inlcr", input, SANE_UNSET | REV, INLCR, 0 )
+ MI_ENTRY("igncr", input, SANE_UNSET | REV, IGNCR, 0 )
+ MI_ENTRY("icrnl", input, SANE_SET | REV, ICRNL, 0 )
+ MI_ENTRY("ixon", input, REV, IXON, 0 )
+ MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 )
+ MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 )
#ifdef IUCLC
- MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 ),
+ MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 )
#endif
#ifdef IXANY
- MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 ),
+ MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 )
#endif
#ifdef IMAXBEL
- MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 ),
+ MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 )
#endif
- MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 ),
+ MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 )
#ifdef OLCUC
- MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 ),
+ MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 )
#endif
#ifdef OCRNL
- MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 ),
+ MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 )
#endif
#ifdef ONLCR
- MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 ),
+ MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 )
#endif
#ifdef ONOCR
- MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 ),
+ MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 )
#endif
#ifdef ONLRET
- MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 ),
+ MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 )
#endif
#ifdef OFILL
- MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 ),
+ MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 )
#endif
#ifdef OFDEL
- MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 ),
+ MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 )
#endif
#ifdef NLDLY
- MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY),
- MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY),
+ MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY)
+ MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY)
#endif
#ifdef CRDLY
- MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY),
- MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY),
- MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY),
- MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY),
+ MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY)
+ MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY)
+ MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY)
+ MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY)
#endif
#ifdef TABDLY
- MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY),
- MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY),
- MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY),
- MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY),
+ MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY)
+ MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY)
+ MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY)
+ MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY)
#else
# ifdef OXTABS
- MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 ),
+ MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 )
# endif
#endif
#ifdef BSDLY
- MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY),
- MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY),
+ MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY)
+ MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY)
#endif
#ifdef VTDLY
- MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY),
- MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY),
+ MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY)
+ MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY)
#endif
#ifdef FFDLY
- MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY),
- MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY),
+ MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY)
+ MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY)
#endif
- MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 ),
- MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 ),
+ MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 )
+ MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 )
#ifdef IEXTEN
- MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ),
-#endif
- MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ),
- MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 ),
- MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 ),
- MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ),
- MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 ),
- MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 ),
+ MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
+#endif
+ MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
+ MI_ENTRY("echoe", local, SANE_SET | REV, ECHOE, 0 )
+ MI_ENTRY("crterase", local, REV | OMIT, ECHOE, 0 )
+ MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
+ MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 )
+ MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 )
#ifdef XCASE
- MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 ),
+ MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 )
#endif
#ifdef TOSTOP
- MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 ),
+ MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 )
#endif
#ifdef ECHOPRT
- MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 ),
- MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 ),
+ MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 )
+ MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 )
#endif
#ifdef ECHOCTL
- MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 ),
- MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 ),
+ MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 )
+ MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 )
#endif
#ifdef ECHOKE
- MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 ),
- MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 ),
+ MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 )
+ MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 )
#endif
};
@@ -322,15 +482,15 @@ enum {
NUM_mode_info = ARRAY_SIZE(mode_info)
};
+
/* Control characters */
struct control_info {
- const char name[7]; /* Name given on command line */
- const unsigned char saneval; /* Value to set for 'stty sane' */
- const unsigned char offset; /* Offset in c_cc */
+ const uint8_t saneval; /* Value to set for 'stty sane' */
+ const uint8_t offset; /* Offset in c_cc */
};
enum {
- /* Must match control_info[] order! */
+ /* Must match control_name[] and control_info[] order! */
CIDX_intr = 0,
CIDX_quit,
CIDX_erase,
@@ -368,60 +528,111 @@ enum {
CIDX_time,
};
+#define CI_ENTRY(n,s,o) n "\0"
+
+/* Name given on command line */
+static const char control_name[] =
+ CI_ENTRY("intr", CINTR, VINTR )
+ CI_ENTRY("quit", CQUIT, VQUIT )
+ CI_ENTRY("erase", CERASE, VERASE )
+ CI_ENTRY("kill", CKILL, VKILL )
+ CI_ENTRY("eof", CEOF, VEOF )
+ CI_ENTRY("eol", CEOL, VEOL )
+#ifdef VEOL2
+ CI_ENTRY("eol2", CEOL2, VEOL2 )
+#endif
+#ifdef VSWTCH
+ CI_ENTRY("swtch", CSWTCH, VSWTCH )
+#endif
+ CI_ENTRY("start", CSTART, VSTART )
+ CI_ENTRY("stop", CSTOP, VSTOP )
+ CI_ENTRY("susp", CSUSP, VSUSP )
+#ifdef VDSUSP
+ CI_ENTRY("dsusp", CDSUSP, VDSUSP )
+#endif
+#ifdef VREPRINT
+ CI_ENTRY("rprnt", CRPRNT, VREPRINT)
+#endif
+#ifdef VWERASE
+ CI_ENTRY("werase", CWERASE, VWERASE )
+#endif
+#ifdef VLNEXT
+ CI_ENTRY("lnext", CLNEXT, VLNEXT )
+#endif
+#ifdef VFLUSHO
+ CI_ENTRY("flush", CFLUSHO, VFLUSHO )
+#endif
+#ifdef VSTATUS
+ CI_ENTRY("status", CSTATUS, VSTATUS )
+#endif
+ /* These must be last because of the display routines */
+ CI_ENTRY("min", 1, VMIN )
+ CI_ENTRY("time", 0, VTIME )
+ ;
+
+#undef CI_ENTRY
+#define CI_ENTRY(n,s,o) { s, o },
+
static const struct control_info control_info[] = {
- {"intr", CINTR, VINTR},
- {"quit", CQUIT, VQUIT},
- {"erase", CERASE, VERASE},
- {"kill", CKILL, VKILL},
- {"eof", CEOF, VEOF},
- {"eol", CEOL, VEOL},
+ /* This should be verbatim cut-n-paste copy of the above CI_ENTRYs */
+ CI_ENTRY("intr", CINTR, VINTR )
+ CI_ENTRY("quit", CQUIT, VQUIT )
+ CI_ENTRY("erase", CERASE, VERASE )
+ CI_ENTRY("kill", CKILL, VKILL )
+ CI_ENTRY("eof", CEOF, VEOF )
+ CI_ENTRY("eol", CEOL, VEOL )
#ifdef VEOL2
- {"eol2", CEOL2, VEOL2},
+ CI_ENTRY("eol2", CEOL2, VEOL2 )
#endif
#ifdef VSWTCH
- {"swtch", CSWTCH, VSWTCH},
+ CI_ENTRY("swtch", CSWTCH, VSWTCH )
#endif
- {"start", CSTART, VSTART},
- {"stop", CSTOP, VSTOP},
- {"susp", CSUSP, VSUSP},
+ CI_ENTRY("start", CSTART, VSTART )
+ CI_ENTRY("stop", CSTOP, VSTOP )
+ CI_ENTRY("susp", CSUSP, VSUSP )
#ifdef VDSUSP
- {"dsusp", CDSUSP, VDSUSP},
+ CI_ENTRY("dsusp", CDSUSP, VDSUSP )
#endif
#ifdef VREPRINT
- {"rprnt", CRPRNT, VREPRINT},
+ CI_ENTRY("rprnt", CRPRNT, VREPRINT)
#endif
#ifdef VWERASE
- {"werase", CWERASE, VWERASE},
+ CI_ENTRY("werase", CWERASE, VWERASE )
#endif
#ifdef VLNEXT
- {"lnext", CLNEXT, VLNEXT},
+ CI_ENTRY("lnext", CLNEXT, VLNEXT )
#endif
#ifdef VFLUSHO
- {"flush", CFLUSHO, VFLUSHO},
+ CI_ENTRY("flush", CFLUSHO, VFLUSHO )
#endif
#ifdef VSTATUS
- {"status", CSTATUS, VSTATUS},
+ CI_ENTRY("status", CSTATUS, VSTATUS )
#endif
/* These must be last because of the display routines */
- {"min", 1, VMIN},
- {"time", 0, VTIME},
+ CI_ENTRY("min", 1, VMIN )
+ CI_ENTRY("time", 0, VTIME )
};
enum {
NUM_control_info = ARRAY_SIZE(control_info)
};
-/* The width of the screen, for output wrapping */
-static unsigned max_col = 80; /* default */
struct globals {
+ const char *device_name; // = bb_msg_standard_input;
+ /* The width of the screen, for output wrapping */
+ unsigned max_col; // = 80;
/* Current position, to know when to wrap */
unsigned current_col;
char buf[10];
};
#define G (*(struct globals*)&bb_common_bufsiz1)
+#define INIT_G() \
+ do { \
+ G.device_name = bb_msg_standard_input; \
+ G.max_col = 80; \
+ } while (0)
-static const char *device_name = bb_msg_standard_input;
/* Return a string that is the printable representation of character CH */
/* Adapted from 'cat' by Torbjorn Granlund */
@@ -454,7 +665,7 @@ static const char *visible(unsigned ch)
static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode)
{
- static const unsigned char tcflag_offsets[] ALIGN1 = {
+ static const uint8_t tcflag_offsets[] ALIGN1 = {
offsetof(struct termios, c_cflag), /* control */
offsetof(struct termios, c_iflag), /* input */
offsetof(struct termios, c_oflag), /* output */
@@ -484,12 +695,12 @@ static void set_speed_or_die(enum speed_setting type, const char *const arg,
static ATTRIBUTE_NORETURN void perror_on_device_and_die(const char *fmt)
{
- bb_perror_msg_and_die(fmt, device_name);
+ bb_perror_msg_and_die(fmt, G.device_name);
}
static void perror_on_device(const char *fmt)
{
- bb_perror_msg(fmt, device_name);
+ bb_perror_msg(fmt, G.device_name);
}
/* Print format string MESSAGE and optional args.
@@ -511,7 +722,7 @@ static void wrapf(const char *message, ...)
if (G.current_col > 0) {
G.current_col++;
if (buf[0] != '\n') {
- if (G.current_col + buflen >= max_col) {
+ if (G.current_col + buflen >= G.max_col) {
bb_putchar('\n');
G.current_col = 0;
} else
@@ -526,7 +737,7 @@ static void wrapf(const char *message, ...)
static void set_window_size(const int rows, const int cols)
{
- struct winsize win = { 0, 0, 0, 0};
+ struct winsize win = { 0, 0, 0, 0 };
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win)) {
if (errno != EINVAL) {
@@ -569,20 +780,30 @@ static const struct suffix_mult stty_suffixes[] = {
static const struct mode_info *find_mode(const char *name)
{
- int i;
- for (i = 0; i < NUM_mode_info; ++i)
- if (!strcmp(name, mode_info[i].name))
+ int i = 0;
+ const char *m = mode_name;
+
+ while (*m) {
+ if (strcmp(name, m) == 0)
return &mode_info[i];
- return 0;
+ m += strlen(m) + 1;
+ i++;
+ }
+ return NULL;
}
static const struct control_info *find_control(const char *name)
{
- int i;
- for (i = 0; i < NUM_control_info; ++i)
- if (!strcmp(name, control_info[i].name))
+ int i = 0;
+ const char *m = mode_name;
+
+ while (*m) {
+ if (strcmp(name, m) == 0)
return &control_info[i];
- return 0;
+ m += strlen(m) + 1;
+ i++;
+ }
+ return NULL;
}
enum {
@@ -704,7 +925,7 @@ static void do_display(const struct termios *mode, const int all)
continue;
}
#endif
- wrapf("%s = %s;", control_info[i].name,
+ wrapf("%s = %s;", nth_string(control_name, i),
visible(mode->c_cc[control_info[i].offset]));
}
#if VEOF == VMIN
@@ -726,12 +947,13 @@ static void do_display(const struct termios *mode, const int all)
mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits;
if ((*bitsp & mask) == mode_info[i].bits) {
if (all || (mode_info[i].flags & SANE_UNSET))
- wrapf("%s", mode_info[i].name);
+ wrapf("-%s"+1, nth_string(mode_name, i));
} else {
- if ((all && mode_info[i].flags & REV) ||
- (!all &&
- (mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV)))
- wrapf("-%s", mode_info[i].name);
+ if ((all && mode_info[i].flags & REV)
+ || (!all && (mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV))
+ ) {
+ wrapf("-%s", nth_string(mode_name, i));
+ }
}
}
if (G.current_col) wrapf("\n");
@@ -861,8 +1083,8 @@ static void set_mode(const struct mode_info *info, int reversed,
mode->c_oflag &= ~OPOST;
}
} else if (info == &mode_info[IDX_raw] || info == &mode_info[IDX_cooked]) {
- if ((info->name[0] == 'r' && reversed)
- || (info->name[0] == 'c' && !reversed)
+ if ((info == &mode_info[IDX_raw] && reversed)
+ || (info == &mode_info[IDX_cooked] && !reversed)
) {
/* Cooked mode */
mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON;
@@ -944,11 +1166,12 @@ static void set_control_char_or_die(const struct control_info *info,
mode->c_cc[info->offset] = value;
}
-#define STTY_require_set_attr (1<<0)
-#define STTY_speed_was_set (1<<1)
-#define STTY_verbose_output (1<<2)
-#define STTY_recoverable_output (1<<3)
-#define STTY_noargs (1<<4)
+#define STTY_require_set_attr (1 << 0)
+#define STTY_speed_was_set (1 << 1)
+#define STTY_verbose_output (1 << 2)
+#define STTY_recoverable_output (1 << 3)
+#define STTY_noargs (1 << 4)
+
int stty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int stty_main(int argc, char **argv)
{
@@ -959,6 +1182,8 @@ int stty_main(int argc, char **argv)
int stty_state;
int k;
+ INIT_G();
+
stty_state = STTY_noargs;
output_func = do_display;
@@ -1086,8 +1311,8 @@ int stty_main(int argc, char **argv)
/* Now it is safe to start doing things */
if (file_name) {
int fd, fdflags;
- device_name = file_name;
- fd = xopen(device_name, O_RDONLY | O_NONBLOCK);
+ G.device_name = file_name;
+ fd = xopen(G.device_name, O_RDONLY | O_NONBLOCK);
if (fd != STDIN_FILENO) {
dup2(fd, STDIN_FILENO);
close(fd);
@@ -1105,7 +1330,7 @@ int stty_main(int argc, char **argv)
perror_on_device_and_die("%s");
if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) {
- get_terminal_width_height(STDOUT_FILENO, &max_col, NULL);
+ get_terminal_width_height(STDOUT_FILENO, &G.max_col, NULL);
output_func(&mode, display_all);
return EXIT_SUCCESS;
}