aboutsummaryrefslogtreecommitdiff
path: root/coreutils/stty.c
diff options
context:
space:
mode:
authorMark Whitley <markw@lineo.com>2001-03-02 20:00:54 +0000
committerMark Whitley <markw@lineo.com>2001-03-02 20:00:54 +0000
commit446dd27843cd9ba7dfa45ef4b28abb2dd83cde8d (patch)
treec836de65a6231f4e1c4b3b25fda8cc6aeac4a3d4 /coreutils/stty.c
parent42ab250709099a1ba6c42e324f828d2a767bae86 (diff)
downloadbusybox-w32-446dd27843cd9ba7dfa45ef4b28abb2dd83cde8d.tar.gz
busybox-w32-446dd27843cd9ba7dfa45ef4b28abb2dd83cde8d.tar.bz2
busybox-w32-446dd27843cd9ba7dfa45ef4b28abb2dd83cde8d.zip
Applied patch from Vladimir N. Oleynik that fixes incorrect behaviour in
recovery_mode and changed option processing.
Diffstat (limited to 'coreutils/stty.c')
-rw-r--r--coreutils/stty.c550
1 files changed, 301 insertions, 249 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c
index 10e28254d..0075b2210 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -24,10 +24,11 @@
24 24
25 David MacKenzie <djm@gnu.ai.mit.edu> 25 David MacKenzie <djm@gnu.ai.mit.edu>
26 26
27 Special for busybox ported by vodz@usa.net 2001 27 Special for busybox ported by Vladimir Oleynik <vodz@usa.net> 2001
28 28
29 */ 29 */
30 30
31//#define TEST
31 32
32#include <termios.h> 33#include <termios.h>
33#include <sys/ioctl.h> 34#include <sys/ioctl.h>
@@ -109,13 +110,13 @@
109# define CSWTCH _POSIX_VDISABLE 110# define CSWTCH _POSIX_VDISABLE
110#endif 111#endif
111 112
112#if defined(VWERSE) && !defined (VWERASE) /* AIX-3.2.5 */ 113#if defined(VWERSE) && !defined (VWERASE) /* AIX-3.2.5 */
113# define VWERASE VWERSE 114# define VWERASE VWERSE
114#endif 115#endif
115#if defined(VDSUSP) && !defined (CDSUSP) 116#if defined(VDSUSP) && !defined (CDSUSP)
116# define CDSUSP Control ('y') 117# define CDSUSP Control ('y')
117#endif 118#endif
118#if !defined(VREPRINT) && defined(VRPRNT) /* Irix 4.0.5 */ 119#if !defined(VREPRINT) && defined(VRPRNT) /* Irix 4.0.5 */
119# define VREPRINT VRPRNT 120# define VREPRINT VRPRNT
120#endif 121#endif
121#if defined(VREPRINT) && !defined(CRPRNT) 122#if defined(VREPRINT) && !defined(CRPRNT)
@@ -130,16 +131,16 @@
130#if defined(VDISCARD) && !defined(VFLUSHO) 131#if defined(VDISCARD) && !defined(VFLUSHO)
131# define VFLUSHO VDISCARD 132# define VFLUSHO VDISCARD
132#endif 133#endif
133#if defined(VFLUSH) && !defined(VFLUSHO) /* Ultrix 4.2 */ 134#if defined(VFLUSH) && !defined(VFLUSHO) /* Ultrix 4.2 */
134# define VFLUSHO VFLUSH 135# define VFLUSHO VFLUSH
135#endif 136#endif
136#if defined(CTLECH) && !defined(ECHOCTL) /* Ultrix 4.3 */ 137#if defined(CTLECH) && !defined(ECHOCTL) /* Ultrix 4.3 */
137# define ECHOCTL CTLECH 138# define ECHOCTL CTLECH
138#endif 139#endif
139#if defined(TCTLECH) && !defined(ECHOCTL) /* Ultrix 4.2 */ 140#if defined(TCTLECH) && !defined(ECHOCTL) /* Ultrix 4.2 */
140# define ECHOCTL TCTLECH 141# define ECHOCTL TCTLECH
141#endif 142#endif
142#if defined(CRTKIL) && !defined(ECHOKE) /* Ultrix 4.2 and 4.3 */ 143#if defined(CRTKIL) && !defined(ECHOKE) /* Ultrix 4.2 and 4.3 */
143# define ECHOKE CRTKIL 144# define ECHOKE CRTKIL
144#endif 145#endif
145#if defined(VFLUSHO) && !defined(CFLUSHO) 146#if defined(VFLUSHO) && !defined(CFLUSHO)
@@ -156,7 +157,7 @@ enum speed_setting {
156 157
157/* What to output and how. */ 158/* What to output and how. */
158enum output_type { 159enum output_type {
159 changed, all, recoverable /* Default, -a, -g. */ 160 changed, all, recoverable /* Default, -a, -g. */
160}; 161};
161 162
162/* Which member(s) of `struct termios' a mode uses. */ 163/* Which member(s) of `struct termios' a mode uses. */
@@ -165,191 +166,189 @@ enum mode_type {
165}; 166};
166 167
167 168
168static const char evenp[] = "evenp"; 169static const char evenp [] = "evenp";
169static const char raw[] = "raw"; 170static const char raw [] = "raw";
170static const char stty_min[] = "min"; 171static const char stty_min [] = "min";
171static const char stty_time[] = "time"; 172static const char stty_time [] = "time";
172static const char stty_swtch[] = "swtch"; 173static const char stty_swtch[] = "swtch";
173static const char stty_eol[] = "eol"; 174static const char stty_eol [] = "eol";
174static const char stty_eof[] = "eof"; 175static const char stty_eof [] = "eof";
175static const char parity[] = "parity"; 176static const char parity [] = "parity";
176static const char stty_oddp[] = "oddp"; 177static const char stty_oddp [] = "oddp";
177static const char stty_nl[] = "nl"; 178static const char stty_nl [] = "nl";
178static const char stty_ek[] = "ek"; 179static const char stty_ek [] = "ek";
179static const char stty_sane[] = "sane"; 180static const char stty_sane [] = "sane";
180static const char cbreak[] = "cbreak"; 181static const char cbreak [] = "cbreak";
181static const char stty_pass8[] = "pass8"; 182static const char stty_pass8[] = "pass8";
182static const char litout[] = "litout"; 183static const char litout [] = "litout";
183static const char cooked[] = "cooked"; 184static const char cooked [] = "cooked";
184static const char decctlq[] = "decctlq"; 185static const char decctlq [] = "decctlq";
185static const char stty_tabs[] = "tabs"; 186static const char stty_tabs [] = "tabs";
186static const char stty_lcase[] = "lcase"; 187static const char stty_lcase[] = "lcase";
187static const char stty_LCASE[] = "LCASE"; 188static const char stty_LCASE[] = "LCASE";
188static const char stty_crt[] = "crt"; 189static const char stty_crt [] = "crt";
189static const char stty_dec[] = "dec"; 190static const char stty_dec [] = "dec";
190 191
191 192
192/* Flags for `struct mode_info'. */ 193/* Flags for `struct mode_info'. */
193#define SANE_SET 1 /* Set in `sane' mode. */ 194#define SANE_SET 1 /* Set in `sane' mode. */
194#define SANE_UNSET 2 /* Unset in `sane' mode. */ 195#define SANE_UNSET 2 /* Unset in `sane' mode. */
195#define REV 4 /* Can be turned off by prepending `-'. */ 196#define REV 4 /* Can be turned off by prepending `-'. */
196#define OMIT 8 /* Don't display value. */ 197#define OMIT 8 /* Don't display value. */
197 198
198/* Each mode. */ 199/* Each mode. */
199struct mode_info { 200struct mode_info {
200 const char *name; /* Name given on command line. */ 201 const char *name; /* Name given on command line. */
201 enum mode_type type; /* Which structure element to change. */ 202 enum mode_type type; /* Which structure element to change. */
202 char flags; /* Setting and display options. */ 203 char flags; /* Setting and display options. */
203 unsigned long bits; /* Bits to set for this mode. */ 204 unsigned long bits; /* Bits to set for this mode. */
204 unsigned long mask; /* Other bits to turn off for this mode. */ 205 unsigned long mask; /* Other bits to turn off for this mode. */
205}; 206};
206 207
207static const struct mode_info mode_info[] = { 208static const struct mode_info mode_info[] = {
208 {"parenb", control, REV, PARENB, 0}, 209 {"parenb", control, REV, PARENB, 0 },
209 {"parodd", control, REV, PARODD, 0}, 210 {"parodd", control, REV, PARODD, 0 },
210 {"cs5", control, 0, CS5, CSIZE}, 211 {"cs5", control, 0, CS5, CSIZE},
211 {"cs6", control, 0, CS6, CSIZE}, 212 {"cs6", control, 0, CS6, CSIZE},
212 {"cs7", control, 0, CS7, CSIZE}, 213 {"cs7", control, 0, CS7, CSIZE},
213 {"cs8", control, 0, CS8, CSIZE}, 214 {"cs8", control, 0, CS8, CSIZE},
214 {"hupcl", control, REV, HUPCL, 0}, 215 {"hupcl", control, REV, HUPCL, 0 },
215 {"hup", control, REV | OMIT, HUPCL, 0}, 216 {"hup", control, REV | OMIT, HUPCL, 0 },
216 {"cstopb", control, REV, CSTOPB, 0}, 217 {"cstopb", control, REV, CSTOPB, 0 },
217 {"cread", control, SANE_SET | REV, CREAD, 0}, 218 {"cread", control, SANE_SET | REV, CREAD, 0 },
218 {"clocal", control, REV, CLOCAL, 0}, 219 {"clocal", control, REV, CLOCAL, 0 },
219#ifdef CRTSCTS 220#ifdef CRTSCTS
220 {"crtscts", control, REV, CRTSCTS, 0}, 221 {"crtscts", control, REV, CRTSCTS, 0 },
221#endif 222#endif
222 223 {"ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 },
223 {"ignbrk", input, SANE_UNSET | REV, IGNBRK, 0}, 224 {"brkint", input, SANE_SET | REV, BRKINT, 0 },
224 {"brkint", input, SANE_SET | REV, BRKINT, 0}, 225 {"ignpar", input, REV, IGNPAR, 0 },
225 {"ignpar", input, REV, IGNPAR, 0}, 226 {"parmrk", input, REV, PARMRK, 0 },
226 {"parmrk", input, REV, PARMRK, 0}, 227 {"inpck", input, REV, INPCK, 0 },
227 {"inpck", input, REV, INPCK, 0}, 228 {"istrip", input, REV, ISTRIP, 0 },
228 {"istrip", input, REV, ISTRIP, 0}, 229 {"inlcr", input, SANE_UNSET | REV, INLCR, 0 },
229 {"inlcr", input, SANE_UNSET | REV, INLCR, 0}, 230 {"igncr", input, SANE_UNSET | REV, IGNCR, 0 },
230 {"igncr", input, SANE_UNSET | REV, IGNCR, 0}, 231 {"icrnl", input, SANE_SET | REV, ICRNL, 0 },
231 {"icrnl", input, SANE_SET | REV, ICRNL, 0}, 232 {"ixon", input, REV, IXON, 0 },
232 {"ixon", input, REV, IXON, 0}, 233 {"ixoff", input, SANE_UNSET | REV, IXOFF, 0 },
233 {"ixoff", input, SANE_UNSET | REV, IXOFF, 0}, 234 {"tandem", input, REV | OMIT, IXOFF, 0 },
234 {"tandem", input, REV | OMIT, IXOFF, 0},
235#ifdef IUCLC 235#ifdef IUCLC
236 {"iuclc", input, SANE_UNSET | REV, IUCLC, 0}, 236 {"iuclc", input, SANE_UNSET | REV, IUCLC, 0 },
237#endif 237#endif
238#ifdef IXANY 238#ifdef IXANY
239 {"ixany", input, SANE_UNSET | REV, IXANY, 0}, 239 {"ixany", input, SANE_UNSET | REV, IXANY, 0 },
240#endif 240#endif
241#ifdef IMAXBEL 241#ifdef IMAXBEL
242 {"imaxbel", input, SANE_SET | REV, IMAXBEL, 0}, 242 {"imaxbel", input, SANE_SET | REV, IMAXBEL, 0 },
243#endif 243#endif
244 244 {"opost", output, SANE_SET | REV, OPOST, 0 },
245 {"opost", output, SANE_SET | REV, OPOST, 0},
246#ifdef OLCUC 245#ifdef OLCUC
247 {"olcuc", output, SANE_UNSET | REV, OLCUC, 0}, 246 {"olcuc", output, SANE_UNSET | REV, OLCUC, 0 },
248#endif 247#endif
249#ifdef OCRNL 248#ifdef OCRNL
250 {"ocrnl", output, SANE_UNSET | REV, OCRNL, 0}, 249 {"ocrnl", output, SANE_UNSET | REV, OCRNL, 0 },
251#endif 250#endif
252#ifdef ONLCR 251#ifdef ONLCR
253 {"onlcr", output, SANE_SET | REV, ONLCR, 0}, 252 {"onlcr", output, SANE_SET | REV, ONLCR, 0 },
254#endif 253#endif
255#ifdef ONOCR 254#ifdef ONOCR
256 {"onocr", output, SANE_UNSET | REV, ONOCR, 0}, 255 {"onocr", output, SANE_UNSET | REV, ONOCR, 0 },
257#endif 256#endif
258#ifdef ONLRET 257#ifdef ONLRET
259 {"onlret", output, SANE_UNSET | REV, ONLRET, 0}, 258 {"onlret", output, SANE_UNSET | REV, ONLRET, 0 },
260#endif 259#endif
261#ifdef OFILL 260#ifdef OFILL
262 {"ofill", output, SANE_UNSET | REV, OFILL, 0}, 261 {"ofill", output, SANE_UNSET | REV, OFILL, 0 },
263#endif 262#endif
264#ifdef OFDEL 263#ifdef OFDEL
265 {"ofdel", output, SANE_UNSET | REV, OFDEL, 0}, 264 {"ofdel", output, SANE_UNSET | REV, OFDEL, 0 },
266#endif 265#endif
267#ifdef NLDLY 266#ifdef NLDLY
268 {"nl1", output, SANE_UNSET, NL1, NLDLY}, 267 {"nl1", output, SANE_UNSET, NL1, NLDLY},
269 {"nl0", output, SANE_SET, NL0, NLDLY}, 268 {"nl0", output, SANE_SET, NL0, NLDLY},
270#endif 269#endif
271#ifdef CRDLY 270#ifdef CRDLY
272 {"cr3", output, SANE_UNSET, CR3, CRDLY}, 271 {"cr3", output, SANE_UNSET, CR3, CRDLY},
273 {"cr2", output, SANE_UNSET, CR2, CRDLY}, 272 {"cr2", output, SANE_UNSET, CR2, CRDLY},
274 {"cr1", output, SANE_UNSET, CR1, CRDLY}, 273 {"cr1", output, SANE_UNSET, CR1, CRDLY},
275 {"cr0", output, SANE_SET, CR0, CRDLY}, 274 {"cr0", output, SANE_SET, CR0, CRDLY},
276#endif 275#endif
276
277#ifdef TABDLY 277#ifdef TABDLY
278 {"tab3", output, SANE_UNSET, TAB3, TABDLY}, 278 {"tab3", output, SANE_UNSET, TAB3, TABDLY},
279 {"tab2", output, SANE_UNSET, TAB2, TABDLY}, 279 {"tab2", output, SANE_UNSET, TAB2, TABDLY},
280 {"tab1", output, SANE_UNSET, TAB1, TABDLY}, 280 {"tab1", output, SANE_UNSET, TAB1, TABDLY},
281 {"tab0", output, SANE_SET, TAB0, TABDLY}, 281 {"tab0", output, SANE_SET, TAB0, TABDLY},
282#else 282#else
283# ifdef OXTABS 283# ifdef OXTABS
284 {"tab3", output, SANE_UNSET, OXTABS, 0}, 284 {"tab3", output, SANE_UNSET, OXTABS, 0 },
285# endif 285# endif
286#endif 286#endif
287
287#ifdef BSDLY 288#ifdef BSDLY
288 {"bs1", output, SANE_UNSET, BS1, BSDLY}, 289 {"bs1", output, SANE_UNSET, BS1, BSDLY},
289 {"bs0", output, SANE_SET, BS0, BSDLY}, 290 {"bs0", output, SANE_SET, BS0, BSDLY},
290#endif 291#endif
291#ifdef VTDLY 292#ifdef VTDLY
292 {"vt1", output, SANE_UNSET, VT1, VTDLY}, 293 {"vt1", output, SANE_UNSET, VT1, VTDLY},
293 {"vt0", output, SANE_SET, VT0, VTDLY}, 294 {"vt0", output, SANE_SET, VT0, VTDLY},
294#endif 295#endif
295#ifdef FFDLY 296#ifdef FFDLY
296 {"ff1", output, SANE_UNSET, FF1, FFDLY}, 297 {"ff1", output, SANE_UNSET, FF1, FFDLY},
297 {"ff0", output, SANE_SET, FF0, FFDLY}, 298 {"ff0", output, SANE_SET, FF0, FFDLY},
298#endif 299#endif
299 300 {"isig", local, SANE_SET | REV, ISIG, 0 },
300 {"isig", local, SANE_SET | REV, ISIG, 0}, 301 {"icanon", local, SANE_SET | REV, ICANON, 0 },
301 {"icanon", local, SANE_SET | REV, ICANON, 0},
302#ifdef IEXTEN 302#ifdef IEXTEN
303 {"iexten", local, SANE_SET | REV, IEXTEN, 0}, 303 {"iexten", local, SANE_SET | REV, IEXTEN, 0 },
304#endif 304#endif
305 {"echo", local, SANE_SET | REV, ECHO, 0}, 305 {"echo", local, SANE_SET | REV, ECHO, 0 },
306 {"echoe", local, SANE_SET | REV, ECHOE, 0}, 306 {"echoe", local, SANE_SET | REV, ECHOE, 0 },
307 {"crterase", local, REV | OMIT, ECHOE, 0}, 307 {"crterase", local, REV | OMIT, ECHOE, 0 },
308 {"echok", local, SANE_SET | REV, ECHOK, 0}, 308 {"echok", local, SANE_SET | REV, ECHOK, 0 },
309 {"echonl", local, SANE_UNSET | REV, ECHONL, 0}, 309 {"echonl", local, SANE_UNSET | REV, ECHONL, 0 },
310 {"noflsh", local, SANE_UNSET | REV, NOFLSH, 0}, 310 {"noflsh", local, SANE_UNSET | REV, NOFLSH, 0 },
311#ifdef XCASE 311#ifdef XCASE
312 {"xcase", local, SANE_UNSET | REV, XCASE, 0}, 312 {"xcase", local, SANE_UNSET | REV, XCASE, 0 },
313#endif 313#endif
314#ifdef TOSTOP 314#ifdef TOSTOP
315 {"tostop", local, SANE_UNSET | REV, TOSTOP, 0}, 315 {"tostop", local, SANE_UNSET | REV, TOSTOP, 0 },
316#endif 316#endif
317#ifdef ECHOPRT 317#ifdef ECHOPRT
318 {"echoprt", local, SANE_UNSET | REV, ECHOPRT, 0}, 318 {"echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 },
319 {"prterase", local, REV | OMIT, ECHOPRT, 0}, 319 {"prterase", local, REV | OMIT, ECHOPRT, 0 },
320#endif 320#endif
321#ifdef ECHOCTL 321#ifdef ECHOCTL
322 {"echoctl", local, SANE_SET | REV, ECHOCTL, 0}, 322 {"echoctl", local, SANE_SET | REV, ECHOCTL, 0 },
323 {"ctlecho", local, REV | OMIT, ECHOCTL, 0}, 323 {"ctlecho", local, REV | OMIT, ECHOCTL, 0 },
324#endif 324#endif
325#ifdef ECHOKE 325#ifdef ECHOKE
326 {"echoke", local, SANE_SET | REV, ECHOKE, 0}, 326 {"echoke", local, SANE_SET | REV, ECHOKE, 0 },
327 {"crtkill", local, REV | OMIT, ECHOKE, 0}, 327 {"crtkill", local, REV | OMIT, ECHOKE, 0 },
328#endif 328#endif
329 329 {evenp, combination, REV | OMIT, 0, 0 },
330 {evenp, combination, REV | OMIT, 0, 0}, 330 {parity, combination, REV | OMIT, 0, 0 },
331 {parity, combination, REV | OMIT, 0, 0}, 331 {stty_oddp, combination, REV | OMIT, 0, 0 },
332 {stty_oddp, combination, REV | OMIT, 0, 0}, 332 {stty_nl, combination, REV | OMIT, 0, 0 },
333 {stty_nl, combination, REV | OMIT, 0, 0}, 333 {stty_ek, combination, OMIT, 0, 0 },
334 {stty_ek, combination, OMIT, 0, 0}, 334 {stty_sane, combination, OMIT, 0, 0 },
335 {stty_sane, combination, OMIT, 0, 0}, 335 {cooked, combination, REV | OMIT, 0, 0 },
336 {cooked, combination, REV | OMIT, 0, 0}, 336 {raw, combination, REV | OMIT, 0, 0 },
337 {raw, combination, REV | OMIT, 0, 0}, 337 {stty_pass8, combination, REV | OMIT, 0, 0 },
338 {stty_pass8, combination, REV | OMIT, 0, 0}, 338 {litout, combination, REV | OMIT, 0, 0 },
339 {litout, combination, REV | OMIT, 0, 0}, 339 {cbreak, combination, REV | OMIT, 0, 0 },
340 {cbreak, combination, REV | OMIT, 0, 0},
341#ifdef IXANY 340#ifdef IXANY
342 {decctlq, combination, REV | OMIT, 0, 0}, 341 {decctlq, combination, REV | OMIT, 0, 0 },
343#endif 342#endif
344#if defined (TABDLY) || defined (OXTABS) 343#if defined (TABDLY) || defined (OXTABS)
345 {stty_tabs, combination, REV | OMIT, 0, 0}, 344 {stty_tabs, combination, REV | OMIT, 0, 0 },
346#endif 345#endif
347#if defined(XCASE) && defined(IUCLC) && defined(OLCUC) 346#if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
348 {stty_lcase, combination, REV | OMIT, 0, 0}, 347 {stty_lcase, combination, REV | OMIT, 0, 0 },
349 {stty_LCASE, combination, REV | OMIT, 0, 0}, 348 {stty_LCASE, combination, REV | OMIT, 0, 0 },
350#endif 349#endif
351 {stty_crt, combination, OMIT, 0, 0}, 350 {stty_crt, combination, OMIT, 0, 0 },
352 {stty_dec, combination, OMIT, 0, 0}, 351 {stty_dec, combination, OMIT, 0, 0 },
353}; 352};
354 353
355static const int NUM_mode_info = 354static const int NUM_mode_info =
@@ -358,83 +357,81 @@ static const int NUM_mode_info =
358 357
359/* Control character settings. */ 358/* Control character settings. */
360struct control_info { 359struct control_info {
361 const char *name; /* Name given on command line. */ 360 const char *name; /* Name given on command line. */
362 unsigned char saneval; /* Value to set for `stty sane'. */ 361 unsigned char saneval; /* Value to set for `stty sane'. */
363 int offset; /* Offset in c_cc. */ 362 int offset; /* Offset in c_cc. */
364}; 363};
365 364
366/* Control characters. */ 365/* Control characters. */
367 366
368static const struct control_info control_info[] = { 367static const struct control_info control_info[] = {
369 {"intr", CINTR, VINTR}, 368 {"intr", CINTR, VINTR},
370 {"quit", CQUIT, VQUIT}, 369 {"quit", CQUIT, VQUIT},
371 {"erase", CERASE, VERASE}, 370 {"erase", CERASE, VERASE},
372 {"kill", CKILL, VKILL}, 371 {"kill", CKILL, VKILL},
373 {stty_eof, CEOF, VEOF}, 372 {stty_eof, CEOF, VEOF},
374 {stty_eol, CEOL, VEOL}, 373 {stty_eol, CEOL, VEOL},
375#ifdef VEOL2 374#ifdef VEOL2
376 {"eol2", CEOL2, VEOL2}, 375 {"eol2", CEOL2, VEOL2},
377#endif 376#endif
378#ifdef VSWTCH 377#ifdef VSWTCH
379 {stty_swtch, CSWTCH, VSWTCH}, 378 {stty_swtch, CSWTCH, VSWTCH},
380#endif 379#endif
381 {"start", CSTART, VSTART}, 380 {"start", CSTART, VSTART},
382 {"stop", CSTOP, VSTOP}, 381 {"stop", CSTOP, VSTOP},
383 {"susp", CSUSP, VSUSP}, 382 {"susp", CSUSP, VSUSP},
384#ifdef VDSUSP 383#ifdef VDSUSP
385 {"dsusp", CDSUSP, VDSUSP}, 384 {"dsusp", CDSUSP, VDSUSP},
386#endif 385#endif
387#ifdef VREPRINT 386#ifdef VREPRINT
388 {"rprnt", CRPRNT, VREPRINT}, 387 {"rprnt", CRPRNT, VREPRINT},
389#endif 388#endif
390#ifdef VWERASE 389#ifdef VWERASE
391 {"werase", CWERASE, VWERASE}, 390 {"werase", CWERASE, VWERASE},
392#endif 391#endif
393#ifdef VLNEXT 392#ifdef VLNEXT
394 {"lnext", CLNEXT, VLNEXT}, 393 {"lnext", CLNEXT, VLNEXT},
395#endif 394#endif
396#ifdef VFLUSHO 395#ifdef VFLUSHO
397 {"flush", CFLUSHO, VFLUSHO}, 396 {"flush", CFLUSHO, VFLUSHO},
398#endif 397#endif
399#ifdef VSTATUS 398#ifdef VSTATUS
400 {"status", CSTATUS, VSTATUS}, 399 {"status", CSTATUS, VSTATUS},
401#endif 400#endif
402
403 /* These must be last because of the display routines. */ 401 /* These must be last because of the display routines. */
404 {stty_min, 1, VMIN}, 402 {stty_min, 1, VMIN},
405 {stty_time, 0, VTIME}, 403 {stty_time, 0, VTIME},
406}; 404};
407 405
408static const int NUM_control_info = 406static const int NUM_control_info =
409 (sizeof(control_info) / sizeof(struct control_info)); 407 (sizeof(control_info) / sizeof(struct control_info));
410 408
411 409
412static const char *visible(unsigned int ch); 410static const char * visible(unsigned int ch);
413static unsigned long baud_to_value(speed_t speed); 411static unsigned long baud_to_value(speed_t speed);
414static int recover_mode(char *arg, struct termios *mode); 412static int recover_mode(char *arg, struct termios *mode);
415static int screen_columns(void); 413static int screen_columns(void);
416static int set_mode(const struct mode_info *info, 414static int set_mode(const struct mode_info *info,
417 int reversed, struct termios *mode); 415 int reversed, struct termios *mode);
418static speed_t string_to_baud(const char *arg); 416static speed_t string_to_baud(const char *arg);
419static tcflag_t *mode_type_flag(enum mode_type type, struct termios *mode); 417static tcflag_t* mode_type_flag(enum mode_type type, struct termios *mode);
420static void display_all(struct termios *mode, int fd, 418static void display_all(struct termios *mode, int fd,
421 const char *device_name); 419 const char *device_name);
422static void display_changed(struct termios *mode); 420static void display_changed(struct termios *mode);
423static void display_recoverable(struct termios *mode); 421static void display_recoverable(struct termios *mode);
424static void display_settings(enum output_type output_type, 422static void display_settings(enum output_type output_type,
425 struct termios *mode, int fd, 423 struct termios *mode, int fd,
426 const char *device_name); 424 const char *device_name);
427static void display_speed(struct termios *mode, int fancy); 425static void display_speed(struct termios *mode, int fancy);
428static void display_window_size(int fancy, int fd, 426static void display_window_size(int fancy, int fd,
429 const char *device_name); 427 const char *device_name);
430static void sane_mode(struct termios *mode); 428static void sane_mode(struct termios *mode);
431static void set_control_char(const struct control_info *info, 429static void set_control_char(const struct control_info *info,
432 const char *arg, struct termios *mode); 430 const char *arg, struct termios *mode);
433static void set_speed(enum speed_setting type, 431static void set_speed(enum speed_setting type,
434 const char *arg, struct termios *mode); 432 const char *arg, struct termios *mode);
435static void set_window_size(int rows, int cols, int fd, 433static void set_window_size(int rows, int cols, int fd,
436 434 const char *device_name);
437 const char *device_name);
438 435
439/* The width of the screen, for output wrapping. */ 436/* The width of the screen, for output wrapping. */
440static int max_col; 437static int max_col;
@@ -449,7 +446,7 @@ static int current_col;
449static void wrapf(const char *message, ...) 446static void wrapf(const char *message, ...)
450{ 447{
451 va_list args; 448 va_list args;
452 char buf[1024]; /* Plenty long for our needs. */ 449 char buf[1024]; /* Plenty long for our needs. */
453 int buflen; 450 int buflen;
454 451
455 va_start(args, message); 452 va_start(args, message);
@@ -469,25 +466,29 @@ static void wrapf(const char *message, ...)
469} 466}
470 467
471static const struct suffix_mult stty_suffixes[] = { 468static const struct suffix_mult stty_suffixes[] = {
472 {"b", 512}, 469 {"b", 512 },
473 {"k", 1024}, 470 {"k", 1024},
474 {"B", 1024}, 471 {"B", 1024},
475 {NULL, 0} 472 {NULL, 0 }
476}; 473};
477 474
475#ifndef TEST
478extern int stty_main(int argc, char **argv) 476extern int stty_main(int argc, char **argv)
477#else
478extern int main(int argc, char **argv)
479#endif
479{ 480{
480 struct termios mode; 481 struct termios mode;
481 enum output_type output_type; 482 enum output_type output_type;
482 int optc; 483 int optc;
483 int require_set_attr; 484 int require_set_attr;
484 int speed_was_set; 485 int speed_was_set;
485 int verbose_output; 486 int verbose_output;
486 int recoverable_output; 487 int recoverable_output;
487 int k; 488 int k;
488 int noargs = 1; 489 int noargs = 1;
489 char *file_name = NULL; 490 char * file_name = NULL;
490 int fd; 491 int fd;
491 const char *device_name; 492 const char *device_name;
492 493
493 output_type = changed; 494 output_type = changed;
@@ -515,7 +516,7 @@ extern int stty_main(int argc, char **argv)
515 file_name = optarg; 516 file_name = optarg;
516 break; 517 break;
517 518
518 default: /* unrecognized option */ 519 default: /* unrecognized option */
519 noargs = 0; 520 noargs = 0;
520 break; 521 break;
521 } 522 }
@@ -581,43 +582,39 @@ extern int stty_main(int argc, char **argv)
581 ++argv[k]; 582 ++argv[k];
582 reversed = 1; 583 reversed = 1;
583 } 584 }
584 for (i = 0; i < NUM_mode_info; ++i) { 585 for (i = 0; i < NUM_mode_info; ++i)
585 if (STREQ(argv[k], mode_info[i].name)) { 586 if (STREQ(argv[k], mode_info[i].name)) {
586 match_found = set_mode(&mode_info[i], reversed, &mode); 587 match_found = set_mode(&mode_info[i], reversed, &mode);
587 require_set_attr = 1; 588 require_set_attr = 1;
588 break; 589 break;
589 } 590 }
590 } 591
591 if (match_found == 0 && reversed) { 592 if (match_found == 0 && reversed)
592 error_msg_and_die("invalid argument `%s'", --argv[k]); 593 error_msg_and_die("invalid argument `%s'", --argv[k]);
593 } 594
594 if (match_found == 0) { 595 if (match_found == 0)
595 for (i = 0; i < NUM_control_info; ++i) { 596 for (i = 0; i < NUM_control_info; ++i)
596 if (STREQ(argv[k], control_info[i].name)) { 597 if (STREQ(argv[k], control_info[i].name)) {
597 if (k == argc - 1) { 598 if (k == argc - 1)
598 error_msg_and_die("missing argument to `%s'", argv[k]); 599 error_msg_and_die("missing argument to `%s'", argv[k]);
599 }
600 match_found = 1; 600 match_found = 1;
601 ++k; 601 ++k;
602 set_control_char(&control_info[i], argv[k], &mode); 602 set_control_char(&control_info[i], argv[k], &mode);
603 require_set_attr = 1; 603 require_set_attr = 1;
604 break; 604 break;
605 } 605 }
606 } 606
607 }
608 if (match_found == 0) { 607 if (match_found == 0) {
609 if (STREQ(argv[k], "ispeed")) { 608 if (STREQ(argv[k], "ispeed")) {
610 if (k == argc - 1) { 609 if (k == argc - 1)
611 error_msg_and_die("missing argument to `%s'", argv[k]); 610 error_msg_and_die("missing argument to `%s'", argv[k]);
612 }
613 ++k; 611 ++k;
614 set_speed(input_speed, argv[k], &mode); 612 set_speed(input_speed, argv[k], &mode);
615 speed_was_set = 1; 613 speed_was_set = 1;
616 require_set_attr = 1; 614 require_set_attr = 1;
617 } else if (STREQ(argv[k], "ospeed")) { 615 } else if (STREQ(argv[k], "ospeed")) {
618 if (k == argc - 1) { 616 if (k == argc - 1)
619 error_msg_and_die("missing argument to `%s'", argv[k]); 617 error_msg_and_die("missing argument to `%s'", argv[k]);
620 }
621 ++k; 618 ++k;
622 set_speed(output_speed, argv[k], &mode); 619 set_speed(output_speed, argv[k], &mode);
623 speed_was_set = 1; 620 speed_was_set = 1;
@@ -625,20 +622,18 @@ extern int stty_main(int argc, char **argv)
625 } 622 }
626#ifdef TIOCGWINSZ 623#ifdef TIOCGWINSZ
627 else if (STREQ(argv[k], "rows")) { 624 else if (STREQ(argv[k], "rows")) {
628 if (k == argc - 1) { 625 if (k == argc - 1)
629 error_msg_and_die("missing argument to `%s'", argv[k]); 626 error_msg_and_die("missing argument to `%s'", argv[k]);
630 }
631 ++k; 627 ++k;
632 set_window_size((int) parse_number(argv[k], stty_suffixes), 628 set_window_size((int) parse_number(argv[k], stty_suffixes),
633 -1, fd, device_name); 629 -1, fd, device_name);
634 } else if (STREQ(argv[k], "cols") || STREQ(argv[k], "columns")) { 630 } else if (STREQ(argv[k], "cols") || STREQ(argv[k], "columns")) {
635 if (k == argc - 1) { 631 if (k == argc - 1)
636 error_msg_and_die("missing argument to `%s'", argv[k]); 632 error_msg_and_die("missing argument to `%s'", argv[k]);
637 }
638 ++k; 633 ++k;
639 set_window_size(-1, 634 set_window_size(-1,
640 (int) parse_number(argv[k], stty_suffixes), 635 (int) parse_number(argv[k], stty_suffixes),
641 fd, device_name); 636 fd, device_name);
642 } else if (STREQ(argv[k], "size")) { 637 } else if (STREQ(argv[k], "size")) {
643 max_col = screen_columns(); 638 max_col = screen_columns();
644 current_col = 0; 639 current_col = 0;
@@ -647,9 +642,8 @@ extern int stty_main(int argc, char **argv)
647#endif 642#endif
648#ifdef HAVE_C_LINE 643#ifdef HAVE_C_LINE
649 else if (STREQ(argv[k], "line")) { 644 else if (STREQ(argv[k], "line")) {
650 if (k == argc - 1) { 645 if (k == argc - 1)
651 error_msg_and_die("missing argument to `%s'", argv[k]); 646 error_msg_and_die("missing argument to `%s'", argv[k]);
652 }
653 ++k; 647 ++k;
654 mode.c_line = parse_number(argv[k], stty_suffixes); 648 mode.c_line = parse_number(argv[k], stty_suffixes);
655 require_set_attr = 1; 649 require_set_attr = 1;
@@ -658,16 +652,14 @@ extern int stty_main(int argc, char **argv)
658 else if (STREQ(argv[k], "speed")) { 652 else if (STREQ(argv[k], "speed")) {
659 max_col = screen_columns(); 653 max_col = screen_columns();
660 display_speed(&mode, 0); 654 display_speed(&mode, 0);
661 } else if (string_to_baud(argv[k]) != (speed_t) - 1) { 655 } else if (recover_mode(argv[k], &mode) == 1)
656 require_set_attr = 1;
657 else if (string_to_baud(argv[k]) != (speed_t) - 1) {
662 set_speed(both_speeds, argv[k], &mode); 658 set_speed(both_speeds, argv[k], &mode);
663 speed_was_set = 1; 659 speed_was_set = 1;
664 require_set_attr = 1; 660 require_set_attr = 1;
665 } else { 661 } else
666 if (recover_mode(argv[k], &mode) == 0) { 662 error_msg_and_die("invalid argument `%s'", argv[k]);
667 error_msg_and_die("invalid argument `%s'", argv[k]);
668 }
669 require_set_attr = 1;
670 }
671 } 663 }
672 k++; 664 k++;
673 } 665 }
@@ -712,21 +704,8 @@ extern int stty_main(int argc, char **argv)
712 new_mode.c_cflag &= (~CIBAUD); 704 new_mode.c_cflag &= (~CIBAUD);
713 if (speed_was_set || memcmp(&mode, &new_mode, sizeof(mode)) != 0) 705 if (speed_was_set || memcmp(&mode, &new_mode, sizeof(mode)) != 0)
714#endif 706#endif
715 {
716 error_msg_and_die ("%s: unable to perform all requested operations", 707 error_msg_and_die ("%s: unable to perform all requested operations",
717 device_name); 708 device_name);
718#ifdef TESTING
719 {
720 size_t i;
721
722 printf("new_mode: mode\n");
723 for (i = 0; i < sizeof(new_mode); i++)
724 printf("0x%02x: 0x%02x\n",
725 *(((unsigned char *) &new_mode) + i),
726 *(((unsigned char *) &mode) + i));
727 }
728#endif
729 }
730 } 709 }
731 } 710 }
732 711
@@ -882,9 +861,9 @@ set_mode(const struct mode_info *info, int reversed, struct termios *mode)
882#endif 861#endif
883 ; 862 ;
884 else if (info->name == stty_dec) { 863 else if (info->name == stty_dec) {
885 mode->c_cc[VINTR] = 3; /* ^C */ 864 mode->c_cc[VINTR] = 3; /* ^C */
886 mode->c_cc[VERASE] = 127; /* DEL */ 865 mode->c_cc[VERASE] = 127; /* DEL */
887 mode->c_cc[VKILL] = 21; /* ^U */ 866 mode->c_cc[VKILL] = 21; /* ^U */
888 mode->c_lflag |= ECHOE 867 mode->c_lflag |= ECHOE
889#ifdef ECHOCTL 868#ifdef ECHOCTL
890 | ECHOCTL 869 | ECHOCTL
@@ -917,11 +896,11 @@ set_control_char(const struct control_info *info, const char *arg,
917 value = arg[0]; 896 value = arg[0];
918 else if (STREQ(arg, "^-") || STREQ(arg, "undef")) 897 else if (STREQ(arg, "^-") || STREQ(arg, "undef"))
919 value = _POSIX_VDISABLE; 898 value = _POSIX_VDISABLE;
920 else if (arg[0] == '^' && arg[1] != '\0') { /* Ignore any trailing junk. */ 899 else if (arg[0] == '^' && arg[1] != '\0') { /* Ignore any trailing junk. */
921 if (arg[1] == '?') 900 if (arg[1] == '?')
922 value = 127; 901 value = 127;
923 else 902 else
924 value = arg[1] & ~0140; /* Non-letters get weird results. */ 903 value = arg[1] & ~0140; /* Non-letters get weird results. */
925 } else 904 } else
926 value = parse_number(arg, stty_suffixes); 905 value = parse_number(arg, stty_suffixes);
927 mode->c_cc[info->offset] = value; 906 mode->c_cc[info->offset] = value;
@@ -1047,7 +1026,7 @@ static tcflag_t *mode_type_flag(enum mode_type type, struct termios *mode)
1047 case local: 1026 case local:
1048 return &mode->c_lflag; 1027 return &mode->c_lflag;
1049 1028
1050 default: /* combination: */ 1029 default: /* combination: */
1051 return NULL; 1030 return NULL;
1052 } 1031 }
1053} 1032}
@@ -1262,8 +1241,8 @@ static int recover_mode(char *arg, struct termios *mode)
1262} 1241}
1263 1242
1264struct speed_map { 1243struct speed_map {
1265 speed_t speed; /* Internal form. */ 1244 speed_t speed; /* Internal form. */
1266 unsigned long value; /* Numeric value. */ 1245 unsigned long value; /* Numeric value. */
1267}; 1246};
1268 1247
1269static const struct speed_map speeds[] = { 1248static const struct speed_map speeds[] = {
@@ -1382,6 +1361,79 @@ static const char *visible(unsigned int ch)
1382 return (const char *) buf; 1361 return (const char *) buf;
1383} 1362}
1384 1363
1364#ifdef TEST
1365unsigned long parse_number(const char *numstr,
1366 const struct suffix_mult *suffixes)
1367{
1368 const struct suffix_mult *sm;
1369 unsigned long int ret;
1370 int len;
1371 char *end;
1372
1373 ret = strtoul(numstr, &end, 10);
1374 if (numstr == end)
1375 error_msg_and_die("invalid number `%s'", numstr);
1376 while (end[0] != '\0') {
1377 sm = suffixes;
1378 while ( sm != 0 ) {
1379 if(sm->suffix) {
1380 len = strlen(sm->suffix);
1381 if (strncmp(sm->suffix, end, len) == 0) {
1382 ret *= sm->mult;
1383 end += len;
1384 break;
1385 }
1386 sm++;
1387
1388 } else
1389 sm = 0;
1390 }
1391 if (sm == 0)
1392 error_msg_and_die("invalid number `%s'", numstr);
1393 }
1394 return ret;
1395}
1396
1397const char *applet_name = "stty";
1398
1399static void verror_msg(const char *s, va_list p)
1400{
1401 fflush(stdout);
1402 fprintf(stderr, "%s: ", applet_name);
1403 vfprintf(stderr, s, p);
1404}
1405
1406extern void error_msg_and_die(const char *s, ...)
1407{
1408 va_list p;
1409
1410 va_start(p, s);
1411 verror_msg(s, p);
1412 va_end(p);
1413 putc('\n', stderr);
1414 exit(EXIT_FAILURE);
1415}
1416
1417static void vperror_msg(const char *s, va_list p)
1418{
1419 int err=errno;
1420 verror_msg(s, p);
1421 if (*s) s = ": ";
1422 fprintf(stderr, "%s%s\n", s, strerror(err));
1423}
1424
1425extern void perror_msg_and_die(const char *s, ...)
1426{
1427 va_list p;
1428
1429 va_start(p, s);
1430 vperror_msg(s, p);
1431 va_end(p);
1432 exit(EXIT_FAILURE);
1433}
1434
1435#endif
1436
1385/* 1437/*
1386Local Variables: 1438Local Variables:
1387c-file-style: "linux" 1439c-file-style: "linux"