1 /* stty -- change and print terminal line settings
2 Copyright (C) 1990-1999 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Usage: stty [-ag] [--all] [--save] [-F device] [--file=device] [setting...]
21 -a, --all Write all current settings to stdout in human-readable form.
22 -g, --save Write all current settings to stdout in stty-readable form.
23 -F, --file Open and use the specified device instead of stdin
25 If no args are given, write to stdout the baud rate and settings that
26 have been changed from their defaults. Mode reading and changes
27 are done on the specified device, or stdin if none was specified.
29 David MacKenzie <djm@gnu.ai.mit.edu> */
33 #ifdef TERMIOS_NEEDS_XOPEN_SOURCE
34 # define _XOPEN_SOURCE
38 #include <sys/types.h>
42 #ifdef GWINSZ_IN_SYS_IOCTL
43 # include <sys/ioctl.h>
45 #ifdef WINSIZE_IN_PTEM
46 # include <sys/stream.h>
47 # include <sys/ptem.h>
49 #ifdef GWINSZ_IN_SYS_PTY
50 # include <sys/ioctl.h>
57 # define VA_START(args, lastarg) va_start(args, lastarg)
60 # define VA_START(args, lastarg) va_start(args)
64 #include "long-options.h"
68 /* The official name of this program (e.g., no `g' prefix). */
69 #define PROGRAM_NAME "stty"
71 #define AUTHORS "David MacKenzie"
73 #ifndef _POSIX_VDISABLE
74 # define _POSIX_VDISABLE ((unsigned char) 0)
77 #define Control(c) ((c) & 0x1f)
78 /* Canonical values for control characters. */
80 # define CINTR Control ('c')
89 # define CKILL Control ('u')
92 # define CEOF Control ('d')
95 # define CEOL _POSIX_VDISABLE
98 # define CSTART Control ('q')
101 # define CSTOP Control ('s')
104 # define CSUSP Control ('z')
106 #if defined(VEOL2) && !defined(CEOL2)
107 # define CEOL2 _POSIX_VDISABLE
109 /* ISC renamed swtch to susp for termios, but we'll accept either name. */
110 #if defined(VSUSP) && !defined(VSWTCH)
111 # define VSWTCH VSUSP
112 # define CSWTCH CSUSP
114 #if defined(VSWTCH) && !defined(CSWTCH)
115 # define CSWTCH _POSIX_VDISABLE
118 /* SunOS 5.3 loses (^Z doesn't work) if `swtch' is the same as `susp'.
119 So the default is to disable `swtch.' */
120 #if defined (__sparc__) && defined (__svr4__)
122 # define CSWTCH _POSIX_VDISABLE
125 #if defined(VWERSE) && !defined (VWERASE) /* AIX-3.2.5 */
126 # define VWERASE VWERSE
128 #if defined(VDSUSP) && !defined (CDSUSP)
129 # define CDSUSP Control ('y')
131 #if !defined(VREPRINT) && defined(VRPRNT) /* Irix 4.0.5 */
132 # define VREPRINT VRPRNT
134 #if defined(VREPRINT) && !defined(CRPRNT)
135 # define CRPRNT Control ('r')
137 #if defined(VWERASE) && !defined(CWERASE)
138 # define CWERASE Control ('w')
140 #if defined(VLNEXT) && !defined(CLNEXT)
141 # define CLNEXT Control ('v')
143 #if defined(VDISCARD) && !defined(VFLUSHO)
144 # define VFLUSHO VDISCARD
146 #if defined(VFLUSH) && !defined(VFLUSHO) /* Ultrix 4.2 */
147 # define VFLUSHO VFLUSH
149 #if defined(CTLECH) && !defined(ECHOCTL) /* Ultrix 4.3 */
150 # define ECHOCTL CTLECH
152 #if defined(TCTLECH) && !defined(ECHOCTL) /* Ultrix 4.2 */
153 # define ECHOCTL TCTLECH
155 #if defined(CRTKIL) && !defined(ECHOKE) /* Ultrix 4.2 and 4.3 */
156 # define ECHOKE CRTKIL
158 #if defined(VFLUSHO) && !defined(CFLUSHO)
159 # define CFLUSHO Control ('o')
161 #if defined(VSTATUS) && !defined(CSTATUS)
162 # define CSTATUS Control ('t')
165 /* Which speeds to set. */
168 input_speed
, output_speed
, both_speeds
171 /* What to output and how. */
174 changed
, all
, recoverable
/* Default, -a, -g. */
177 /* Which member(s) of `struct termios' a mode uses. */
180 control
, input
, output
, local
, combination
183 /* Flags for `struct mode_info'. */
184 #define SANE_SET 1 /* Set in `sane' mode. */
185 #define SANE_UNSET 2 /* Unset in `sane' mode. */
186 #define REV 4 /* Can be turned off by prepending `-'. */
187 #define OMIT 8 /* Don't display value. */
192 const char *name
; /* Name given on command line. */
193 enum mode_type type
; /* Which structure element to change. */
194 char flags
; /* Setting and display options. */
195 unsigned long bits
; /* Bits to set for this mode. */
196 unsigned long mask
; /* Other bits to turn off for this mode. */
199 static struct mode_info mode_info
[] =
201 {"parenb", control
, REV
, PARENB
, 0},
202 {"parodd", control
, REV
, PARODD
, 0},
203 {"cs5", control
, 0, CS5
, CSIZE
},
204 {"cs6", control
, 0, CS6
, CSIZE
},
205 {"cs7", control
, 0, CS7
, CSIZE
},
206 {"cs8", control
, 0, CS8
, CSIZE
},
207 {"hupcl", control
, REV
, HUPCL
, 0},
208 {"hup", control
, REV
| OMIT
, HUPCL
, 0},
209 {"cstopb", control
, REV
, CSTOPB
, 0},
210 {"cread", control
, SANE_SET
| REV
, CREAD
, 0},
211 {"clocal", control
, REV
, CLOCAL
, 0},
213 {"crtscts", control
, REV
, CRTSCTS
, 0},
216 {"ignbrk", input
, SANE_UNSET
| REV
, IGNBRK
, 0},
217 {"brkint", input
, SANE_SET
| REV
, BRKINT
, 0},
218 {"ignpar", input
, REV
, IGNPAR
, 0},
219 {"parmrk", input
, REV
, PARMRK
, 0},
220 {"inpck", input
, REV
, INPCK
, 0},
221 {"istrip", input
, REV
, ISTRIP
, 0},
222 {"inlcr", input
, SANE_UNSET
| REV
, INLCR
, 0},
223 {"igncr", input
, SANE_UNSET
| REV
, IGNCR
, 0},
224 {"icrnl", input
, SANE_SET
| REV
, ICRNL
, 0},
225 {"ixon", input
, REV
, IXON
, 0},
226 {"ixoff", input
, SANE_UNSET
| REV
, IXOFF
, 0},
227 {"tandem", input
, REV
| OMIT
, IXOFF
, 0},
229 {"iuclc", input
, SANE_UNSET
| REV
, IUCLC
, 0},
232 {"ixany", input
, SANE_UNSET
| REV
, IXANY
, 0},
235 {"imaxbel", input
, SANE_SET
| REV
, IMAXBEL
, 0},
238 {"opost", output
, SANE_SET
| REV
, OPOST
, 0},
240 {"olcuc", output
, SANE_UNSET
| REV
, OLCUC
, 0},
243 {"ocrnl", output
, SANE_UNSET
| REV
, OCRNL
, 0},
246 {"onlcr", output
, SANE_SET
| REV
, ONLCR
, 0},
249 {"onocr", output
, SANE_UNSET
| REV
, ONOCR
, 0},
252 {"onlret", output
, SANE_UNSET
| REV
, ONLRET
, 0},
255 {"ofill", output
, SANE_UNSET
| REV
, OFILL
, 0},
258 {"ofdel", output
, SANE_UNSET
| REV
, OFDEL
, 0},
261 {"nl1", output
, SANE_UNSET
, NL1
, NLDLY
},
262 {"nl0", output
, SANE_SET
, NL0
, NLDLY
},
265 {"cr3", output
, SANE_UNSET
, CR3
, CRDLY
},
266 {"cr2", output
, SANE_UNSET
, CR2
, CRDLY
},
267 {"cr1", output
, SANE_UNSET
, CR1
, CRDLY
},
268 {"cr0", output
, SANE_SET
, CR0
, CRDLY
},
271 {"tab3", output
, SANE_UNSET
, TAB3
, TABDLY
},
272 {"tab2", output
, SANE_UNSET
, TAB2
, TABDLY
},
273 {"tab1", output
, SANE_UNSET
, TAB1
, TABDLY
},
274 {"tab0", output
, SANE_SET
, TAB0
, TABDLY
},
277 {"tab3", output
, SANE_UNSET
, OXTABS
, 0},
281 {"bs1", output
, SANE_UNSET
, BS1
, BSDLY
},
282 {"bs0", output
, SANE_SET
, BS0
, BSDLY
},
285 {"vt1", output
, SANE_UNSET
, VT1
, VTDLY
},
286 {"vt0", output
, SANE_SET
, VT0
, VTDLY
},
289 {"ff1", output
, SANE_UNSET
, FF1
, FFDLY
},
290 {"ff0", output
, SANE_SET
, FF0
, FFDLY
},
293 {"isig", local
, SANE_SET
| REV
, ISIG
, 0},
294 {"icanon", local
, SANE_SET
| REV
, ICANON
, 0},
296 {"iexten", local
, SANE_SET
| REV
, IEXTEN
, 0},
298 {"echo", local
, SANE_SET
| REV
, ECHO
, 0},
299 {"echoe", local
, SANE_SET
| REV
, ECHOE
, 0},
300 {"crterase", local
, REV
| OMIT
, ECHOE
, 0},
301 {"echok", local
, SANE_SET
| REV
, ECHOK
, 0},
302 {"echonl", local
, SANE_UNSET
| REV
, ECHONL
, 0},
303 {"noflsh", local
, SANE_UNSET
| REV
, NOFLSH
, 0},
305 {"xcase", local
, SANE_UNSET
| REV
, XCASE
, 0},
308 {"tostop", local
, SANE_UNSET
| REV
, TOSTOP
, 0},
311 {"echoprt", local
, SANE_UNSET
| REV
, ECHOPRT
, 0},
312 {"prterase", local
, REV
| OMIT
, ECHOPRT
, 0},
315 {"echoctl", local
, SANE_SET
| REV
, ECHOCTL
, 0},
316 {"ctlecho", local
, REV
| OMIT
, ECHOCTL
, 0},
319 {"echoke", local
, SANE_SET
| REV
, ECHOKE
, 0},
320 {"crtkill", local
, REV
| OMIT
, ECHOKE
, 0},
323 {"evenp", combination
, REV
| OMIT
, 0, 0},
324 {"parity", combination
, REV
| OMIT
, 0, 0},
325 {"oddp", combination
, REV
| OMIT
, 0, 0},
326 {"nl", combination
, REV
| OMIT
, 0, 0},
327 {"ek", combination
, OMIT
, 0, 0},
328 {"sane", combination
, OMIT
, 0, 0},
329 {"cooked", combination
, REV
| OMIT
, 0, 0},
330 {"raw", combination
, REV
| OMIT
, 0, 0},
331 {"pass8", combination
, REV
| OMIT
, 0, 0},
332 {"litout", combination
, REV
| OMIT
, 0, 0},
333 {"cbreak", combination
, REV
| OMIT
, 0, 0},
335 {"decctlq", combination
, REV
| OMIT
, 0, 0},
337 #if defined (TABDLY) || defined (OXTABS)
338 {"tabs", combination
, REV
| OMIT
, 0, 0},
340 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
341 {"lcase", combination
, REV
| OMIT
, 0, 0},
342 {"LCASE", combination
, REV
| OMIT
, 0, 0},
344 {"crt", combination
, OMIT
, 0, 0},
345 {"dec", combination
, OMIT
, 0, 0},
347 {NULL
, control
, 0, 0, 0}
350 /* Control character settings. */
353 const char *name
; /* Name given on command line. */
354 unsigned char saneval
; /* Value to set for `stty sane'. */
355 int offset
; /* Offset in c_cc. */
358 /* Control characters. */
360 static struct control_info control_info
[] =
362 {"intr", CINTR
, VINTR
},
363 {"quit", CQUIT
, VQUIT
},
364 {"erase", CERASE
, VERASE
},
365 {"kill", CKILL
, VKILL
},
369 {"eol2", CEOL2
, VEOL2
},
372 {"swtch", CSWTCH
, VSWTCH
},
374 {"start", CSTART
, VSTART
},
375 {"stop", CSTOP
, VSTOP
},
376 {"susp", CSUSP
, VSUSP
},
378 {"dsusp", CDSUSP
, VDSUSP
},
381 {"rprnt", CRPRNT
, VREPRINT
},
384 {"werase", CWERASE
, VWERASE
},
387 {"lnext", CLNEXT
, VLNEXT
},
390 {"flush", CFLUSHO
, VFLUSHO
},
393 {"status", CSTATUS
, VSTATUS
},
396 /* These must be last because of the display routines. */
402 static const char *visible
PARAMS ((unsigned int ch
));
403 static unsigned long baud_to_value
PARAMS ((speed_t speed
));
404 static int recover_mode
PARAMS ((char *arg
, struct termios
*mode
));
405 static int screen_columns
PARAMS ((void));
406 static int set_mode
PARAMS ((struct mode_info
*info
, int reversed
,
407 struct termios
*mode
));
408 static long integer_arg
PARAMS ((const char *s
));
409 static speed_t string_to_baud
PARAMS ((const char *arg
));
410 static tcflag_t
*mode_type_flag
PARAMS ((enum mode_type type
,
411 struct termios
*mode
));
412 static void display_all
PARAMS ((struct termios
*mode
, int fd
,
413 const char *device_name
));
414 static void display_changed
PARAMS ((struct termios
*mode
));
415 static void display_recoverable
PARAMS ((struct termios
*mode
));
416 static void display_settings
PARAMS ((enum output_type output_type
,
417 struct termios
*mode
, int fd
,
418 const char *device_name
));
419 static void display_speed
PARAMS ((struct termios
*mode
, int fancy
));
420 static void display_window_size
PARAMS ((int fancy
, int fd
,
421 const char *device_name
));
422 static void sane_mode
PARAMS ((struct termios
*mode
));
423 static void set_control_char
PARAMS ((struct control_info
*info
,
425 struct termios
*mode
));
426 static void set_speed
PARAMS ((enum speed_setting type
, const char *arg
,
427 struct termios
*mode
));
428 static void set_window_size
PARAMS ((int rows
, int cols
, int fd
,
429 const char *device_name
));
431 /* The width of the screen, for output wrapping. */
434 /* Current position, to know when to wrap. */
435 static int current_col
;
437 static struct option longopts
[] =
439 {"all", no_argument
, NULL
, 'a'},
440 {"save", no_argument
, NULL
, 'g'},
441 {"file", required_argument
, NULL
, 'F'},
445 /* The name this program was run with. */
448 /* Print format string MESSAGE and optional args.
449 Wrap to next line first if it won't fit.
450 Print a space first unless MESSAGE will start a new line. */
455 wrapf (const char *message
,...)
457 wrapf (message
, va_alist
)
463 char buf
[1024]; /* Plenty long for our needs. */
466 VA_START (args
, message
);
467 vsprintf (buf
, message
, args
);
469 buflen
= strlen (buf
);
470 if (current_col
+ (current_col
> 0) + buflen
>= max_col
)
481 current_col
+= buflen
;
488 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
493 Usage: %s [-F device] [--file=device] [SETTING]...\n\
494 or: %s [-F device] [--file=device] [-a|--all]\n\
495 or: %s [-F device] [--file=device] [-g|--save]\n\
497 program_name
, program_name
, program_name
);
499 Print or change terminal characteristics.\n\
501 -a, --all print all current settings in human-readable form\n\
502 -g, --save print all current settings in a stty-readable form\n\
503 -F, --file open and use the specified device instead of stdin\n\
504 --help display this help and exit\n\
505 --version output version information and exit\n\
507 Optional - before SETTING indicates negation. An * marks non-POSIX\n\
508 settings. The underlying system defines which settings are available.\n\
512 Special characters:\n\
513 * dsusp CHAR CHAR will send a terminal stop signal once input flushed\n\
514 eof CHAR CHAR will send an end of file (terminate the input)\n\
515 eol CHAR CHAR will end the line\n\
516 * eol2 CHAR alternate CHAR for ending the line\n\
517 erase CHAR CHAR will erase the last character typed\n\
518 intr CHAR CHAR will send an interrupt signal\n\
519 kill CHAR CHAR will erase the current line\n\
520 * lnext CHAR CHAR will enter the next character quoted\n\
521 quit CHAR CHAR will send a quit signal\n\
522 * rprnt CHAR CHAR will redraw the current line\n\
523 start CHAR CHAR will restart the output after stopping it\n\
524 stop CHAR CHAR will stop the output\n\
525 susp CHAR CHAR will send a terminal stop signal\n\
526 * swtch CHAR CHAR will switch to a different shell layer\n\
527 * werase CHAR CHAR will erase the last word typed\n\
532 N set the input and output speeds to N bauds\n\
533 * cols N tell the kernel that the terminal has N columns\n\
534 * columns N same as cols N\n\
535 ispeed N set the input speed to N\n\
536 * line N use line discipline N\n\
537 min N with -icanon, set N characters minimum for a completed read\n\
538 ospeed N set the output speed to N\n\
539 * rows N tell the kernel that the terminal has N rows\n\
540 * size print the number of rows and columns according to the kernel\n\
541 speed print the terminal speed\n\
542 time N with -icanon, set read timeout of N tenths of a second\n\
547 [-]clocal disable modem control signals\n\
548 [-]cread allow input to be received\n\
549 * [-]crtscts enable RTS/CTS handshaking\n\
550 csN set character size to N bits, N in [5..8]\n\
551 [-]cstopb use two stop bits per character (one with `-')\n\
552 [-]hup send a hangup signal when the last process closes the tty\n\
553 [-]hupcl same as [-]hup\n\
554 [-]parenb generate parity bit in output and expect parity bit in input\n\
555 [-]parodd set odd parity (even with `-')\n\
560 [-]brkint breaks cause an interrupt signal\n\
561 [-]icrnl translate carriage return to newline\n\
562 [-]ignbrk ignore break characters\n\
563 [-]igncr ignore carriage return\n\
564 [-]ignpar ignore characters with parity errors\n\
565 * [-]imaxbel beep and do not flush a full input buffer on a character\n\
566 [-]inlcr translate newline to carriage return\n\
567 [-]inpck enable input parity checking\n\
568 [-]istrip clear high (8th) bit of input characters\n\
569 * [-]iuclc translate uppercase characters to lowercase\n\
570 * [-]ixany let any character restart output, not only start character\n\
571 [-]ixoff enable sending of start/stop characters\n\
572 [-]ixon enable XON/XOFF flow control\n\
573 [-]parmrk mark parity errors (with a 255-0-character sequence)\n\
574 [-]tandem same as [-]ixoff\n\
579 * bsN backspace delay style, N in [0..1]\n\
580 * crN carriage return delay style, N in [0..3]\n\
581 * ffN form feed delay style, N in [0..1]\n\
582 * nlN newline delay style, N in [0..1]\n\
583 * [-]ocrnl translate carriage return to newline\n\
584 * [-]ofdel use delete characters for fill instead of null characters\n\
585 * [-]ofill use fill (padding) characters instead of timing for delays\n\
586 * [-]olcuc translate lowercase characters to uppercase\n\
587 * [-]onlcr translate newline to carriage return-newline\n\
588 * [-]onlret newline performs a carriage return\n\
589 * [-]onocr do not print carriage returns in the first column\n\
590 [-]opost postprocess output\n\
591 * tabN horizontal tab delay style, N in [0..3]\n\
592 * tabs same as tab0\n\
593 * -tabs same as tab3\n\
594 * vtN vertical tab delay style, N in [0..1]\n\
599 [-]crterase echo erase characters as backspace-space-backspace\n\
600 * crtkill kill all line by obeying the echoprt and echoe settings\n\
601 * -crtkill kill all line by obeying the echoctl and echok settings\n\
602 * [-]ctlecho echo control characters in hat notation (`^c')\n\
603 [-]echo echo input characters\n\
604 * [-]echoctl same as [-]ctlecho\n\
605 [-]echoe same as [-]crterase\n\
606 [-]echok echo a newline after a kill character\n\
607 * [-]echoke same as [-]crtkill\n\
608 [-]echonl echo newline even if not echoing other characters\n\
609 * [-]echoprt echo erased characters backward, between `\\' and '/'\n\
610 [-]icanon enable erase, kill, werase, and rprnt special characters\n\
611 [-]iexten enable non-POSIX special characters\n\
612 [-]isig enable interrupt, quit, and suspend special characters\n\
613 [-]noflsh disable flushing after interrupt and quit special characters\n\
614 * [-]prterase same as [-]echoprt\n\
615 * [-]tostop stop background jobs that try to write to the terminal\n\
616 * [-]xcase with icanon, escape with `\\' for uppercase characters\n\
620 Combination settings:\n\
621 * [-]LCASE same as [-]lcase\n\
622 cbreak same as -icanon\n\
623 -cbreak same as icanon\n\
624 cooked same as brkint ignpar istrip icrnl ixon opost isig\n\
625 icanon, eof and eol characters to their default values\n\
626 -cooked same as raw\n\
627 crt same as echoe echoctl echoke\n\
628 dec same as echoe echoctl echoke -ixany intr ^c erase 0177\n\
630 * [-]decctlq same as [-]ixany\n\
631 ek erase and kill characters to their default values\n\
632 evenp same as parenb -parodd cs7\n\
633 -evenp same as -parenb cs8\n\
634 * [-]lcase same as xcase iuclc olcuc\n\
635 litout same as -parenb -istrip -opost cs8\n\
636 -litout same as parenb istrip opost cs7\n\
637 nl same as -icrnl -onlcr\n\
638 -nl same as icrnl -inlcr -igncr onlcr -ocrnl -onlret\n\
639 oddp same as parenb parodd cs7\n\
640 -oddp same as -parenb cs8\n\
641 [-]parity same as [-]evenp\n\
642 pass8 same as -parenb -istrip cs8\n\
643 -pass8 same as parenb istrip cs7\n\
644 raw same as -ignbrk -brkint -ignpar -parmrk -inpck -istrip\n\
645 -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany\n\
646 -imaxbel -opost -isig -icanon -xcase min 1 time 0\n\
647 -raw same as cooked\n\
648 sane same as cread -ignbrk brkint -inlcr -igncr icrnl\n\
649 -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr\n\
650 -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0\n\
651 isig icanon iexten echo echoe echok -echonl -noflsh\n\
652 -xcase -tostop -echoprt echoctl echoke, all special\n\
653 characters to their default values.\n\
657 Handle the tty line connected to standard input. Without arguments,\n\
658 prints baud rate, line discipline, and deviations from stty sane. In\n\
659 settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
660 127; special values ^- or undef used to disable special characters.\n\
662 puts (_("\nReport bugs to <bug-sh-utils@gnu.org>."));
667 /* Return 1 if the string contains only valid options. */
669 valid_options (char *opt
, const char *valid_opts
,
670 const char *valid_arg_opts
)
680 if (strchr (valid_opts
, ch
))
682 if (strchr (valid_arg_opts
, ch
))
690 main (int argc
, char **argv
)
693 enum output_type output_type
;
695 int require_set_attr
;
698 int recoverable_output
;
701 char *file_name
= NULL
;
703 const char *device_name
;
704 const char *posixly_correct
= getenv ("POSIXLY_CORRECT");
705 int invalid_long_option
= 0;
707 program_name
= argv
[0];
708 setlocale (LC_ALL
, "");
709 bindtextdomain (PACKAGE
, LOCALEDIR
);
710 textdomain (PACKAGE
);
712 parse_long_options (argc
, argv
, PROGRAM_NAME
, GNU_PACKAGE
, VERSION
,
715 output_type
= changed
;
717 recoverable_output
= 0;
719 /* Don't print error messages for unrecognized options. */
722 while ((optc
= getopt_long (argc
, argv
, "agF:", longopts
, NULL
)) != -1)
724 int unrecognized_option
= 0;
733 recoverable_output
= 1;
734 output_type
= recoverable
;
739 error (2, 0, _("only one device may be specified"));
744 unrecognized_option
= 1;
748 if (unrecognized_option
)
752 /* FIXME: what is this?!? */
753 if (invalid_long_option
)
756 /* Clear out the options that have been parsed. This is really
757 gross, but it's needed because stty SETTINGS look like options to
758 getopt(), so we need to work around things in a really horrible
759 way. If any new options are ever added to stty, the short option
760 MUST NOT be a letter which is the first letter of one of the
761 possible stty settings. If you change anything about how stty
762 parses options, be sure it still works with combinations of
763 short and long options, --, POSIXLY_CORRECT, etc. */
764 for (k
= 1; k
< argc
; k
++)
772 /* Handle --, and reset noargs if there are arguments following it. */
773 if (STREQ (argv
[k
], "--"))
781 /* Handle "--file device" */
782 len
= strlen (argv
[k
]);
783 if (len
>= 3 && strstr ("--file", argv
[k
]))
790 /* Handle "--all" and "--save". */
792 && (strstr ("--all", argv
[k
])
793 || strstr ("--save", argv
[k
])))
799 /* Handle "--file=device". */
800 eq
= strchr (argv
[k
], '=');
801 if (eq
&& eq
- argv
[k
] >= 3)
804 if (strstr ("--file", argv
[k
]))
809 /* Put the equals sign back for the error message. */
813 /* Handle "-a", "-ag", "-aF/dev/foo", "-aF /dev/foo", etc. */
814 if (valid_options (argv
[k
], "ag", "F"))
816 /* FIXME: this loses when the device name ends in `F'.
817 e.g. `stty -F/dev/BARF nl' would clobber the `nl' argument. */
818 if (argv
[k
][strlen (argv
[k
]) - 1] == 'F')
822 /* Everything else must be a normal, non-option argument. */
831 /* Specifying both -a and -g gets an error. */
832 if (verbose_output
&& recoverable_output
)
834 _("the options for verbose and stty-readable output styles are\n\
835 mutually exclusive"));
837 /* Specifying any other arguments with -a or -g gets an error. */
838 if (!noargs
&& (verbose_output
|| recoverable_output
))
839 error (2, 0, _("when specifying an output style, modes may not be set"));
841 /* FIXME: it'd be better not to open the file until we've verified
842 that all arguments are valid. Otherwise, we could end up doing
843 only some of the requested operations and then failing, probably
844 leaving things in an undesirable state. */
849 device_name
= file_name
;
850 fd
= open (device_name
, O_RDONLY
| O_NONBLOCK
);
852 error (1, errno
, "%s", device_name
);
853 if ((fdflags
= fcntl (fd
, F_GETFL
)) == -1
854 || fcntl (fd
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
855 error (1, errno
, _("%s: couldn't reset non-blocking mode"),
861 device_name
= _("standard input");
864 /* Initialize to all zeroes so there is no risk memcmp will report a
865 spurious difference in an uninitialized portion of the structure. */
866 memset (&mode
, 0, sizeof (mode
));
867 if (tcgetattr (fd
, &mode
))
868 error (1, errno
, "%s", device_name
);
870 if (verbose_output
|| recoverable_output
|| noargs
)
872 max_col
= screen_columns ();
874 display_settings (output_type
, &mode
, fd
, device_name
);
879 require_set_attr
= 0;
893 if (argv
[k
][0] == '-')
898 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
900 if (STREQ (argv
[k
], mode_info
[i
].name
))
902 match_found
= set_mode (&mode_info
[i
], reversed
, &mode
);
903 require_set_attr
= 1;
907 if (match_found
== 0 && reversed
)
909 error (0, 0, _("invalid argument `%s'"), --argv
[k
]);
912 if (match_found
== 0)
914 for (i
= 0; control_info
[i
].name
!= NULL
; ++i
)
916 if (STREQ (argv
[k
], control_info
[i
].name
))
920 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
925 set_control_char (&control_info
[i
], argv
[k
], &mode
);
926 require_set_attr
= 1;
931 if (match_found
== 0)
933 if (STREQ (argv
[k
], "ispeed"))
937 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
941 set_speed (input_speed
, argv
[k
], &mode
);
943 require_set_attr
= 1;
945 else if (STREQ (argv
[k
], "ospeed"))
949 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
953 set_speed (output_speed
, argv
[k
], &mode
);
955 require_set_attr
= 1;
958 else if (STREQ (argv
[k
], "rows"))
962 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
966 set_window_size ((int) integer_arg (argv
[k
]), -1,
969 else if (STREQ (argv
[k
], "cols")
970 || STREQ (argv
[k
], "columns"))
974 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
978 set_window_size (-1, (int) integer_arg (argv
[k
]),
981 else if (STREQ (argv
[k
], "size"))
983 max_col
= screen_columns ();
985 display_window_size (0, fd
, device_name
);
989 else if (STREQ (argv
[k
], "line"))
993 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
997 mode
.c_line
= integer_arg (argv
[k
]);
998 require_set_attr
= 1;
1001 else if (STREQ (argv
[k
], "speed"))
1003 max_col
= screen_columns ();
1004 display_speed (&mode
, 0);
1006 else if (string_to_baud (argv
[k
]) != (speed_t
) -1)
1008 set_speed (both_speeds
, argv
[k
], &mode
);
1010 require_set_attr
= 1;
1014 if (recover_mode (argv
[k
], &mode
) == 0)
1016 error (0, 0, _("invalid argument `%s'"), argv
[k
]);
1019 require_set_attr
= 1;
1025 if (require_set_attr
)
1027 struct termios new_mode
;
1029 if (tcsetattr (fd
, TCSADRAIN
, &mode
))
1030 error (1, errno
, "%s", device_name
);
1032 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
1033 it performs *any* of the requested operations. This means it
1034 can report `success' when it has actually failed to perform
1035 some proper subset of the requested operations. To detect
1036 this partial failure, get the current terminal attributes and
1037 compare them to the requested ones. */
1039 /* Initialize to all zeroes so there is no risk memcmp will report a
1040 spurious difference in an uninitialized portion of the structure. */
1041 memset (&new_mode
, 0, sizeof (new_mode
));
1042 if (tcgetattr (fd
, &new_mode
))
1043 error (1, errno
, "%s", device_name
);
1045 /* Normally, one shouldn't use memcmp to compare structures that
1046 may have `holes' containing uninitialized data, but we have been
1047 careful to initialize the storage of these two variables to all
1048 zeroes. One might think it more efficient simply to compare the
1049 modified fields, but that would require enumerating those fields --
1050 and not all systems have the same fields in this structure. */
1052 if (memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1055 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1056 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1057 sometimes (m1 != m2). The only difference is in the four bits
1058 of the c_cflag field corresponding to the baud rate. To save
1059 Sun users a little confusion, don't report an error if this
1060 happens. But suppress the error only if we haven't tried to
1061 set the baud rate explicitly -- otherwise we'd never give an
1062 error for a true failure to set the baud rate. */
1064 new_mode
.c_cflag
&= (~CIBAUD
);
1065 if (speed_was_set
|| memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1069 _("%s: unable to perform all requested operations"),
1074 printf (_("new_mode: mode\n"));
1075 for (i
= 0; i
< sizeof (new_mode
); i
++)
1076 printf ("0x%02x: 0x%02x\n",
1077 *(((unsigned char *) &new_mode
) + i
),
1078 *(((unsigned char *) &mode
) + i
));
1088 /* Return 0 if not applied because not reversible; otherwise return 1. */
1091 set_mode (struct mode_info
*info
, int reversed
, struct termios
*mode
)
1095 if (reversed
&& (info
->flags
& REV
) == 0)
1098 bitsp
= mode_type_flag (info
->type
, mode
);
1102 /* Combination mode. */
1103 if (STREQ (info
->name
, "evenp") || STREQ (info
->name
, "parity"))
1106 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1108 mode
->c_cflag
= (mode
->c_cflag
& ~PARODD
& ~CSIZE
) | PARENB
| CS7
;
1110 else if (STREQ (info
->name
, "oddp"))
1113 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1115 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARODD
| PARENB
;
1117 else if (STREQ (info
->name
, "nl"))
1121 mode
->c_iflag
= (mode
->c_iflag
| ICRNL
) & ~INLCR
& ~IGNCR
;
1122 mode
->c_oflag
= (mode
->c_oflag
1137 mode
->c_iflag
= mode
->c_iflag
& ~ICRNL
;
1139 mode
->c_oflag
= mode
->c_oflag
& ~ONLCR
;
1143 else if (STREQ (info
->name
, "ek"))
1145 mode
->c_cc
[VERASE
] = CERASE
;
1146 mode
->c_cc
[VKILL
] = CKILL
;
1148 else if (STREQ (info
->name
, "sane"))
1150 else if (STREQ (info
->name
, "cbreak"))
1153 mode
->c_lflag
|= ICANON
;
1155 mode
->c_lflag
&= ~ICANON
;
1157 else if (STREQ (info
->name
, "pass8"))
1161 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1162 mode
->c_iflag
|= ISTRIP
;
1166 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1167 mode
->c_iflag
&= ~ISTRIP
;
1170 else if (STREQ (info
->name
, "litout"))
1174 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1175 mode
->c_iflag
|= ISTRIP
;
1176 mode
->c_oflag
|= OPOST
;
1180 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1181 mode
->c_iflag
&= ~ISTRIP
;
1182 mode
->c_oflag
&= ~OPOST
;
1185 else if (STREQ (info
->name
, "raw") || STREQ (info
->name
, "cooked"))
1187 if ((info
->name
[0] == 'r' && reversed
)
1188 || (info
->name
[0] == 'c' && !reversed
))
1191 mode
->c_iflag
|= BRKINT
| IGNPAR
| ISTRIP
| ICRNL
| IXON
;
1192 mode
->c_oflag
|= OPOST
;
1193 mode
->c_lflag
|= ISIG
| ICANON
;
1195 mode
->c_cc
[VEOF
] = CEOF
;
1198 mode
->c_cc
[VEOL
] = CEOL
;
1205 mode
->c_oflag
&= ~OPOST
;
1206 mode
->c_lflag
&= ~(ISIG
| ICANON
1211 mode
->c_cc
[VMIN
] = 1;
1212 mode
->c_cc
[VTIME
] = 0;
1216 else if (STREQ (info
->name
, "decctlq"))
1219 mode
->c_iflag
|= IXANY
;
1221 mode
->c_iflag
&= ~IXANY
;
1225 else if (STREQ (info
->name
, "tabs"))
1228 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB3
;
1230 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB0
;
1234 else if (STREQ (info
->name
, "tabs"))
1237 mode
->c_oflag
= mode
->c_oflag
| OXTABS
;
1239 mode
->c_oflag
= mode
->c_oflag
& ~OXTABS
;
1243 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
1244 else if (STREQ (info
->name
, "lcase")
1245 || STREQ (info
->name
, "LCASE"))
1249 mode
->c_lflag
&= ~XCASE
;
1250 mode
->c_iflag
&= ~IUCLC
;
1251 mode
->c_oflag
&= ~OLCUC
;
1255 mode
->c_lflag
|= XCASE
;
1256 mode
->c_iflag
|= IUCLC
;
1257 mode
->c_oflag
|= OLCUC
;
1261 else if (STREQ (info
->name
, "crt"))
1262 mode
->c_lflag
|= ECHOE
1270 else if (STREQ (info
->name
, "dec"))
1272 mode
->c_cc
[VINTR
] = 3; /* ^C */
1273 mode
->c_cc
[VERASE
] = 127; /* DEL */
1274 mode
->c_cc
[VKILL
] = 21; /* ^U */
1275 mode
->c_lflag
|= ECHOE
1284 mode
->c_iflag
&= ~IXANY
;
1289 *bitsp
= *bitsp
& ~info
->mask
& ~info
->bits
;
1291 *bitsp
= (*bitsp
& ~info
->mask
) | info
->bits
;
1297 set_control_char (struct control_info
*info
, const char *arg
,
1298 struct termios
*mode
)
1300 unsigned char value
;
1302 if (STREQ (info
->name
, "min") || STREQ (info
->name
, "time"))
1303 value
= integer_arg (arg
);
1304 else if (arg
[0] == '\0' || arg
[1] == '\0')
1306 else if (STREQ (arg
, "^-") || STREQ (arg
, "undef"))
1307 value
= _POSIX_VDISABLE
;
1308 else if (arg
[0] == '^' && arg
[1] != '\0') /* Ignore any trailing junk. */
1313 value
= arg
[1] & ~0140; /* Non-letters get weird results. */
1316 value
= integer_arg (arg
);
1317 mode
->c_cc
[info
->offset
] = value
;
1321 set_speed (enum speed_setting type
, const char *arg
, struct termios
*mode
)
1325 baud
= string_to_baud (arg
);
1326 if (type
== input_speed
|| type
== both_speeds
)
1327 cfsetispeed (mode
, baud
);
1328 if (type
== output_speed
|| type
== both_speeds
)
1329 cfsetospeed (mode
, baud
);
1335 get_win_size (int fd
, struct winsize
*win
)
1337 int err
= ioctl (fd
, TIOCGWINSZ
, (char *) win
);
1342 set_window_size (int rows
, int cols
, int fd
, const char *device_name
)
1346 if (get_win_size (fd
, &win
))
1348 if (errno
!= EINVAL
)
1349 error (1, errno
, "%s", device_name
);
1350 memset (&win
, 0, sizeof (win
));
1359 /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote:
1360 The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.
1361 This comment from sys/ttold.h describes Sun's twisted logic - a better
1362 test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).
1363 At any rate, the problem is gone in Solaris 2.x.
1365 Unfortunately, the old TIOCSSIZE code does collide with TIOCSWINSZ,
1366 but they can be disambiguated by checking whether a "struct ttysize"
1367 structure's "ts_lines" field is greater than 64K or not. If so,
1368 it's almost certainly a "struct winsize" instead.
1370 At any rate, the bug manifests itself when ws_row == 0; the symptom is
1371 that ws_row is set to ws_col, and ws_col is set to (ws_xpixel<<16) +
1372 ws_ypixel. Since GNU stty sets rows and columns separately, this bug
1373 caused "stty rows 0 cols 0" to set rows to cols and cols to 0, while
1374 "stty cols 0 rows 0" would do the right thing. On a little-endian
1375 machine like the sun386i, the problem is the same, but for ws_col == 0.
1377 The workaround is to do the ioctl once with row and col = 1 to set the
1378 pixel info, and then do it again using a TIOCSSIZE to set rows/cols. */
1380 if (win
.ws_row
== 0 || win
.ws_col
== 0)
1382 struct ttysize ttysz
;
1384 ttysz
.ts_lines
= win
.ws_row
;
1385 ttysz
.ts_cols
= win
.ws_col
;
1390 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1391 error (1, errno
, "%s", device_name
);
1393 if (ioctl (fd
, TIOCSSIZE
, (char *) &ttysz
))
1394 error (1, errno
, "%s", device_name
);
1399 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1400 error (1, errno
, "%s", device_name
);
1404 display_window_size (int fancy
, int fd
, const char *device_name
)
1408 if (get_win_size (fd
, &win
))
1410 if (errno
!= EINVAL
)
1411 error (1, errno
, "%s", device_name
);
1413 error (1, 0, _("%s: no size information for this device"), device_name
);
1417 wrapf (fancy
? "rows %d; columns %d;" : "%d %d\n",
1418 win
.ws_row
, win
.ws_col
);
1426 screen_columns (void)
1431 /* With Solaris 2.[123], this ioctl fails and errno is set to
1432 EINVAL for telnet (but not rlogin) sessions.
1433 On ISC 3.0, it fails for the console and the serial port
1434 (but it works for ptys).
1435 It can also fail on any system when stdout isn't a tty.
1436 In case of any failure, just use the default. */
1437 if (get_win_size (STDOUT_FILENO
, &win
) == 0 && win
.ws_col
> 0)
1440 /* FIXME: use xstrtol */
1441 if (getenv ("COLUMNS"))
1442 return atoi (getenv ("COLUMNS"));
1447 mode_type_flag (enum mode_type type
, struct termios
*mode
)
1452 return &mode
->c_cflag
;
1455 return &mode
->c_iflag
;
1458 return &mode
->c_oflag
;
1461 return &mode
->c_lflag
;
1472 display_settings (enum output_type output_type
, struct termios
*mode
,
1473 int fd
, const char *device_name
)
1475 switch (output_type
)
1478 display_changed (mode
);
1482 display_all (mode
, fd
, device_name
);
1486 display_recoverable (mode
);
1492 display_changed (struct termios
*mode
)
1498 enum mode_type prev_type
= control
;
1500 display_speed (mode
, 1);
1502 wrapf ("line = %d;", mode
->c_line
);
1508 for (i
= 0; !STREQ (control_info
[i
].name
, "min"); ++i
)
1510 if (mode
->c_cc
[control_info
[i
].offset
] == control_info
[i
].saneval
)
1512 /* If swtch is the same as susp, don't print both. */
1514 if (STREQ (control_info
[i
].name
, "swtch"))
1517 /* If eof uses the same slot as min, only print whichever applies. */
1519 if ((mode
->c_lflag
& ICANON
) == 0
1520 && (STREQ (control_info
[i
].name
, "eof")
1521 || STREQ (control_info
[i
].name
, "eol")))
1526 wrapf ("%s = %s;", control_info
[i
].name
,
1527 visible (mode
->c_cc
[control_info
[i
].offset
]));
1529 if ((mode
->c_lflag
& ICANON
) == 0)
1531 wrapf ("min = %d; time = %d;\n", (int) mode
->c_cc
[VMIN
],
1532 (int) mode
->c_cc
[VTIME
]);
1534 else if (empty_line
== 0)
1539 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1541 if (mode_info
[i
].flags
& OMIT
)
1543 if (mode_info
[i
].type
!= prev_type
)
1545 if (empty_line
== 0)
1551 prev_type
= mode_info
[i
].type
;
1554 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1555 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1556 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1558 if (mode_info
[i
].flags
& SANE_UNSET
)
1560 wrapf ("%s", mode_info
[i
].name
);
1564 else if ((mode_info
[i
].flags
& (SANE_SET
| REV
)) == (SANE_SET
| REV
))
1566 wrapf ("-%s", mode_info
[i
].name
);
1570 if (empty_line
== 0)
1576 display_all (struct termios
*mode
, int fd
, const char *device_name
)
1581 enum mode_type prev_type
= control
;
1583 display_speed (mode
, 1);
1585 display_window_size (1, fd
, device_name
);
1588 wrapf ("line = %d;", mode
->c_line
);
1593 for (i
= 0; ! STREQ (control_info
[i
].name
, "min"); ++i
)
1595 /* If swtch is the same as susp, don't print both. */
1597 if (STREQ (control_info
[i
].name
, "swtch"))
1600 /* If eof uses the same slot as min, only print whichever applies. */
1602 if ((mode
->c_lflag
& ICANON
) == 0
1603 && (STREQ (control_info
[i
].name
, "eof")
1604 || STREQ (control_info
[i
].name
, "eol")))
1607 wrapf ("%s = %s;", control_info
[i
].name
,
1608 visible (mode
->c_cc
[control_info
[i
].offset
]));
1611 if ((mode
->c_lflag
& ICANON
) == 0)
1613 wrapf ("min = %d; time = %d;", mode
->c_cc
[VMIN
], mode
->c_cc
[VTIME
]);
1614 if (current_col
!= 0)
1618 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1620 if (mode_info
[i
].flags
& OMIT
)
1622 if (mode_info
[i
].type
!= prev_type
)
1626 prev_type
= mode_info
[i
].type
;
1629 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1630 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1631 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1632 wrapf ("%s", mode_info
[i
].name
);
1633 else if (mode_info
[i
].flags
& REV
)
1634 wrapf ("-%s", mode_info
[i
].name
);
1641 display_speed (struct termios
*mode
, int fancy
)
1643 if (cfgetispeed (mode
) == 0 || cfgetispeed (mode
) == cfgetospeed (mode
))
1644 wrapf (fancy
? "speed %lu baud;" : "%lu\n",
1645 baud_to_value (cfgetospeed (mode
)));
1647 wrapf (fancy
? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n",
1648 baud_to_value (cfgetispeed (mode
)),
1649 baud_to_value (cfgetospeed (mode
)));
1655 display_recoverable (struct termios
*mode
)
1659 printf ("%lx:%lx:%lx:%lx",
1660 (unsigned long) mode
->c_iflag
, (unsigned long) mode
->c_oflag
,
1661 (unsigned long) mode
->c_cflag
, (unsigned long) mode
->c_lflag
);
1662 for (i
= 0; i
< NCCS
; ++i
)
1663 printf (":%x", (unsigned int) mode
->c_cc
[i
]);
1668 recover_mode (char *arg
, struct termios
*mode
)
1672 unsigned long iflag
, oflag
, cflag
, lflag
;
1674 /* Scan into temporaries since it is too much trouble to figure out
1675 the right format for `tcflag_t'. */
1676 if (sscanf (arg
, "%lx:%lx:%lx:%lx%n",
1677 &iflag
, &oflag
, &cflag
, &lflag
, &n
) != 4)
1679 mode
->c_iflag
= iflag
;
1680 mode
->c_oflag
= oflag
;
1681 mode
->c_cflag
= cflag
;
1682 mode
->c_lflag
= lflag
;
1684 for (i
= 0; i
< NCCS
; ++i
)
1686 if (sscanf (arg
, ":%x%n", &chr
, &n
) != 1)
1688 mode
->c_cc
[i
] = chr
;
1692 /* Fail if there are too many fields. */
1701 const char *string
; /* ASCII representation. */
1702 speed_t speed
; /* Internal form. */
1703 unsigned long value
; /* Numeric value. */
1706 struct speed_map speeds
[] =
1713 {"134.5", B134
, 134},
1718 {"1200", B1200
, 1200},
1719 {"1800", B1800
, 1800},
1720 {"2400", B2400
, 2400},
1721 {"4800", B4800
, 4800},
1722 {"9600", B9600
, 9600},
1723 {"19200", B19200
, 19200},
1724 {"38400", B38400
, 38400},
1725 {"exta", B19200
, 19200},
1726 {"extb", B38400
, 38400},
1728 {"57600", B57600
, 57600},
1731 {"115200", B115200
, 115200},
1734 {"230400", B230400
, 230400},
1737 {"460800", B460800
, 460800},
1743 string_to_baud (const char *arg
)
1747 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1748 if (STREQ (arg
, speeds
[i
].string
))
1749 return speeds
[i
].speed
;
1750 return (speed_t
) -1;
1753 static unsigned long
1754 baud_to_value (speed_t speed
)
1758 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1759 if (speed
== speeds
[i
].speed
)
1760 return speeds
[i
].value
;
1765 sane_mode (struct termios
*mode
)
1770 for (i
= 0; control_info
[i
].name
; ++i
)
1773 if (STREQ (control_info
[i
].name
, "min"))
1776 mode
->c_cc
[control_info
[i
].offset
] = control_info
[i
].saneval
;
1779 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1781 if (mode_info
[i
].flags
& SANE_SET
)
1783 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1784 *bitsp
= (*bitsp
& ~mode_info
[i
].mask
) | mode_info
[i
].bits
;
1786 else if (mode_info
[i
].flags
& SANE_UNSET
)
1788 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1789 *bitsp
= *bitsp
& ~mode_info
[i
].mask
& ~mode_info
[i
].bits
;
1794 /* Return a string that is the printable representation of character CH. */
1795 /* Adapted from `cat' by Torbjorn Granlund. */
1798 visible (unsigned int ch
)
1800 static char buf
[10];
1803 if (ch
== _POSIX_VDISABLE
)
1804 return _("<undef>");
1822 *bpout
++ = ch
- 128;
1832 *bpout
++ = ch
- 128 + 64;
1842 return (const char *) buf
;
1845 /* Parse string S as an integer, using decimal radix by default,
1846 but allowing octal and hex numbers as in C. */
1847 /* From `od' by Richard Stallman. */
1850 integer_arg (const char *s
)
1853 if (xstrtol (s
, NULL
, 0, &value
, "bB") != LONGINT_OK
)
1855 error (0, 0, _("invalid integer argument `%s'"), s
);