1 /* source: xio-termios.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
4 
5 /* this file contains the source for terminal I/O options */
6 
7 #include "xiosysincludes.h"
8 #include "xioopen.h"
9 
10 #include "xio-termios.h"
11 
12 /****** TERMIOS addresses ******/
13 #if _WITH_TERMIOS
14 #if WITH_TERMIOS
15 const struct optdesc opt_tiocsctty={ "tiocsctty", "ctty",OPT_TIOCSCTTY,  GROUP_TERMIOS,   PH_LATE2, TYPE_BOOL,     OFUNC_SPEC };
16 
17 /* it is important for handling of these options that they have PH_FD */
18 const struct optdesc opt_brkint  = { "brkint",  NULL, OPT_BRKINT,  GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, BRKINT };
19 const struct optdesc opt_icrnl   = { "icrnl",   NULL, OPT_ICRNL,   GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, ICRNL };
20 const struct optdesc opt_ignbrk  = { "ignbrk",  NULL, OPT_IGNBRK,  GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IGNBRK };
21 const struct optdesc opt_igncr   = { "igncr",   NULL, OPT_IGNCR,   GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IGNCR };
22 const struct optdesc opt_ignpar  = { "ignpar",  NULL, OPT_IGNPAR,  GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IGNPAR };
23 const struct optdesc opt_imaxbel = { "imaxbel", NULL, OPT_IMAXBEL, GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IMAXBEL };
24 const struct optdesc opt_inlcr   = { "inlcr",   NULL, OPT_INLCR,   GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, INLCR };
25 const struct optdesc opt_inpck   = { "inpck",   NULL, OPT_INPCK,   GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, INPCK };
26 const struct optdesc opt_istrip  = { "istrip",  NULL, OPT_ISTRIP,  GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, ISTRIP };
27 #ifdef IUCLC
28 const struct optdesc opt_iuclc   = { "iuclc",   NULL, OPT_IUCLC,   GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IUCLC };
29 #endif
30 const struct optdesc opt_ixany   = { "ixany",   NULL, OPT_IXANY,   GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IXANY };
31 const struct optdesc opt_ixoff   = { "ixoff",   NULL, OPT_IXOFF,   GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IXOFF };
32 const struct optdesc opt_ixon    = { "ixon",    NULL, OPT_IXON,    GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, IXON };
33 const struct optdesc opt_parmrk  = { "parmrk",  NULL, OPT_PARMRK,  GROUP_TERMIOS, PH_FD, TYPE_BOOL, OFUNC_TERMIOS_FLAG, 0, PARMRK };
34 
35 #ifdef CRDLY
36 #  ifdef CR0
37 const struct optdesc opt_cr0     = { "cr0",     NULL, OPT_CR0,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, CR0, CRDLY };
38 #  endif
39 #  ifdef CR1
40 const struct optdesc opt_cr1     = { "cr1",     NULL, OPT_CR1,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, CR1, CRDLY };
41 #  endif
42 #  ifdef CR2
43 const struct optdesc opt_cr2     = { "cr2",     NULL, OPT_CR2,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, CR2, CRDLY };
44 #  endif
45 #  ifdef CR3
46 const struct optdesc opt_cr3     = { "cr3",     NULL, OPT_CR3,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, CR3, CRDLY };
47 #  endif
48 #  if CRDLY_SHIFT >= 0
49 const struct optdesc opt_crdly   = { "crdly",   NULL, OPT_CRDLY,   GROUP_TERMIOS, PH_FD, TYPE_UINT,  OFUNC_TERMIOS_VALUE,   1, CRDLY, CRDLY_SHIFT };
50 #  endif
51 #endif /* defined(CRDLY) */
52 #ifdef NLDLY
53 #  ifdef NL0
54 const struct optdesc opt_nl0     = { "nl0",     NULL, OPT_NL0,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, NL0, NLDLY };
55 #  endif
56 #  ifdef NL1
57 const struct optdesc opt_nl1     = { "nl1",     NULL, OPT_NL1,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, NL1, NLDLY };
58 #  endif
59 const struct optdesc opt_nldly   = { "nldly",   NULL, OPT_NLDLY,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 1, NLDLY };
60 #endif /* defined(NLDLY) */
61 #ifdef OCRNL
62 const struct optdesc opt_ocrnl   = { "ocrnl",   NULL, OPT_OCRNL,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 1, OCRNL };
63 #endif
64 #ifdef OFDEL
65 const struct optdesc opt_ofdel   = { "ofdel",   NULL, OPT_OFDEL,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 1, OFDEL };
66 #endif
67 #ifdef OFILL
68 const struct optdesc opt_ofill   = { "ofill",   NULL, OPT_OFILL,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 1, OFILL };
69 #endif
70 const struct optdesc opt_opost   = { "opost",   NULL, OPT_OPOST,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 1, OPOST };
71 #ifdef OLCUC
72 const struct optdesc opt_olcuc   = { "olcuc",   NULL, OPT_OLCUC,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 1, OLCUC };
73 #endif
74 const struct optdesc opt_onlcr   = { "onlcr",   NULL, OPT_ONLCR,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 1, ONLCR };
75 #ifdef ONLRET
76 const struct optdesc opt_onlret  = { "onlret",  NULL, OPT_ONLRET,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 1, ONLRET };
77 #endif
78 #ifdef ONOCR
79 const struct optdesc opt_onocr   = { "onocr",   NULL, OPT_ONOCR,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 1, ONOCR };
80 #endif
81 #ifdef TABDLY
82 #  ifdef TAB0
83 const struct optdesc opt_tab0    = { "tab0",    NULL, OPT_TAB0,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, TAB0, TABDLY };
84 #  endif
85 #  ifdef TAB1
86 const struct optdesc opt_tab1    = { "tab1",    NULL, OPT_TAB1,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, TAB1, TABDLY };
87 #  endif
88 #  ifdef TAB2
89 const struct optdesc opt_tab2    = { "tab2",    NULL, OPT_TAB2,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, TAB2, TABDLY };
90 #  endif
91 #  ifdef TAB3
92 const struct optdesc opt_tab3    = { "tab3",    NULL, OPT_TAB3,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, TAB3, TABDLY };
93 #  endif
94 #  ifdef XTABS
95 const struct optdesc opt_xtabs   = { "xtabs",   NULL, OPT_XTABS,   GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, XTABS, TABDLY };
96 #  endif
97 #  if TABDLY_SHIFT >= 0
98 const struct optdesc opt_tabdly  = { "tabdly",  NULL, OPT_TABDLY,  GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_VALUE, 1, TABDLY, TABDLY_SHIFT };
99 #  endif
100 #endif /* defined(TABDLY) */
101 #ifdef BSDLY
102 #  ifdef BS0
103 const struct optdesc opt_bs0     = { "bs0",     NULL, OPT_BS0,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, BS0, BSDLY };
104 #endif
105 #  ifdef BS1
106 const struct optdesc opt_bs1     = { "bs1",     NULL, OPT_BS1,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, BS1, BSDLY };
107 #  endif
108 const struct optdesc opt_bsdly   = { "bsdly",   NULL, OPT_BSDLY,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    1, BSDLY };
109 #endif
110 #ifdef VTDLY
111 #  ifdef VT0
112 const struct optdesc opt_vt0     = { "vt0",     NULL, OPT_VT0,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, VT0, VTDLY };
113 #  endif
114 #  ifdef VT1
115 const struct optdesc opt_vt1     = { "vt1",     NULL, OPT_VT1,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, VT1, VTDLY };
116 #  endif
117 const struct optdesc opt_vtdly   = { "vtdly",   NULL, OPT_VTDLY,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    1, VTDLY };
118 #endif
119 #ifdef FFDLY
120 #  ifdef FF0
121 const struct optdesc opt_ff0     = { "ff0",     NULL, OPT_FF0,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, FF0, FFDLY };
122 #  endif
123 #  ifdef FF1
124 const struct optdesc opt_ff1     = { "ff1",     NULL, OPT_FF1,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 1, FF1, FFDLY };
125 #  endif
126 const struct optdesc opt_ffdly   = { "ffdly",   NULL, OPT_FFDLY,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    1, FFDLY };
127 #endif
128 
129 #ifdef CBAUD
130 const struct optdesc opt_b0      = { "b0",      NULL, OPT_B0,      GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B0,       CBAUD };
131 const struct optdesc opt_b50     = { "b50",     NULL, OPT_B50,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B50,      CBAUD };
132 const struct optdesc opt_b75     = { "b75",     NULL, OPT_B75,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B75,      CBAUD };
133 const struct optdesc opt_b110    = { "b110",    NULL, OPT_B110,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B110,     CBAUD };
134 const struct optdesc opt_b134    = { "b134",    NULL, OPT_B134,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B134,     CBAUD };
135 const struct optdesc opt_b150    = { "b150",    NULL, OPT_B150,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B150,     CBAUD };
136 const struct optdesc opt_b200    = { "b200",    NULL, OPT_B200,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B200,     CBAUD };
137 const struct optdesc opt_b300    = { "b300",    NULL, OPT_B300,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B300,     CBAUD };
138 const struct optdesc opt_b600    = { "b600",    NULL, OPT_B600,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B600,     CBAUD };
139 #ifdef B900  /* HP-UX */
140 const struct optdesc opt_b900    = { "b900",    NULL, OPT_B900,    GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B900,     CBAUD };
141 #endif
142 const struct optdesc opt_b1200   = { "b1200",   NULL, OPT_B1200,   GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1200,    CBAUD };
143 const struct optdesc opt_b1800   = { "b1800",   NULL, OPT_B1800,   GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1800,    CBAUD };
144 const struct optdesc opt_b2400   = { "b2400",   NULL, OPT_B2400,   GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B2400,    CBAUD };
145 #ifdef B3600  /* HP-UX */
146 const struct optdesc opt_b3600   = { "b3600",   NULL, OPT_B3600,   GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B3600,    CBAUD };
147 #endif
148 const struct optdesc opt_b4800   = { "b4800",   NULL, OPT_B4800,   GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B4800,    CBAUD };
149 #ifdef B7200  /* HP-UX */
150 const struct optdesc opt_b7200   = { "b7200",   NULL, OPT_B7200,   GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B7200,    CBAUD };
151 #endif
152 const struct optdesc opt_b9600   = { "b9600",   NULL, OPT_B9600,   GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B9600,    CBAUD };
153 const struct optdesc opt_b19200  = { "b19200",  NULL, OPT_B19200,  GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B19200,   CBAUD };
154 const struct optdesc opt_b38400  = { "b38400",  NULL, OPT_B38400,  GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B38400,   CBAUD };
155 #ifdef B57600
156 const struct optdesc opt_b57600  = { "b57600",  NULL, OPT_B57600,  GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B57600,   CBAUD };
157 #endif
158 #ifdef B115200
159 const struct optdesc opt_b115200 = { "b115200", NULL, OPT_B115200, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B115200,  CBAUD };
160 #endif
161 #ifdef B230400
162 const struct optdesc opt_b230400 = { "b230400", NULL, OPT_B230400, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B230400,  CBAUD };
163 #endif
164 #ifdef B460800
165 const struct optdesc opt_b460800 = { "b460800", NULL, OPT_B460800, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B460800,  CBAUD };
166 #endif
167 #ifdef B500000
168 const struct optdesc opt_b500000 = { "b500000", NULL, OPT_B500000, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B500000,  CBAUD };
169 #endif
170 #ifdef B576000
171 const struct optdesc opt_b576000 = { "b576000", NULL, OPT_B576000, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B576000,  CBAUD };
172 #endif
173 #ifdef B921600
174 const struct optdesc opt_b921600 = { "b921600", NULL, OPT_B921600, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B921600,  CBAUD };
175 #endif
176 #ifdef B1000000
177 const struct optdesc opt_b1000000= { "b1000000",NULL, OPT_B1000000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1000000, CBAUD };
178 #endif
179 #ifdef B1152000
180 const struct optdesc opt_b1152000= { "b1152000",NULL, OPT_B1152000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1152000, CBAUD };
181 #endif
182 #ifdef B1500000
183 const struct optdesc opt_b1500000= { "b1500000",NULL, OPT_B1500000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B1500000, CBAUD };
184 #endif
185 #ifdef B2000000
186 const struct optdesc opt_b2000000= { "b2000000",NULL, OPT_B2000000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B2000000, CBAUD };
187 #endif
188 #ifdef B2500000
189 const struct optdesc opt_b2500000= { "b2500000",NULL, OPT_B2500000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B2500000, CBAUD };
190 #endif
191 #ifdef B3000000
192 const struct optdesc opt_b3000000= { "b3000000",NULL, OPT_B3000000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B3000000, CBAUD };
193 #endif
194 #ifdef B3500000
195 const struct optdesc opt_b3500000= { "b3500000",NULL, OPT_B3500000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B3500000, CBAUD };
196 #endif
197 #ifdef B4000000
198 const struct optdesc opt_b4000000= { "b4000000",NULL, OPT_B4000000,GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, B4000000, CBAUD };
199 #endif
200 #endif /* defined(CBAUD) */
201 const struct optdesc opt_cs5     = { "cs5",     NULL, OPT_CS5,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS5, CSIZE };
202 const struct optdesc opt_cs6     = { "cs6",     NULL, OPT_CS6,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS6, CSIZE };
203 const struct optdesc opt_cs7     = { "cs7",     NULL, OPT_CS7,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS7, CSIZE };
204 const struct optdesc opt_cs8     = { "cs8",     NULL, OPT_CS8,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_PATTERN, 2, CS8, CSIZE };
205 #if CSIZE_SHIFT >= 0
206 const struct optdesc opt_csize   = { "csize",   NULL, OPT_CSIZE,   GROUP_TERMIOS, PH_FD, TYPE_UINT,  OFUNC_TERMIOS_VALUE,   2, CSIZE, CSIZE_SHIFT };
207 #endif
208 const struct optdesc opt_cstopb  = { "cstopb",  NULL, OPT_CSTOPB,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    2, CSTOPB };
209 const struct optdesc opt_cread   = { "cread",   NULL, OPT_CREAD,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    2, CREAD };
210 const struct optdesc opt_parenb  = { "parenb",  NULL, OPT_PARENB,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    2, PARENB };
211 const struct optdesc opt_parodd  = { "parodd",  NULL, OPT_PARODD,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    2, PARODD };
212 const struct optdesc opt_hupcl   = { "hupcl",   NULL, OPT_HUPCL,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    2, HUPCL };
213 const struct optdesc opt_clocal  = { "clocal",  NULL, OPT_CLOCAL,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    2, CLOCAL };
214 /*const struct optdesc opt_cibaud  = { "cibaud",NULL,   OPT_CIBAUD,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    2, CIBAUD };*/
215 #ifdef CRTSCTS
216 const struct optdesc opt_crtscts = { "crtscts", NULL, OPT_CRTSCTS, GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG,    2, CRTSCTS };
217 #endif
218 
219 const struct optdesc opt_isig    = { "isig",    NULL, OPT_ISIG,    GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, ISIG };
220 const struct optdesc opt_icanon  = { "icanon",  NULL, OPT_ICANON,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, ICANON };
221 #ifdef XCASE
222 const struct optdesc opt_xcase   = { "xcase",   NULL, OPT_XCASE,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, XCASE };
223 #endif
224 const struct optdesc opt_echo    = { "echo",    NULL, OPT_ECHO,    GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, ECHO };
225 const struct optdesc opt_echoe   = { "echoe",   NULL, OPT_ECHOE,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, ECHOE };
226 const struct optdesc opt_echok   = { "echok",   NULL, OPT_ECHOK,   GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, ECHOK };
227 const struct optdesc opt_echonl  = { "echonl",  NULL, OPT_ECHONL,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, ECHONL };
228 const struct optdesc opt_echoctl = { "echoctl", NULL, OPT_ECHOCTL, GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, ECHOCTL };
229 #ifdef ECHOPRT
230 const struct optdesc opt_echoprt = { "echoprt", NULL, OPT_ECHOPRT, GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, ECHOPRT };
231 #endif
232 const struct optdesc opt_echoke  = { "echoke",  NULL, OPT_ECHOKE,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, ECHOKE };
233 const struct optdesc opt_flusho  = { "flusho",  NULL, OPT_FLUSHO,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, FLUSHO };
234 const struct optdesc opt_noflsh  = { "noflsh",  NULL, OPT_NOFLSH,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, NOFLSH };
235 const struct optdesc opt_tostop  = { "tostop",  NULL, OPT_TOSTOP,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, TOSTOP };
236 #ifdef PENDIN
237 const struct optdesc opt_pendin  = { "pendin",  NULL, OPT_PENDIN,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, PENDIN };
238 #endif
239 const struct optdesc opt_iexten  = { "iexten",  NULL, OPT_IEXTEN,  GROUP_TERMIOS, PH_FD, TYPE_BOOL,  OFUNC_TERMIOS_FLAG, 3, IEXTEN };
240 
241 const struct optdesc opt_vintr    = { "vintr",  "intr",  OPT_VINTR,    GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VINTR };
242 const struct optdesc opt_vquit    = { "vquit",  "quit",  OPT_VQUIT,    GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VQUIT };
243 const struct optdesc opt_verase   = { "verase", "erase", OPT_VERASE,   GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VERASE };
244 const struct optdesc opt_vkill    = { "vkill",  "kill",  OPT_VKILL,    GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VKILL };
245 const struct optdesc opt_veof     = { "veof",   "eof",   OPT_VEOF,     GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VEOF };
246 const struct optdesc opt_vtime    = { "vtime",  "time",  OPT_VTIME,    GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VTIME };
247 const struct optdesc opt_vmin     = { "vmin",   "min",   OPT_VMIN,     GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VMIN };
248 #ifdef VSWTC
249 const struct optdesc opt_vswtc    = { "vswtc",  "swtc",  OPT_VSWTC,    GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VSWTC };
250 #endif /* VSWTC */
251 const struct optdesc opt_vstart   = { "vstart", "start", OPT_VSTART,   GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VSTART };
252 const struct optdesc opt_vstop    = { "vstop",  "stop",  OPT_VSTOP,    GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VSTOP };
253 const struct optdesc opt_vsusp    = { "vsusp",  "susp",  OPT_VSUSP,    GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VSUSP };
254 #ifdef VDSUSP  /* HP-UX */
255 const struct optdesc opt_vdsusp   = { "vdsusp", "dsusp", OPT_VDSUSP,   GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VDSUSP };
256 #endif
257 const struct optdesc opt_veol     = { "veol",   "eol",   OPT_VEOL,     GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VEOL };
258 #ifdef VREPRINT
259 const struct optdesc opt_vreprint = { "vreprint","reprint",OPT_VREPRINT,GROUP_TERMIOS,PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VREPRINT };
260 #endif
261 #ifdef VDISCARD
262 const struct optdesc opt_vdiscard = { "vdiscard","discard",OPT_VDISCARD,GROUP_TERMIOS,PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VDISCARD };
263 #endif
264 #ifdef VWERASE
265 const struct optdesc opt_vwerase  = { "vwerase","werase",OPT_VWERASE,  GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VWERASE };
266 #endif
267 const struct optdesc opt_vlnext   = { "vlnext", "lnext", OPT_VLNEXT,   GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VLNEXT };
268 const struct optdesc opt_veol2    = { "veol2",  "eol2",  OPT_VEOL2,    GROUP_TERMIOS, PH_FD, TYPE_BYTE, OFUNC_TERMIOS_CHAR, VEOL2 };
269 
270 const struct optdesc opt_raw      = { "raw",    NULL,    OPT_RAW,      GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC };
271 const struct optdesc opt_sane     = { "sane",   NULL,    OPT_SANE,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC };
272 const struct optdesc opt_termios_cfmakeraw = { "termios-cfmakeraw", "cfmakeraw", OPT_TERMIOS_CFMAKERAW, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC };
273 const struct optdesc opt_termios_rawer     = { "termios-rawer",     "rawer",     OPT_TERMIOS_RAWER,     GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC };
274 
275 #if HAVE_TERMIOS_ISPEED
276 const struct optdesc opt_ispeed = { "ispeed", NULL, OPT_ISPEED, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_SPEED, 0/*in*/ };
277 #endif
278 #if HAVE_TERMIOS_OSPEED
279 const struct optdesc opt_ospeed = { "ospeed", NULL, OPT_OSPEED, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_SPEED, 1/*out*/ };
280 #endif
281 
282 
xiotermiosflag_applyopt(int fd,struct opt * opt)283 int xiotermiosflag_applyopt(int fd, struct opt *opt) {
284    int result;
285    if (opt->value.u_bool) {
286       result = xiotermios_setflag(fd, opt->desc->major, opt->desc->minor);
287    } else {
288       result = xiotermios_clrflag(fd, opt->desc->major, opt->desc->minor);
289    }
290    if (result < 0) {
291       opt->desc = ODESC_ERROR;
292       return -1;
293    }
294    return 0;
295 }
296 
297 #endif /* WITH_TERMIOS */
298 
299 bool _xiotermios_doit = false;	/* _data has been retrieved and manipulated, set it later */
300 union {
301    struct termios termarg;
302    tcflag_t flags[4];
303 } _xiotermios_data;
304 
xiotermios_setflag(int fd,int word,tcflag_t mask)305 int xiotermios_setflag(int fd, int word, tcflag_t mask) {
306    if (!_xiotermios_doit) {
307       if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
308 	 Error3("tcgetattr(%d, %p): %s",
309 		fd, &_xiotermios_data.termarg, strerror(errno));
310 	 return -1;
311       }
312       _xiotermios_doit = true;
313    }
314    _xiotermios_data.flags[word] |= mask;
315    return 0;
316 }
317 
xiotermios_clrflag(int fd,int word,tcflag_t mask)318 int xiotermios_clrflag(int fd, int word, tcflag_t mask) {
319    if (!_xiotermios_doit) {
320       if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
321 	 Error3("tcgetattr(%d, %p): %s",
322 		fd, &_xiotermios_data.termarg, strerror(errno));
323 	 return -1;
324       }
325       _xiotermios_doit = true;
326    }
327    _xiotermios_data.flags[word] &= ~mask;
328    return 0;
329 }
330 
xiotermios_value(int fd,int word,tcflag_t mask,tcflag_t value)331 int xiotermios_value(int fd, int word, tcflag_t mask, tcflag_t value) {
332    if (!_xiotermios_doit) {
333       if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
334 	 Error3("tcgetattr(%d, %p): %s",
335 		fd, &_xiotermios_data.termarg, strerror(errno));
336 	 return -1;
337       }
338       _xiotermios_doit = true;
339    }
340    _xiotermios_data.flags[word] &= ~mask;
341    _xiotermios_data.flags[word] |= value;
342    return 0;
343 }
344 
xiotermios_char(int fd,int n,unsigned char c)345 int xiotermios_char(int fd, int n, unsigned char c) {
346    if (!_xiotermios_doit) {
347       if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
348 	 Error3("tcgetattr(%d, %p): %s",
349 		fd, &_xiotermios_data.termarg, strerror(errno));
350 	 return -1;
351       }
352       _xiotermios_doit = true;
353    }
354    _xiotermios_data.termarg.c_cc[n] = c;
355    return 0;
356 }
357 
358 #if HAVE_TERMIOS_ISPEED || HAVE_TERMIOS_OSPEED
xiotermios_speed(int fd,int n,speed_t speed)359 int xiotermios_speed(int fd, int n, speed_t speed) {
360    if (!_xiotermios_doit) {
361       if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
362 	 Error3("tcgetattr(%d, %p): %s",
363 		fd, &_xiotermios_data.termarg, strerror(errno));
364 	 return -1;
365       }
366       _xiotermios_doit = true;
367    }
368    if (n == 0) {
369       if (cfsetispeed(&_xiotermios_data.termarg, speed) < 0) {
370 	 Error3("cfsetispeed(%p, "F_speed"): %s",
371 	       &_xiotermios_data.termarg, speed, strerror(errno));
372       }
373    } else {
374       if (cfsetospeed(&_xiotermios_data.termarg, speed) < 0) {
375 	 Error3("cfsetospeed(%p, "F_speed"): %s",
376 	       &_xiotermios_data.termarg, speed, strerror(errno));
377       }
378    }
379 // Tcgetattr(fd, &_xiotermios_data.termarg);
380    return 0;
381 }
382 #endif /* HAVE_TERMIOS_ISPEED */
383 
384 /* those termios parameters that are undefined (system dependent) we define
385    to a neutral form so we may use them in the complex patterns */
386 
387 #ifndef BS0
388 #  define BS0 0
389 #endif
390 #ifndef BSDLY
391 #  define BSDLY 0
392 #endif
393 #ifndef CR0
394 #  define CR0 0
395 #endif
396 #ifndef CRDLY
397 #  define CRDLY 0
398 #endif
399 #ifndef ECHOPRT
400 #  define ECHOPRT 0
401 #endif
402 #ifndef FF0
403 #  define FF0 0
404 #endif
405 #ifndef FFDLY
406 #  define FFDLY 0
407 #endif
408 #ifndef IUCLC
409 #  define IUCLC 0
410 #endif
411 #ifndef NL0
412 #  define NL0 0
413 #endif
414 #ifndef NLDLY
415 #  define NLDLY 0
416 #endif
417 #ifndef OCRNL
418 #  define OCRNL 0
419 #endif
420 #ifndef OFDEL
421 #  define OFDEL 0
422 #endif
423 #ifndef OFILL
424 #  define OFILL 0
425 #endif
426 #ifndef OLCUC
427 #  define OLCUC 0
428 #endif
429 #ifndef ONLRET
430 #  define ONLRET 0
431 #endif
432 #ifndef ONOCR
433 #  define ONOCR 0
434 #endif
435 #ifndef TAB0
436 #  define TAB0 0
437 #endif
438 #ifndef TABDLY
439 #  define TABDLY 0
440 #endif
441 #ifndef VT0
442 #  define VT0 0
443 #endif
444 #ifndef VTDLY
445 #  define VTDLY 0
446 #endif
447 #ifndef XCASE
448 #  define XCASE 0
449 #endif
450 
xiotermios_spec(int fd,int optcode)451 int xiotermios_spec(int fd, int optcode) {
452    if (!_xiotermios_doit) {
453       if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
454 	 Error3("tcgetattr(%d, %p): %s",
455 		fd, &_xiotermios_data.termarg, strerror(errno));
456 	 return -1;
457       }
458       _xiotermios_doit = true;
459    }
460    switch (optcode) {
461    case OPT_RAW:
462       _xiotermios_data.termarg.c_iflag &=
463 	 ~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL);
464       _xiotermios_data.termarg.c_iflag |= (0);
465       _xiotermios_data.termarg.c_oflag &= ~(OPOST);
466       _xiotermios_data.termarg.c_oflag |= (0);
467       _xiotermios_data.termarg.c_cflag &= ~(0);
468       _xiotermios_data.termarg.c_cflag |= (0);
469       _xiotermios_data.termarg.c_lflag &= ~(ISIG|ICANON|XCASE);
470       _xiotermios_data.termarg.c_lflag |= (0);
471       _xiotermios_data.termarg.c_cc[VMIN] = 1;
472       _xiotermios_data.termarg.c_cc[VTIME] = 0;
473       break;
474    case OPT_TERMIOS_RAWER:
475       _xiotermios_data.termarg.c_iflag = 0;
476       _xiotermios_data.termarg.c_oflag = 0;
477       _xiotermios_data.termarg.c_lflag = 0;
478       _xiotermios_data.termarg.c_cflag = (CS8);
479       _xiotermios_data.termarg.c_cc[VMIN] = 1;
480       _xiotermios_data.termarg.c_cc[VTIME] = 0;
481       break;
482    case OPT_SANE:
483       /* cread -ignbrk brkint  -inlcr  -igncr  icrnl
484 	 -ixoff  -iuclc  -ixany  imaxbel opost -olcuc -ocrnl
485 	 onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0
486 	 vt0 ff0 isig icanon iexten echo echoe echok -echonl
487 	 -noflsh -xcase -tostop -echoprt echoctl echoke, and
488 	 also  sets  all special characters to their default
489 	 values.
490       */
491       _xiotermios_data.termarg.c_iflag &= ~(IGNBRK|INLCR|IGNCR|IXOFF|IUCLC|IXANY);
492       _xiotermios_data.termarg.c_iflag |= (BRKINT|ICRNL|IMAXBEL);
493       _xiotermios_data.termarg.c_oflag &= ~(OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
494       _xiotermios_data.termarg.c_oflag |= (OPOST|ONLCR|NL0|CR0|TAB0|BS0|VT0|FF0);
495       _xiotermios_data.termarg.c_cflag &= ~(0);
496       _xiotermios_data.termarg.c_cflag |= (CREAD);
497       _xiotermios_data.termarg.c_lflag &= ~(ECHONL|NOFLSH|XCASE|TOSTOP|ECHOPRT);
498       _xiotermios_data.termarg.c_lflag |= (ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE);
499       /*! "sets characters to their default values... - which? */
500       break;
501    case OPT_TERMIOS_CFMAKERAW:
502 #if HAVE_CFMAKERAW
503       cfmakeraw(&_xiotermios_data.termarg);
504 #else
505       /* these setting follow the Linux documenation of cfmakeraw */
506       _xiotermios_data.termarg.c_iflag &=
507 	 ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
508       _xiotermios_data.termarg.c_oflag &= ~(OPOST);
509       _xiotermios_data.termarg.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
510       _xiotermios_data.termarg.c_cflag &= ~(CSIZE|PARENB);
511       _xiotermios_data.termarg.c_cflag |= (CS8);
512 #endif
513       break;
514    default:
515       Error("TERMIOS option not handled - internal error?");
516       return -1;
517    }
518    return 0;
519 }
520 
xiotermios_flush(int fd)521 int xiotermios_flush(int fd) {
522    if (_xiotermios_doit) {
523       if (Tcsetattr(fd, TCSADRAIN, &_xiotermios_data.termarg) < 0) {
524 	 Error3("tcsetattr(%d, TCSADRAIN, %p): %s",
525 		fd, &_xiotermios_data.termarg, strerror(errno));
526 	 return -1;
527       }
528       _xiotermios_doit = false;
529    }
530    return 0;
531 }
532 
533 #endif /* _WITH_TERMIOS */
534 
535