1 /* stty -- change and print terminal line settings
2 Copyright (C) 90,91,92,93,94,95,96,97,1998 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 #ifndef _POSIX_VDISABLE
69 # define _POSIX_VDISABLE ((unsigned char) 0)
72 #define Control(c) ((c) & 0x1f)
73 /* Canonical values for control characters. */
75 # define CINTR Control ('c')
84 # define CKILL Control ('u')
87 # define CEOF Control ('d')
90 # define CEOL _POSIX_VDISABLE
93 # define CSTART Control ('q')
96 # define CSTOP Control ('s')
99 # define CSUSP Control ('z')
101 #if defined(VEOL2) && !defined(CEOL2)
102 # define CEOL2 _POSIX_VDISABLE
104 /* ISC renamed swtch to susp for termios, but we'll accept either name. */
105 #if defined(VSUSP) && !defined(VSWTCH)
106 # define VSWTCH VSUSP
107 # define CSWTCH CSUSP
109 #if defined(VSWTCH) && !defined(CSWTCH)
110 # define CSWTCH _POSIX_VDISABLE
113 /* SunOS 5.3 loses (^Z doesn't work) if `swtch' is the same as `susp'.
114 So the default is to disable `swtch.' */
115 #if defined (__sparc__) && defined (__svr4__)
117 # define CSWTCH _POSIX_VDISABLE
120 #if defined(VWERSE) && !defined (VWERASE) /* AIX-3.2.5 */
121 # define VWERASE VWERSE
123 #if defined(VDSUSP) && !defined (CDSUSP)
124 # define CDSUSP Control ('y')
126 #if !defined(VREPRINT) && defined(VRPRNT) /* Irix 4.0.5 */
127 # define VREPRINT VRPRNT
129 #if defined(VREPRINT) && !defined(CRPRNT)
130 # define CRPRNT Control ('r')
132 #if defined(VWERASE) && !defined(CWERASE)
133 # define CWERASE Control ('w')
135 #if defined(VLNEXT) && !defined(CLNEXT)
136 # define CLNEXT Control ('v')
138 #if defined(VDISCARD) && !defined(VFLUSHO)
139 # define VFLUSHO VDISCARD
141 #if defined(VFLUSH) && !defined(VFLUSHO) /* Ultrix 4.2 */
142 # define VFLUSHO VFLUSH
144 #if defined(CTLECH) && !defined(ECHOCTL) /* Ultrix 4.3 */
145 # define ECHOCTL CTLECH
147 #if defined(TCTLECH) && !defined(ECHOCTL) /* Ultrix 4.2 */
148 # define ECHOCTL TCTLECH
150 #if defined(CRTKIL) && !defined(ECHOKE) /* Ultrix 4.2 and 4.3 */
151 # define ECHOKE CRTKIL
153 #if defined(VFLUSHO) && !defined(CFLUSHO)
154 # define CFLUSHO Control ('o')
156 #if defined(VSTATUS) && !defined(CSTATUS)
157 # define CSTATUS Control ('t')
160 /* Which speeds to set. */
163 input_speed
, output_speed
, both_speeds
166 /* What to output and how. */
169 changed
, all
, recoverable
/* Default, -a, -g. */
172 /* Which member(s) of `struct termios' a mode uses. */
175 control
, input
, output
, local
, combination
178 /* Flags for `struct mode_info'. */
179 #define SANE_SET 1 /* Set in `sane' mode. */
180 #define SANE_UNSET 2 /* Unset in `sane' mode. */
181 #define REV 4 /* Can be turned off by prepending `-'. */
182 #define OMIT 8 /* Don't display value. */
187 const char *name
; /* Name given on command line. */
188 enum mode_type type
; /* Which structure element to change. */
189 char flags
; /* Setting and display options. */
190 unsigned long bits
; /* Bits to set for this mode. */
191 unsigned long mask
; /* Other bits to turn off for this mode. */
194 static struct mode_info mode_info
[] =
196 {"parenb", control
, REV
, PARENB
, 0},
197 {"parodd", control
, REV
, PARODD
, 0},
198 {"cs5", control
, 0, CS5
, CSIZE
},
199 {"cs6", control
, 0, CS6
, CSIZE
},
200 {"cs7", control
, 0, CS7
, CSIZE
},
201 {"cs8", control
, 0, CS8
, CSIZE
},
202 {"hupcl", control
, REV
, HUPCL
, 0},
203 {"hup", control
, REV
| OMIT
, HUPCL
, 0},
204 {"cstopb", control
, REV
, CSTOPB
, 0},
205 {"cread", control
, SANE_SET
| REV
, CREAD
, 0},
206 {"clocal", control
, REV
, CLOCAL
, 0},
208 {"crtscts", control
, REV
, CRTSCTS
, 0},
211 {"ignbrk", input
, SANE_UNSET
| REV
, IGNBRK
, 0},
212 {"brkint", input
, SANE_SET
| REV
, BRKINT
, 0},
213 {"ignpar", input
, REV
, IGNPAR
, 0},
214 {"parmrk", input
, REV
, PARMRK
, 0},
215 {"inpck", input
, REV
, INPCK
, 0},
216 {"istrip", input
, REV
, ISTRIP
, 0},
217 {"inlcr", input
, SANE_UNSET
| REV
, INLCR
, 0},
218 {"igncr", input
, SANE_UNSET
| REV
, IGNCR
, 0},
219 {"icrnl", input
, SANE_SET
| REV
, ICRNL
, 0},
220 {"ixon", input
, REV
, IXON
, 0},
221 {"ixoff", input
, SANE_UNSET
| REV
, IXOFF
, 0},
222 {"tandem", input
, REV
| OMIT
, IXOFF
, 0},
224 {"iuclc", input
, SANE_UNSET
| REV
, IUCLC
, 0},
227 {"ixany", input
, SANE_UNSET
| REV
, IXANY
, 0},
230 {"imaxbel", input
, SANE_SET
| REV
, IMAXBEL
, 0},
233 {"opost", output
, SANE_SET
| REV
, OPOST
, 0},
235 {"olcuc", output
, SANE_UNSET
| REV
, OLCUC
, 0},
238 {"ocrnl", output
, SANE_UNSET
| REV
, OCRNL
, 0},
241 {"onlcr", output
, SANE_SET
| REV
, ONLCR
, 0},
244 {"onocr", output
, SANE_UNSET
| REV
, ONOCR
, 0},
247 {"onlret", output
, SANE_UNSET
| REV
, ONLRET
, 0},
250 {"ofill", output
, SANE_UNSET
| REV
, OFILL
, 0},
253 {"ofdel", output
, SANE_UNSET
| REV
, OFDEL
, 0},
256 {"nl1", output
, SANE_UNSET
, NL1
, NLDLY
},
257 {"nl0", output
, SANE_SET
, NL0
, NLDLY
},
260 {"cr3", output
, SANE_UNSET
, CR3
, CRDLY
},
261 {"cr2", output
, SANE_UNSET
, CR2
, CRDLY
},
262 {"cr1", output
, SANE_UNSET
, CR1
, CRDLY
},
263 {"cr0", output
, SANE_SET
, CR0
, CRDLY
},
266 {"tab3", output
, SANE_UNSET
, TAB3
, TABDLY
},
267 {"tab2", output
, SANE_UNSET
, TAB2
, TABDLY
},
268 {"tab1", output
, SANE_UNSET
, TAB1
, TABDLY
},
269 {"tab0", output
, SANE_SET
, TAB0
, TABDLY
},
272 {"tab3", output
, SANE_UNSET
, OXTABS
, 0},
276 {"bs1", output
, SANE_UNSET
, BS1
, BSDLY
},
277 {"bs0", output
, SANE_SET
, BS0
, BSDLY
},
280 {"vt1", output
, SANE_UNSET
, VT1
, VTDLY
},
281 {"vt0", output
, SANE_SET
, VT0
, VTDLY
},
284 {"ff1", output
, SANE_UNSET
, FF1
, FFDLY
},
285 {"ff0", output
, SANE_SET
, FF0
, FFDLY
},
288 {"isig", local
, SANE_SET
| REV
, ISIG
, 0},
289 {"icanon", local
, SANE_SET
| REV
, ICANON
, 0},
291 {"iexten", local
, SANE_SET
| REV
, IEXTEN
, 0},
293 {"echo", local
, SANE_SET
| REV
, ECHO
, 0},
294 {"echoe", local
, SANE_SET
| REV
, ECHOE
, 0},
295 {"crterase", local
, REV
| OMIT
, ECHOE
, 0},
296 {"echok", local
, SANE_SET
| REV
, ECHOK
, 0},
297 {"echonl", local
, SANE_UNSET
| REV
, ECHONL
, 0},
298 {"noflsh", local
, SANE_UNSET
| REV
, NOFLSH
, 0},
300 {"xcase", local
, SANE_UNSET
| REV
, XCASE
, 0},
303 {"tostop", local
, SANE_UNSET
| REV
, TOSTOP
, 0},
306 {"echoprt", local
, SANE_UNSET
| REV
, ECHOPRT
, 0},
307 {"prterase", local
, REV
| OMIT
, ECHOPRT
, 0},
310 {"echoctl", local
, SANE_SET
| REV
, ECHOCTL
, 0},
311 {"ctlecho", local
, REV
| OMIT
, ECHOCTL
, 0},
314 {"echoke", local
, SANE_SET
| REV
, ECHOKE
, 0},
315 {"crtkill", local
, REV
| OMIT
, ECHOKE
, 0},
318 {"evenp", combination
, REV
| OMIT
, 0, 0},
319 {"parity", combination
, REV
| OMIT
, 0, 0},
320 {"oddp", combination
, REV
| OMIT
, 0, 0},
321 {"nl", combination
, REV
| OMIT
, 0, 0},
322 {"ek", combination
, OMIT
, 0, 0},
323 {"sane", combination
, OMIT
, 0, 0},
324 {"cooked", combination
, REV
| OMIT
, 0, 0},
325 {"raw", combination
, REV
| OMIT
, 0, 0},
326 {"pass8", combination
, REV
| OMIT
, 0, 0},
327 {"litout", combination
, REV
| OMIT
, 0, 0},
328 {"cbreak", combination
, REV
| OMIT
, 0, 0},
330 {"decctlq", combination
, REV
| OMIT
, 0, 0},
332 #if defined (TABDLY) || defined (OXTABS)
333 {"tabs", combination
, REV
| OMIT
, 0, 0},
335 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
336 {"lcase", combination
, REV
| OMIT
, 0, 0},
337 {"LCASE", combination
, REV
| OMIT
, 0, 0},
339 {"crt", combination
, OMIT
, 0, 0},
340 {"dec", combination
, OMIT
, 0, 0},
342 {NULL
, control
, 0, 0, 0}
345 /* Control character settings. */
348 const char *name
; /* Name given on command line. */
349 unsigned char saneval
; /* Value to set for `stty sane'. */
350 int offset
; /* Offset in c_cc. */
353 /* Control characters. */
355 static struct control_info control_info
[] =
357 {"intr", CINTR
, VINTR
},
358 {"quit", CQUIT
, VQUIT
},
359 {"erase", CERASE
, VERASE
},
360 {"kill", CKILL
, VKILL
},
364 {"eol2", CEOL2
, VEOL2
},
367 {"swtch", CSWTCH
, VSWTCH
},
369 {"start", CSTART
, VSTART
},
370 {"stop", CSTOP
, VSTOP
},
371 {"susp", CSUSP
, VSUSP
},
373 {"dsusp", CDSUSP
, VDSUSP
},
376 {"rprnt", CRPRNT
, VREPRINT
},
379 {"werase", CWERASE
, VWERASE
},
382 {"lnext", CLNEXT
, VLNEXT
},
385 {"flush", CFLUSHO
, VFLUSHO
},
388 {"status", CSTATUS
, VSTATUS
},
391 /* These must be last because of the display routines. */
397 static const char *visible
PARAMS ((unsigned int ch
));
398 static unsigned long baud_to_value
PARAMS ((speed_t speed
));
399 static int recover_mode
PARAMS ((char *arg
, struct termios
*mode
));
400 static int screen_columns
PARAMS ((void));
401 static int set_mode
PARAMS ((struct mode_info
*info
, int reversed
,
402 struct termios
*mode
));
403 static long integer_arg
PARAMS ((const char *s
));
404 static speed_t string_to_baud
PARAMS ((const char *arg
));
405 static tcflag_t
*mode_type_flag
PARAMS ((enum mode_type type
,
406 struct termios
*mode
));
407 static void display_all
PARAMS ((struct termios
*mode
, int fd
,
408 const char *device_name
));
409 static void display_changed
PARAMS ((struct termios
*mode
));
410 static void display_recoverable
PARAMS ((struct termios
*mode
));
411 static void display_settings
PARAMS ((enum output_type output_type
,
412 struct termios
*mode
, int fd
,
413 const char *device_name
));
414 static void display_speed
PARAMS ((struct termios
*mode
, int fancy
));
415 static void display_window_size
PARAMS ((int fancy
, int fd
,
416 const char *device_name
));
417 static void sane_mode
PARAMS ((struct termios
*mode
));
418 static void set_control_char
PARAMS ((struct control_info
*info
,
420 struct termios
*mode
));
421 static void set_speed
PARAMS ((enum speed_setting type
, const char *arg
,
422 struct termios
*mode
));
423 static void set_window_size
PARAMS ((int rows
, int cols
, int fd
,
424 const char *device_name
));
426 /* The width of the screen, for output wrapping. */
429 /* Current position, to know when to wrap. */
430 static int current_col
;
432 static struct option longopts
[] =
434 {"all", no_argument
, NULL
, 'a'},
435 {"save", no_argument
, NULL
, 'g'},
436 {"file", required_argument
, NULL
, 'F'},
440 /* The name this program was run with. */
443 /* Print format string MESSAGE and optional args.
444 Wrap to next line first if it won't fit.
445 Print a space first unless MESSAGE will start a new line. */
450 wrapf (const char *message
,...)
452 wrapf (message
, va_alist
)
458 char buf
[1024]; /* Plenty long for our needs. */
461 VA_START (args
, message
);
462 vsprintf (buf
, message
, args
);
464 buflen
= strlen (buf
);
465 if (current_col
+ (current_col
> 0) + buflen
>= max_col
)
476 current_col
+= buflen
;
483 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
488 Usage: %s [-F device] [--file=device] [SETTING]...\n\
489 or: %s [-F device] [--file=device] [-a|--all]\n\
490 or: %s [-F device] [--file=device] [-g|--save]\n\
492 program_name
, program_name
, program_name
);
494 Print or change terminal characteristics.\n\
496 -a, --all print all current settings in human-readable form\n\
497 -g, --save print all current settings in a stty-readable form\n\
498 -F, --file open and use the specified device instead of stdin\n\
499 --help display this help and exit\n\
500 --version output version information and exit\n\
502 Optional - before SETTING indicates negation. An * marks non-POSIX\n\
503 settings. The underlying system defines which settings are available.\n\
507 Special characters:\n\
508 * dsusp CHAR CHAR will send a terminal stop signal once input flushed\n\
509 eof CHAR CHAR will send an end of file (terminate the input)\n\
510 eol CHAR CHAR will end the line\n\
511 * eol2 CHAR alternate CHAR for ending the line\n\
512 erase CHAR CHAR will erase the last character typed\n\
513 intr CHAR CHAR will send an interrupt signal\n\
514 kill CHAR CHAR will erase the current line\n\
515 * lnext CHAR CHAR will enter the next character quoted\n\
516 quit CHAR CHAR will send a quit signal\n\
517 * rprnt CHAR CHAR will redraw the current line\n\
518 start CHAR CHAR will restart the output after stopping it\n\
519 stop CHAR CHAR will stop the output\n\
520 susp CHAR CHAR will send a terminal stop signal\n\
521 * swtch CHAR CHAR will switch to a different shell layer\n\
522 * werase CHAR CHAR will erase the last word typed\n\
527 N set the input and output speeds to N bauds\n\
528 * cols N tell the kernel that the terminal has N columns\n\
529 * columns N same as cols N\n\
530 ispeed N set the input speed to N\n\
531 * line N use line discipline N\n\
532 min N with -icanon, set N characters minimum for a completed read\n\
533 ospeed N set the output speed to N\n\
534 * rows N tell the kernel that the terminal has N rows\n\
535 * size print the number of rows and columns according to the kernel\n\
536 speed print the terminal speed\n\
537 time N with -icanon, set read timeout of N tenths of a second\n\
542 [-]clocal disable modem control signals\n\
543 [-]cread allow input to be received\n\
544 * [-]crtscts enable RTS/CTS handshaking\n\
545 csN set character size to N bits, N in [5..8]\n\
546 [-]cstopb use two stop bits per character (one with `-')\n\
547 [-]hup send a hangup signal when the last process closes the tty\n\
548 [-]hupcl same as [-]hup\n\
549 [-]parenb generate parity bit in output and expect parity bit in input\n\
550 [-]parodd set odd parity (even with `-')\n\
555 [-]brkint breaks cause an interrupt signal\n\
556 [-]icrnl translate carriage return to newline\n\
557 [-]ignbrk ignore break characters\n\
558 [-]igncr ignore carriage return\n\
559 [-]ignpar ignore characters with parity errors\n\
560 * [-]imaxbel beep and do not flush a full input buffer on a character\n\
561 [-]inlcr translate newline to carriage return\n\
562 [-]inpck enable input parity checking\n\
563 [-]istrip clear high (8th) bit of input characters\n\
564 * [-]iuclc translate uppercase characters to lowercase\n\
565 * [-]ixany let any character restart output, not only start character\n\
566 [-]ixoff enable sending of start/stop characters\n\
567 [-]ixon enable XON/XOFF flow control\n\
568 [-]parmrk mark parity errors (with a 255-0-character sequence)\n\
569 [-]tandem same as [-]ixoff\n\
574 * bsN backspace delay style, N in [0..1]\n\
575 * crN carriage return delay style, N in [0..3]\n\
576 * ffN form feed delay style, N in [0..1]\n\
577 * nlN newline delay style, N in [0..1]\n\
578 * [-]ocrnl translate carriage return to newline\n\
579 * [-]ofdel use delete characters for fill instead of null characters\n\
580 * [-]ofill use fill (padding) characters instead of timing for delays\n\
581 * [-]olcuc translate lowercase characters to uppercase\n\
582 * [-]onlcr translate newline to carriage return-newline\n\
583 * [-]onlret newline performs a carriage return\n\
584 * [-]onocr do not print carriage returns in the first column\n\
585 [-]opost postprocess output\n\
586 * tabN horizontal tab delay style, N in [0..3]\n\
587 * tabs same as tab0\n\
588 * -tabs same as tab3\n\
589 * vtN vertical tab delay style, N in [0..1]\n\
594 [-]crterase echo erase characters as backspace-space-backspace\n\
595 * crtkill kill all line by obeying the echoprt and echoe settings\n\
596 * -crtkill kill all line by obeying the echoctl and echok settings\n\
597 * [-]ctlecho echo control characters in hat notation (`^c')\n\
598 [-]echo echo input characters\n\
599 * [-]echoctl same as [-]ctlecho\n\
600 [-]echoe same as [-]crterase\n\
601 [-]echok echo a newline after a kill character\n\
602 * [-]echoke same as [-]crtkill\n\
603 [-]echonl echo newline even if not echoing other characters\n\
604 * [-]echoprt echo erased characters backward, between `\\' and '/'\n\
605 [-]icanon enable erase, kill, werase, and rprnt special characters\n\
606 [-]iexten enable non-POSIX special characters\n\
607 [-]isig enable interrupt, quit, and suspend special characters\n\
608 [-]noflsh disable flushing after interrupt and quit special characters\n\
609 * [-]prterase same as [-]echoprt\n\
610 * [-]tostop stop background jobs that try to write to the terminal\n\
611 * [-]xcase with icanon, escape with `\\' for uppercase characters\n\
615 Combination settings:\n\
616 * [-]LCASE same as [-]lcase\n\
617 cbreak same as -icanon\n\
618 -cbreak same as icanon\n\
619 cooked same as brkint ignpar istrip icrnl ixon opost isig\n\
620 icanon, eof and eol characters to their default values\n\
621 -cooked same as raw\n\
622 crt same as echoe echoctl echoke\n\
623 dec same as echoe echoctl echoke -ixany intr ^c erase 0177\n\
625 * [-]decctlq same as [-]ixany\n\
626 ek erase and kill characters to their default values\n\
627 evenp same as parenb -parodd cs7\n\
628 -evenp same as -parenb cs8\n\
629 * [-]lcase same as xcase iuclc olcuc\n\
630 litout same as -parenb -istrip -opost cs8\n\
631 -litout same as parenb istrip opost cs7\n\
632 nl same as -icrnl -onlcr\n\
633 -nl same as icrnl -inlcr -igncr onlcr -ocrnl -onlret\n\
634 oddp same as parenb parodd cs7\n\
635 -oddp same as -parenb cs8\n\
636 [-]parity same as [-]evenp\n\
637 pass8 same as -parenb -istrip cs8\n\
638 -pass8 same as parenb istrip cs7\n\
639 raw same as -ignbrk -brkint -ignpar -parmrk -inpck -istrip\n\
640 -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany\n\
641 -imaxbel -opost -isig -icanon -xcase min 1 time 0\n\
642 -raw same as cooked\n\
643 sane same as cread -ignbrk brkint -inlcr -igncr icrnl\n\
644 -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr\n\
645 -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0\n\
646 isig icanon iexten echo echoe echok -echonl -noflsh\n\
647 -xcase -tostop -echoprt echoctl echoke, all special\n\
648 characters to their default values.\n\
652 Handle the tty line connected to standard input. Without arguments,\n\
653 prints baud rate, line discipline, and deviations from stty sane. In\n\
654 settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
655 127; special values ^- or undef used to disable special characters.\n\
657 puts (_("\nReport bugs to <bug-sh-utils@gnu.org>."));
662 /* Return 1 if the string contains only valid options. */
664 valid_options (char *opt
, const char *valid_opts
,
665 const char *valid_arg_opts
)
675 if (strchr (valid_opts
, ch
))
677 if (strchr (valid_arg_opts
, ch
))
685 main (int argc
, char **argv
)
688 enum output_type output_type
;
690 int require_set_attr
;
693 int recoverable_output
;
696 char *file_name
= NULL
;
698 const char *device_name
;
699 const char *posixly_correct
= getenv ("POSIXLY_CORRECT");
700 int invalid_long_option
= 0;
702 program_name
= argv
[0];
703 setlocale (LC_ALL
, "");
704 bindtextdomain (PACKAGE
, LOCALEDIR
);
705 textdomain (PACKAGE
);
707 parse_long_options (argc
, argv
, "stty", GNU_PACKAGE
, VERSION
, usage
);
709 output_type
= changed
;
711 recoverable_output
= 0;
713 /* Don't print error messages for unrecognized options. */
716 while ((optc
= getopt_long (argc
, argv
, "agF:", longopts
, NULL
)) != -1)
718 int unrecognized_option
= 0;
727 recoverable_output
= 1;
728 output_type
= recoverable
;
733 error (2, 0, _("only one device may be specified"));
738 unrecognized_option
= 1;
742 if (unrecognized_option
)
746 /* FIXME: what is this?!? */
747 if (invalid_long_option
)
750 /* Clear out the options that have been parsed. This is really
751 gross, but it's needed because stty SETTINGS look like options to
752 getopt(), so we need to work around things in a really horrible
753 way. If any new options are ever added to stty, the short option
754 MUST NOT be a letter which is the first letter of one of the
755 possible stty settings. If you change anything about how stty
756 parses options, be sure it still works with combinations of
757 short and long options, --, POSIXLY_CORRECT, etc. */
758 for (k
= 1; k
< argc
; k
++)
766 /* Handle --, and reset noargs if there are arguments following it. */
767 if (STREQ (argv
[k
], "--"))
775 /* Handle "--file device" */
776 len
= strlen (argv
[k
]);
777 if (len
>= 3 && strstr ("--file", argv
[k
]))
784 /* Handle "--all" and "--save". */
786 && (strstr ("--all", argv
[k
])
787 || strstr ("--save", argv
[k
])))
793 /* Handle "--file=device". */
794 eq
= strchr (argv
[k
], '=');
795 if (eq
&& eq
- argv
[k
] >= 3)
798 if (strstr ("--file", argv
[k
]))
803 /* Put the equals sign back for the error message. */
807 /* Handle "-a", "-ag", "-aF/dev/foo", "-aF /dev/foo", etc. */
808 if (valid_options (argv
[k
], "ag", "F"))
810 /* FIXME: this loses when the device name ends in `F'.
811 e.g. `stty -F/dev/BARF nl' would clobber the `nl' argument. */
812 if (argv
[k
][strlen (argv
[k
]) - 1] == 'F')
816 /* Everything else must be a normal, non-option argument. */
825 /* Specifying both -a and -g gets an error. */
826 if (verbose_output
&& recoverable_output
)
828 _("the options for verbose and stty-readable output styles are\n\
829 mutually exclusive"));
831 /* Specifying any other arguments with -a or -g gets an error. */
832 if (!noargs
&& (verbose_output
|| recoverable_output
))
833 error (2, 0, _("when specifying an output style, modes may not be set"));
835 /* FIXME: it'd be better not to open the file until we've verified
836 that all arguments are valid. Otherwise, we could end up doing
837 only some of the requested operations and then failing, probably
838 leaving things in an undesirable state. */
843 device_name
= file_name
;
844 fd
= open (device_name
, O_RDONLY
| O_NONBLOCK
);
846 error (1, errno
, "%s", device_name
);
847 if ((fdflags
= fcntl (fd
, F_GETFL
)) == -1
848 || fcntl (fd
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
849 error (1, errno
, _("%s: couldn't reset non-blocking mode"),
855 device_name
= _("standard input");
858 /* Initialize to all zeroes so there is no risk memcmp will report a
859 spurious difference in an uninitialized portion of the structure. */
860 memset (&mode
, 0, sizeof (mode
));
861 if (tcgetattr (fd
, &mode
))
862 error (1, errno
, "%s", device_name
);
864 if (verbose_output
|| recoverable_output
|| noargs
)
866 max_col
= screen_columns ();
868 display_settings (output_type
, &mode
, fd
, device_name
);
873 require_set_attr
= 0;
887 if (argv
[k
][0] == '-')
892 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
894 if (STREQ (argv
[k
], mode_info
[i
].name
))
896 match_found
= set_mode (&mode_info
[i
], reversed
, &mode
);
897 require_set_attr
= 1;
901 if (match_found
== 0 && reversed
)
903 error (0, 0, _("invalid argument `%s'"), --argv
[k
]);
906 if (match_found
== 0)
908 for (i
= 0; control_info
[i
].name
!= NULL
; ++i
)
910 if (STREQ (argv
[k
], control_info
[i
].name
))
914 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
919 set_control_char (&control_info
[i
], argv
[k
], &mode
);
920 require_set_attr
= 1;
925 if (match_found
== 0)
927 if (STREQ (argv
[k
], "ispeed"))
931 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
935 set_speed (input_speed
, argv
[k
], &mode
);
937 require_set_attr
= 1;
939 else if (STREQ (argv
[k
], "ospeed"))
943 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
947 set_speed (output_speed
, argv
[k
], &mode
);
949 require_set_attr
= 1;
952 else if (STREQ (argv
[k
], "rows"))
956 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
960 set_window_size ((int) integer_arg (argv
[k
]), -1,
963 else if (STREQ (argv
[k
], "cols")
964 || STREQ (argv
[k
], "columns"))
968 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
972 set_window_size (-1, (int) integer_arg (argv
[k
]),
975 else if (STREQ (argv
[k
], "size"))
977 max_col
= screen_columns ();
979 display_window_size (0, fd
, device_name
);
983 else if (STREQ (argv
[k
], "line"))
987 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
991 mode
.c_line
= integer_arg (argv
[k
]);
992 require_set_attr
= 1;
995 else if (STREQ (argv
[k
], "speed"))
997 max_col
= screen_columns ();
998 display_speed (&mode
, 0);
1000 else if (string_to_baud (argv
[k
]) != (speed_t
) -1)
1002 set_speed (both_speeds
, argv
[k
], &mode
);
1004 require_set_attr
= 1;
1008 if (recover_mode (argv
[k
], &mode
) == 0)
1010 error (0, 0, _("invalid argument `%s'"), argv
[k
]);
1013 require_set_attr
= 1;
1019 if (require_set_attr
)
1021 struct termios new_mode
;
1023 if (tcsetattr (fd
, TCSADRAIN
, &mode
))
1024 error (1, errno
, "%s", device_name
);
1026 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
1027 it performs *any* of the requested operations. This means it
1028 can report `success' when it has actually failed to perform
1029 some proper subset of the requested operations. To detect
1030 this partial failure, get the current terminal attributes and
1031 compare them to the requested ones. */
1033 /* Initialize to all zeroes so there is no risk memcmp will report a
1034 spurious difference in an uninitialized portion of the structure. */
1035 memset (&new_mode
, 0, sizeof (new_mode
));
1036 if (tcgetattr (fd
, &new_mode
))
1037 error (1, errno
, "%s", device_name
);
1039 /* Normally, one shouldn't use memcmp to compare structures that
1040 may have `holes' containing uninitialized data, but we have been
1041 careful to initialize the storage of these two variables to all
1042 zeroes. One might think it more efficient simply to compare the
1043 modified fields, but that would require enumerating those fields --
1044 and not all systems have the same fields in this structure. */
1046 if (memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1049 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1050 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1051 sometimes (m1 != m2). The only difference is in the four bits
1052 of the c_cflag field corresponding to the baud rate. To save
1053 Sun users a little confusion, don't report an error if this
1054 happens. But suppress the error only if we haven't tried to
1055 set the baud rate explicitly -- otherwise we'd never give an
1056 error for a true failure to set the baud rate. */
1058 new_mode
.c_cflag
&= (~CIBAUD
);
1059 if (speed_was_set
|| memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1064 _("%s: unable to perform all requested operations"),
1066 printf (_("new_mode: mode\n"));
1067 for (i
= 0; i
< sizeof (new_mode
); i
++)
1068 printf ("0x%02x: 0x%02x\n",
1069 *(((unsigned char *) &new_mode
) + i
),
1070 *(((unsigned char *) &mode
) + i
));
1078 /* Return 0 if not applied because not reversible; otherwise return 1. */
1081 set_mode (struct mode_info
*info
, int reversed
, struct termios
*mode
)
1085 if (reversed
&& (info
->flags
& REV
) == 0)
1088 bitsp
= mode_type_flag (info
->type
, mode
);
1092 /* Combination mode. */
1093 if (STREQ (info
->name
, "evenp") || STREQ (info
->name
, "parity"))
1096 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1098 mode
->c_cflag
= (mode
->c_cflag
& ~PARODD
& ~CSIZE
) | PARENB
| CS7
;
1100 else if (STREQ (info
->name
, "oddp"))
1103 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1105 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARODD
| PARENB
;
1107 else if (STREQ (info
->name
, "nl"))
1111 mode
->c_iflag
= (mode
->c_iflag
| ICRNL
) & ~INLCR
& ~IGNCR
;
1112 mode
->c_oflag
= (mode
->c_oflag
1127 mode
->c_iflag
= mode
->c_iflag
& ~ICRNL
;
1129 mode
->c_oflag
= mode
->c_oflag
& ~ONLCR
;
1133 else if (STREQ (info
->name
, "ek"))
1135 mode
->c_cc
[VERASE
] = CERASE
;
1136 mode
->c_cc
[VKILL
] = CKILL
;
1138 else if (STREQ (info
->name
, "sane"))
1140 else if (STREQ (info
->name
, "cbreak"))
1143 mode
->c_lflag
|= ICANON
;
1145 mode
->c_lflag
&= ~ICANON
;
1147 else if (STREQ (info
->name
, "pass8"))
1151 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1152 mode
->c_iflag
|= ISTRIP
;
1156 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1157 mode
->c_iflag
&= ~ISTRIP
;
1160 else if (STREQ (info
->name
, "litout"))
1164 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1165 mode
->c_iflag
|= ISTRIP
;
1166 mode
->c_oflag
|= OPOST
;
1170 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1171 mode
->c_iflag
&= ~ISTRIP
;
1172 mode
->c_oflag
&= ~OPOST
;
1175 else if (STREQ (info
->name
, "raw") || STREQ (info
->name
, "cooked"))
1177 if ((info
->name
[0] == 'r' && reversed
)
1178 || (info
->name
[0] == 'c' && !reversed
))
1181 mode
->c_iflag
|= BRKINT
| IGNPAR
| ISTRIP
| ICRNL
| IXON
;
1182 mode
->c_oflag
|= OPOST
;
1183 mode
->c_lflag
|= ISIG
| ICANON
;
1185 mode
->c_cc
[VEOF
] = CEOF
;
1188 mode
->c_cc
[VEOL
] = CEOL
;
1195 mode
->c_oflag
&= ~OPOST
;
1196 mode
->c_lflag
&= ~(ISIG
| ICANON
1201 mode
->c_cc
[VMIN
] = 1;
1202 mode
->c_cc
[VTIME
] = 0;
1206 else if (STREQ (info
->name
, "decctlq"))
1209 mode
->c_iflag
|= IXANY
;
1211 mode
->c_iflag
&= ~IXANY
;
1215 else if (STREQ (info
->name
, "tabs"))
1218 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB3
;
1220 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB0
;
1224 else if (STREQ (info
->name
, "tabs"))
1227 mode
->c_oflag
= mode
->c_oflag
| OXTABS
;
1229 mode
->c_oflag
= mode
->c_oflag
& ~OXTABS
;
1233 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
1234 else if (STREQ (info
->name
, "lcase")
1235 || STREQ (info
->name
, "LCASE"))
1239 mode
->c_lflag
&= ~XCASE
;
1240 mode
->c_iflag
&= ~IUCLC
;
1241 mode
->c_oflag
&= ~OLCUC
;
1245 mode
->c_lflag
|= XCASE
;
1246 mode
->c_iflag
|= IUCLC
;
1247 mode
->c_oflag
|= OLCUC
;
1251 else if (STREQ (info
->name
, "crt"))
1252 mode
->c_lflag
|= ECHOE
1260 else if (STREQ (info
->name
, "dec"))
1262 mode
->c_cc
[VINTR
] = 3; /* ^C */
1263 mode
->c_cc
[VERASE
] = 127; /* DEL */
1264 mode
->c_cc
[VKILL
] = 21; /* ^U */
1265 mode
->c_lflag
|= ECHOE
1274 mode
->c_iflag
&= ~IXANY
;
1279 *bitsp
= *bitsp
& ~info
->mask
& ~info
->bits
;
1281 *bitsp
= (*bitsp
& ~info
->mask
) | info
->bits
;
1287 set_control_char (struct control_info
*info
, const char *arg
,
1288 struct termios
*mode
)
1290 unsigned char value
;
1292 if (STREQ (info
->name
, "min") || STREQ (info
->name
, "time"))
1293 value
= integer_arg (arg
);
1294 else if (arg
[0] == '\0' || arg
[1] == '\0')
1296 else if (STREQ (arg
, "^-") || STREQ (arg
, "undef"))
1297 value
= _POSIX_VDISABLE
;
1298 else if (arg
[0] == '^' && arg
[1] != '\0') /* Ignore any trailing junk. */
1303 value
= arg
[1] & ~0140; /* Non-letters get weird results. */
1306 value
= integer_arg (arg
);
1307 mode
->c_cc
[info
->offset
] = value
;
1311 set_speed (enum speed_setting type
, const char *arg
, struct termios
*mode
)
1315 baud
= string_to_baud (arg
);
1316 if (type
== input_speed
|| type
== both_speeds
)
1317 cfsetispeed (mode
, baud
);
1318 if (type
== output_speed
|| type
== both_speeds
)
1319 cfsetospeed (mode
, baud
);
1325 get_win_size (int fd
, struct winsize
*win
)
1327 int err
= ioctl (fd
, TIOCGWINSZ
, (char *) win
);
1332 set_window_size (int rows
, int cols
, int fd
, const char *device_name
)
1336 if (get_win_size (fd
, &win
))
1338 if (errno
!= EINVAL
)
1339 error (1, errno
, "%s", device_name
);
1340 memset (&win
, 0, sizeof (win
));
1349 /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote:
1350 The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.
1351 This comment from sys/ttold.h describes Sun's twisted logic - a better
1352 test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).
1353 At any rate, the problem is gone in Solaris 2.x.
1355 Unfortunately, the old TIOCSSIZE code does collide with TIOCSWINSZ,
1356 but they can be disambiguated by checking whether a "struct ttysize"
1357 structure's "ts_lines" field is greater than 64K or not. If so,
1358 it's almost certainly a "struct winsize" instead.
1360 At any rate, the bug manifests itself when ws_row == 0; the symptom is
1361 that ws_row is set to ws_col, and ws_col is set to (ws_xpixel<<16) +
1362 ws_ypixel. Since GNU stty sets rows and columns separately, this bug
1363 caused "stty rows 0 cols 0" to set rows to cols and cols to 0, while
1364 "stty cols 0 rows 0" would do the right thing. On a little-endian
1365 machine like the sun386i, the problem is the same, but for ws_col == 0.
1367 The workaround is to do the ioctl once with row and col = 1 to set the
1368 pixel info, and then do it again using a TIOCSSIZE to set rows/cols. */
1370 if (win
.ws_row
== 0 || win
.ws_col
== 0)
1372 struct ttysize ttysz
;
1374 ttysz
.ts_lines
= win
.ws_row
;
1375 ttysz
.ts_cols
= win
.ws_col
;
1380 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1381 error (1, errno
, "%s", device_name
);
1383 if (ioctl (fd
, TIOCSSIZE
, (char *) &ttysz
))
1384 error (1, errno
, "%s", device_name
);
1389 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1390 error (1, errno
, "%s", device_name
);
1394 display_window_size (int fancy
, int fd
, const char *device_name
)
1398 if (get_win_size (fd
, &win
))
1400 if (errno
!= EINVAL
)
1401 error (1, errno
, "%s", device_name
);
1403 error (1, 0, _("%s: no size information for this device"), device_name
);
1407 wrapf (fancy
? "rows %d; columns %d;" : "%d %d\n",
1408 win
.ws_row
, win
.ws_col
);
1416 screen_columns (void)
1421 /* With Solaris 2.[123], this ioctl fails and errno is set to
1422 EINVAL for telnet (but not rlogin) sessions.
1423 On ISC 3.0, it fails for the console and the serial port
1424 (but it works for ptys).
1425 It can also fail on any system when stdout isn't a tty.
1426 In case of any failure, just use the default. */
1427 if (get_win_size (STDOUT_FILENO
, &win
) == 0 && win
.ws_col
> 0)
1430 /* FIXME: use xstrtol */
1431 if (getenv ("COLUMNS"))
1432 return atoi (getenv ("COLUMNS"));
1437 mode_type_flag (enum mode_type type
, struct termios
*mode
)
1442 return &mode
->c_cflag
;
1445 return &mode
->c_iflag
;
1448 return &mode
->c_oflag
;
1451 return &mode
->c_lflag
;
1462 display_settings (enum output_type output_type
, struct termios
*mode
,
1463 int fd
, const char *device_name
)
1465 switch (output_type
)
1468 display_changed (mode
);
1472 display_all (mode
, fd
, device_name
);
1476 display_recoverable (mode
);
1482 display_changed (struct termios
*mode
)
1488 enum mode_type prev_type
= control
;
1490 display_speed (mode
, 1);
1492 wrapf ("line = %d;", mode
->c_line
);
1498 for (i
= 0; !STREQ (control_info
[i
].name
, "min"); ++i
)
1500 if (mode
->c_cc
[control_info
[i
].offset
] == control_info
[i
].saneval
)
1502 /* If swtch is the same as susp, don't print both. */
1504 if (STREQ (control_info
[i
].name
, "swtch"))
1507 /* If eof uses the same slot as min, only print whichever applies. */
1509 if ((mode
->c_lflag
& ICANON
) == 0
1510 && (STREQ (control_info
[i
].name
, "eof")
1511 || STREQ (control_info
[i
].name
, "eol")))
1516 wrapf ("%s = %s;", control_info
[i
].name
,
1517 visible (mode
->c_cc
[control_info
[i
].offset
]));
1519 if ((mode
->c_lflag
& ICANON
) == 0)
1521 wrapf ("min = %d; time = %d;\n", (int) mode
->c_cc
[VMIN
],
1522 (int) mode
->c_cc
[VTIME
]);
1524 else if (empty_line
== 0)
1529 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1531 if (mode_info
[i
].flags
& OMIT
)
1533 if (mode_info
[i
].type
!= prev_type
)
1535 if (empty_line
== 0)
1541 prev_type
= mode_info
[i
].type
;
1544 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1545 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1546 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1548 if (mode_info
[i
].flags
& SANE_UNSET
)
1550 wrapf ("%s", mode_info
[i
].name
);
1554 else if ((mode_info
[i
].flags
& (SANE_SET
| REV
)) == (SANE_SET
| REV
))
1556 wrapf ("-%s", mode_info
[i
].name
);
1560 if (empty_line
== 0)
1566 display_all (struct termios
*mode
, int fd
, const char *device_name
)
1571 enum mode_type prev_type
= control
;
1573 display_speed (mode
, 1);
1575 display_window_size (1, fd
, device_name
);
1578 wrapf ("line = %d;", mode
->c_line
);
1583 for (i
= 0; ! STREQ (control_info
[i
].name
, "min"); ++i
)
1585 /* If swtch is the same as susp, don't print both. */
1587 if (STREQ (control_info
[i
].name
, "swtch"))
1590 /* If eof uses the same slot as min, only print whichever applies. */
1592 if ((mode
->c_lflag
& ICANON
) == 0
1593 && (STREQ (control_info
[i
].name
, "eof")
1594 || STREQ (control_info
[i
].name
, "eol")))
1597 wrapf ("%s = %s;", control_info
[i
].name
,
1598 visible (mode
->c_cc
[control_info
[i
].offset
]));
1601 if ((mode
->c_lflag
& ICANON
) == 0)
1603 wrapf ("min = %d; time = %d;", mode
->c_cc
[VMIN
], mode
->c_cc
[VTIME
]);
1604 if (current_col
!= 0)
1608 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1610 if (mode_info
[i
].flags
& OMIT
)
1612 if (mode_info
[i
].type
!= prev_type
)
1616 prev_type
= mode_info
[i
].type
;
1619 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1620 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1621 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1622 wrapf ("%s", mode_info
[i
].name
);
1623 else if (mode_info
[i
].flags
& REV
)
1624 wrapf ("-%s", mode_info
[i
].name
);
1631 display_speed (struct termios
*mode
, int fancy
)
1633 if (cfgetispeed (mode
) == 0 || cfgetispeed (mode
) == cfgetospeed (mode
))
1634 wrapf (fancy
? "speed %lu baud;" : "%lu\n",
1635 baud_to_value (cfgetospeed (mode
)));
1637 wrapf (fancy
? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n",
1638 baud_to_value (cfgetispeed (mode
)),
1639 baud_to_value (cfgetospeed (mode
)));
1645 display_recoverable (struct termios
*mode
)
1649 printf ("%lx:%lx:%lx:%lx",
1650 (unsigned long) mode
->c_iflag
, (unsigned long) mode
->c_oflag
,
1651 (unsigned long) mode
->c_cflag
, (unsigned long) mode
->c_lflag
);
1652 for (i
= 0; i
< NCCS
; ++i
)
1653 printf (":%x", (unsigned int) mode
->c_cc
[i
]);
1658 recover_mode (char *arg
, struct termios
*mode
)
1662 unsigned long iflag
, oflag
, cflag
, lflag
;
1664 /* Scan into temporaries since it is too much trouble to figure out
1665 the right format for `tcflag_t'. */
1666 if (sscanf (arg
, "%lx:%lx:%lx:%lx%n",
1667 &iflag
, &oflag
, &cflag
, &lflag
, &n
) != 4)
1669 mode
->c_iflag
= iflag
;
1670 mode
->c_oflag
= oflag
;
1671 mode
->c_cflag
= cflag
;
1672 mode
->c_lflag
= lflag
;
1674 for (i
= 0; i
< NCCS
; ++i
)
1676 if (sscanf (arg
, ":%x%n", &chr
, &n
) != 1)
1678 mode
->c_cc
[i
] = chr
;
1682 /* Fail if there are too many fields. */
1691 const char *string
; /* ASCII representation. */
1692 speed_t speed
; /* Internal form. */
1693 unsigned long value
; /* Numeric value. */
1696 struct speed_map speeds
[] =
1703 {"134.5", B134
, 134},
1708 {"1200", B1200
, 1200},
1709 {"1800", B1800
, 1800},
1710 {"2400", B2400
, 2400},
1711 {"4800", B4800
, 4800},
1712 {"9600", B9600
, 9600},
1713 {"19200", B19200
, 19200},
1714 {"38400", B38400
, 38400},
1715 {"exta", B19200
, 19200},
1716 {"extb", B38400
, 38400},
1718 {"57600", B57600
, 57600},
1721 {"115200", B115200
, 115200},
1724 {"230400", B230400
, 230400},
1727 {"460800", B460800
, 460800},
1733 string_to_baud (const char *arg
)
1737 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1738 if (STREQ (arg
, speeds
[i
].string
))
1739 return speeds
[i
].speed
;
1740 return (speed_t
) -1;
1743 static unsigned long
1744 baud_to_value (speed_t speed
)
1748 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1749 if (speed
== speeds
[i
].speed
)
1750 return speeds
[i
].value
;
1755 sane_mode (struct termios
*mode
)
1760 for (i
= 0; control_info
[i
].name
; ++i
)
1763 if (STREQ (control_info
[i
].name
, "min"))
1766 mode
->c_cc
[control_info
[i
].offset
] = control_info
[i
].saneval
;
1769 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1771 if (mode_info
[i
].flags
& SANE_SET
)
1773 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1774 *bitsp
= (*bitsp
& ~mode_info
[i
].mask
) | mode_info
[i
].bits
;
1776 else if (mode_info
[i
].flags
& SANE_UNSET
)
1778 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1779 *bitsp
= *bitsp
& ~mode_info
[i
].mask
& ~mode_info
[i
].bits
;
1784 /* Return a string that is the printable representation of character CH. */
1785 /* Adapted from `cat' by Torbjorn Granlund. */
1788 visible (unsigned int ch
)
1790 static char buf
[10];
1793 if (ch
== _POSIX_VDISABLE
)
1794 return _("<undef>");
1812 *bpout
++ = ch
- 128;
1822 *bpout
++ = ch
- 128 + 64;
1832 return (const char *) buf
;
1835 /* Parse string S as an integer, using decimal radix by default,
1836 but allowing octal and hex numbers as in C. */
1837 /* From `od' by Richard Stallman. */
1840 integer_arg (const char *s
)
1843 if (xstrtol (s
, NULL
, 0, &value
, "bB") != LONGINT_OK
)
1845 error (0, 0, _("invalid integer argument `%s'"), s
);