1 /* stty -- change and print terminal line settings
2 Copyright (C) 1990-2004 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>
56 #define VA_START(args, lastarg) va_start(args, lastarg)
59 #include "long-options.h"
63 /* The official name of this program (e.g., no `g' prefix). */
64 #define PROGRAM_NAME "stty"
66 #define AUTHORS "David MacKenzie"
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(CREPRINT) && !defined(CRPRNT)
133 # define CRPRNT Control ('r')
135 #if defined(VWERASE) && !defined(CWERASE)
136 # define CWERASE Control ('w')
138 #if defined(VLNEXT) && !defined(CLNEXT)
139 # define CLNEXT Control ('v')
141 #if defined(VDISCARD) && !defined(VFLUSHO)
142 # define VFLUSHO VDISCARD
144 #if defined(VFLUSH) && !defined(VFLUSHO) /* Ultrix 4.2 */
145 # define VFLUSHO VFLUSH
147 #if defined(CTLECH) && !defined(ECHOCTL) /* Ultrix 4.3 */
148 # define ECHOCTL CTLECH
150 #if defined(TCTLECH) && !defined(ECHOCTL) /* Ultrix 4.2 */
151 # define ECHOCTL TCTLECH
153 #if defined(CRTKIL) && !defined(ECHOKE) /* Ultrix 4.2 and 4.3 */
154 # define ECHOKE CRTKIL
156 #if defined(VFLUSHO) && !defined(CFLUSHO)
157 # define CFLUSHO Control ('o')
159 #if defined(VSTATUS) && !defined(CSTATUS)
160 # define CSTATUS Control ('t')
163 /* Which speeds to set. */
166 input_speed
, output_speed
, both_speeds
169 /* What to output and how. */
172 changed
, all
, recoverable
/* Default, -a, -g. */
175 /* Which member(s) of `struct termios' a mode uses. */
178 control
, input
, output
, local
, combination
181 /* Flags for `struct mode_info'. */
182 #define SANE_SET 1 /* Set in `sane' mode. */
183 #define SANE_UNSET 2 /* Unset in `sane' mode. */
184 #define REV 4 /* Can be turned off by prepending `-'. */
185 #define OMIT 8 /* Don't display value. */
190 const char *name
; /* Name given on command line. */
191 enum mode_type type
; /* Which structure element to change. */
192 char flags
; /* Setting and display options. */
193 unsigned long bits
; /* Bits to set for this mode. */
194 unsigned long mask
; /* Other bits to turn off for this mode. */
197 static struct mode_info mode_info
[] =
199 {"parenb", control
, REV
, PARENB
, 0},
200 {"parodd", control
, REV
, PARODD
, 0},
201 {"cs5", control
, 0, CS5
, CSIZE
},
202 {"cs6", control
, 0, CS6
, CSIZE
},
203 {"cs7", control
, 0, CS7
, CSIZE
},
204 {"cs8", control
, 0, CS8
, CSIZE
},
205 {"hupcl", control
, REV
, HUPCL
, 0},
206 {"hup", control
, REV
| OMIT
, HUPCL
, 0},
207 {"cstopb", control
, REV
, CSTOPB
, 0},
208 {"cread", control
, SANE_SET
| REV
, CREAD
, 0},
209 {"clocal", control
, REV
, CLOCAL
, 0},
211 {"crtscts", control
, REV
, CRTSCTS
, 0},
214 {"ignbrk", input
, SANE_UNSET
| REV
, IGNBRK
, 0},
215 {"brkint", input
, SANE_SET
| REV
, BRKINT
, 0},
216 {"ignpar", input
, REV
, IGNPAR
, 0},
217 {"parmrk", input
, REV
, PARMRK
, 0},
218 {"inpck", input
, REV
, INPCK
, 0},
219 {"istrip", input
, REV
, ISTRIP
, 0},
220 {"inlcr", input
, SANE_UNSET
| REV
, INLCR
, 0},
221 {"igncr", input
, SANE_UNSET
| REV
, IGNCR
, 0},
222 {"icrnl", input
, SANE_SET
| REV
, ICRNL
, 0},
223 {"ixon", input
, REV
, IXON
, 0},
224 {"ixoff", input
, SANE_UNSET
| REV
, IXOFF
, 0},
225 {"tandem", input
, REV
| OMIT
, IXOFF
, 0},
227 {"iuclc", input
, SANE_UNSET
| REV
, IUCLC
, 0},
230 {"ixany", input
, SANE_UNSET
| REV
, IXANY
, 0},
233 {"imaxbel", input
, SANE_SET
| REV
, IMAXBEL
, 0},
236 {"opost", output
, SANE_SET
| REV
, OPOST
, 0},
238 {"olcuc", output
, SANE_UNSET
| REV
, OLCUC
, 0},
241 {"ocrnl", output
, SANE_UNSET
| REV
, OCRNL
, 0},
244 {"onlcr", output
, SANE_SET
| REV
, ONLCR
, 0},
247 {"onocr", output
, SANE_UNSET
| REV
, ONOCR
, 0},
250 {"onlret", output
, SANE_UNSET
| REV
, ONLRET
, 0},
253 {"ofill", output
, SANE_UNSET
| REV
, OFILL
, 0},
256 {"ofdel", output
, SANE_UNSET
| REV
, OFDEL
, 0},
259 {"nl1", output
, SANE_UNSET
, NL1
, NLDLY
},
260 {"nl0", output
, SANE_SET
, NL0
, NLDLY
},
263 {"cr3", output
, SANE_UNSET
, CR3
, CRDLY
},
264 {"cr2", output
, SANE_UNSET
, CR2
, CRDLY
},
265 {"cr1", output
, SANE_UNSET
, CR1
, CRDLY
},
266 {"cr0", output
, SANE_SET
, CR0
, CRDLY
},
269 {"tab3", output
, SANE_UNSET
, TAB3
, TABDLY
},
270 {"tab2", output
, SANE_UNSET
, TAB2
, TABDLY
},
271 {"tab1", output
, SANE_UNSET
, TAB1
, TABDLY
},
272 {"tab0", output
, SANE_SET
, TAB0
, TABDLY
},
275 {"tab3", output
, SANE_UNSET
, OXTABS
, 0},
279 {"bs1", output
, SANE_UNSET
, BS1
, BSDLY
},
280 {"bs0", output
, SANE_SET
, BS0
, BSDLY
},
283 {"vt1", output
, SANE_UNSET
, VT1
, VTDLY
},
284 {"vt0", output
, SANE_SET
, VT0
, VTDLY
},
287 {"ff1", output
, SANE_UNSET
, FF1
, FFDLY
},
288 {"ff0", output
, SANE_SET
, FF0
, FFDLY
},
291 {"isig", local
, SANE_SET
| REV
, ISIG
, 0},
292 {"icanon", local
, SANE_SET
| REV
, ICANON
, 0},
294 {"iexten", local
, SANE_SET
| REV
, IEXTEN
, 0},
296 {"echo", local
, SANE_SET
| REV
, ECHO
, 0},
297 {"echoe", local
, SANE_SET
| REV
, ECHOE
, 0},
298 {"crterase", local
, REV
| OMIT
, ECHOE
, 0},
299 {"echok", local
, SANE_SET
| REV
, ECHOK
, 0},
300 {"echonl", local
, SANE_UNSET
| REV
, ECHONL
, 0},
301 {"noflsh", local
, SANE_UNSET
| REV
, NOFLSH
, 0},
303 {"xcase", local
, SANE_UNSET
| REV
, XCASE
, 0},
306 {"tostop", local
, SANE_UNSET
| REV
, TOSTOP
, 0},
309 {"echoprt", local
, SANE_UNSET
| REV
, ECHOPRT
, 0},
310 {"prterase", local
, REV
| OMIT
, ECHOPRT
, 0},
313 {"echoctl", local
, SANE_SET
| REV
, ECHOCTL
, 0},
314 {"ctlecho", local
, REV
| OMIT
, ECHOCTL
, 0},
317 {"echoke", local
, SANE_SET
| REV
, ECHOKE
, 0},
318 {"crtkill", local
, REV
| OMIT
, ECHOKE
, 0},
321 {"evenp", combination
, REV
| OMIT
, 0, 0},
322 {"parity", combination
, REV
| OMIT
, 0, 0},
323 {"oddp", combination
, REV
| OMIT
, 0, 0},
324 {"nl", combination
, REV
| OMIT
, 0, 0},
325 {"ek", combination
, OMIT
, 0, 0},
326 {"sane", combination
, OMIT
, 0, 0},
327 {"cooked", combination
, REV
| OMIT
, 0, 0},
328 {"raw", combination
, REV
| OMIT
, 0, 0},
329 {"pass8", combination
, REV
| OMIT
, 0, 0},
330 {"litout", combination
, REV
| OMIT
, 0, 0},
331 {"cbreak", combination
, REV
| OMIT
, 0, 0},
333 {"decctlq", combination
, REV
| OMIT
, 0, 0},
335 #if defined (TABDLY) || defined (OXTABS)
336 {"tabs", combination
, REV
| OMIT
, 0, 0},
338 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
339 {"lcase", combination
, REV
| OMIT
, 0, 0},
340 {"LCASE", combination
, REV
| OMIT
, 0, 0},
342 {"crt", combination
, OMIT
, 0, 0},
343 {"dec", combination
, OMIT
, 0, 0},
345 {NULL
, control
, 0, 0, 0}
348 /* Control character settings. */
351 const char *name
; /* Name given on command line. */
352 unsigned char saneval
; /* Value to set for `stty sane'. */
353 int offset
; /* Offset in c_cc. */
356 /* Control characters. */
358 static struct control_info control_info
[] =
360 {"intr", CINTR
, VINTR
},
361 {"quit", CQUIT
, VQUIT
},
362 {"erase", CERASE
, VERASE
},
363 {"kill", CKILL
, VKILL
},
367 {"eol2", CEOL2
, VEOL2
},
370 {"swtch", CSWTCH
, VSWTCH
},
372 {"start", CSTART
, VSTART
},
373 {"stop", CSTOP
, VSTOP
},
374 {"susp", CSUSP
, VSUSP
},
376 {"dsusp", CDSUSP
, VDSUSP
},
379 {"rprnt", CRPRNT
, VREPRINT
},
381 # ifdef CREPRINT /* HPUX 10.20 needs this */
382 {"rprnt", CRPRNT
, CREPRINT
},
386 {"werase", CWERASE
, VWERASE
},
389 {"lnext", CLNEXT
, VLNEXT
},
392 {"flush", CFLUSHO
, VFLUSHO
},
395 {"status", CSTATUS
, VSTATUS
},
398 /* These must be last because of the display routines. */
404 static const char *visible (unsigned int ch
);
405 static unsigned long baud_to_value (speed_t speed
);
406 static int recover_mode (char *arg
, struct termios
*mode
);
407 static int screen_columns (void);
408 static int set_mode (struct mode_info
*info
, int reversed
,
409 struct termios
*mode
);
410 static long integer_arg (const char *s
);
411 static speed_t
string_to_baud (const char *arg
);
412 static tcflag_t
*mode_type_flag (enum mode_type type
, struct termios
*mode
);
413 static void display_all (struct termios
*mode
, int fd
, const char *device_name
);
414 static void display_changed (struct termios
*mode
);
415 static void display_recoverable (struct termios
*mode
);
416 static void display_settings (enum output_type output_type
,
417 struct termios
*mode
, int fd
,
418 const char *device_name
);
419 static void display_speed (struct termios
*mode
, int fancy
);
420 static void display_window_size (int fancy
, int fd
, const char *device_name
);
421 static void sane_mode (struct termios
*mode
);
422 static void set_control_char (struct control_info
*info
,
424 struct termios
*mode
);
425 static void set_speed (enum speed_setting type
, const char *arg
,
426 struct termios
*mode
);
427 static void set_window_size (int rows
, int cols
, int fd
,
428 const char *device_name
);
430 /* The width of the screen, for output wrapping. */
433 /* Current position, to know when to wrap. */
434 static int current_col
;
436 static struct option longopts
[] =
438 {"all", no_argument
, NULL
, 'a'},
439 {"save", no_argument
, NULL
, 'g'},
440 {"file", required_argument
, NULL
, 'F'},
444 /* The name this program was run with. */
447 static void wrapf (const char *message
, ...)
448 __attribute__ ((__format__ (__printf__
, 1, 2)));
450 /* Print format string MESSAGE and optional args.
451 Wrap to next line first if it won't fit.
452 Print a space first unless MESSAGE will start a new line. */
456 wrapf (const char *message
,...)
459 char buf
[1024]; /* Plenty long for our needs. */
462 VA_START (args
, message
);
463 vsprintf (buf
, message
, args
);
465 buflen
= strlen (buf
);
467 && max_col
<= current_col
+ (0 < current_col
) + buflen
)
478 current_col
+= buflen
;
484 if (status
!= EXIT_SUCCESS
)
485 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
490 Usage: %s [-F DEVICE] [--file=DEVICE] [SETTING]...\n\
491 or: %s [-F DEVICE] [--file=DEVICE] [-a|--all]\n\
492 or: %s [-F DEVICE] [--file=DEVICE] [-g|--save]\n\
494 program_name
, program_name
, program_name
);
496 Print or change terminal characteristics.\n\
498 -a, --all print all current settings in human-readable form\n\
499 -g, --save print all current settings in a stty-readable form\n\
500 -F, --file=DEVICE open and use the specified DEVICE instead of stdin\n\
502 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
503 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
506 Optional - before SETTING indicates negation. An * marks non-POSIX\n\
507 settings. The underlying system defines which settings are available.\n\
511 Special characters:\n\
512 * dsusp CHAR CHAR will send a terminal stop signal once input flushed\n\
513 eof CHAR CHAR will send an end of file (terminate the input)\n\
514 eol CHAR CHAR will end the line\n\
517 * eol2 CHAR alternate CHAR for ending the line\n\
518 erase CHAR CHAR will erase the last character typed\n\
519 intr CHAR CHAR will send an interrupt signal\n\
520 kill CHAR CHAR will erase the current line\n\
523 * lnext CHAR CHAR will enter the next character quoted\n\
524 quit CHAR CHAR will send a quit signal\n\
525 * rprnt CHAR CHAR will redraw the current line\n\
526 start CHAR CHAR will restart the output after stopping it\n\
529 stop CHAR CHAR will stop the output\n\
530 susp CHAR CHAR will send a terminal stop signal\n\
531 * swtch CHAR CHAR will switch to a different shell layer\n\
532 * werase CHAR CHAR will erase the last word typed\n\
537 N set the input and output speeds to N bauds\n\
538 * cols N tell the kernel that the terminal has N columns\n\
539 * columns N same as cols N\n\
542 ispeed N set the input speed to N\n\
543 * line N use line discipline N\n\
544 min N with -icanon, set N characters minimum for a completed read\n\
545 ospeed N set the output speed to N\n\
548 * rows N tell the kernel that the terminal has N rows\n\
549 * size print the number of rows and columns according to the kernel\n\
550 speed print the terminal speed\n\
551 time N with -icanon, set read timeout of N tenths of a second\n\
556 [-]clocal disable modem control signals\n\
557 [-]cread allow input to be received\n\
558 * [-]crtscts enable RTS/CTS handshaking\n\
559 csN set character size to N bits, N in [5..8]\n\
562 [-]cstopb use two stop bits per character (one with `-')\n\
563 [-]hup send a hangup signal when the last process closes the tty\n\
564 [-]hupcl same as [-]hup\n\
565 [-]parenb generate parity bit in output and expect parity bit in input\n\
566 [-]parodd set odd parity (even with `-')\n\
571 [-]brkint breaks cause an interrupt signal\n\
572 [-]icrnl translate carriage return to newline\n\
573 [-]ignbrk ignore break characters\n\
574 [-]igncr ignore carriage return\n\
577 [-]ignpar ignore characters with parity errors\n\
578 * [-]imaxbel beep and do not flush a full input buffer on a character\n\
579 [-]inlcr translate newline to carriage return\n\
580 [-]inpck enable input parity checking\n\
581 [-]istrip clear high (8th) bit of input characters\n\
584 * [-]iuclc translate uppercase characters to lowercase\n\
585 * [-]ixany let any character restart output, not only start character\n\
586 [-]ixoff enable sending of start/stop characters\n\
587 [-]ixon enable XON/XOFF flow control\n\
588 [-]parmrk mark parity errors (with a 255-0-character sequence)\n\
589 [-]tandem same as [-]ixoff\n\
594 * bsN backspace delay style, N in [0..1]\n\
595 * crN carriage return delay style, N in [0..3]\n\
596 * ffN form feed delay style, N in [0..1]\n\
597 * nlN newline delay style, N in [0..1]\n\
600 * [-]ocrnl translate carriage return to newline\n\
601 * [-]ofdel use delete characters for fill instead of null characters\n\
602 * [-]ofill use fill (padding) characters instead of timing for delays\n\
603 * [-]olcuc translate lowercase characters to uppercase\n\
604 * [-]onlcr translate newline to carriage return-newline\n\
605 * [-]onlret newline performs a carriage return\n\
608 * [-]onocr do not print carriage returns in the first column\n\
609 [-]opost postprocess output\n\
610 * tabN horizontal tab delay style, N in [0..3]\n\
611 * tabs same as tab0\n\
612 * -tabs same as tab3\n\
613 * vtN vertical tab delay style, N in [0..1]\n\
618 [-]crterase echo erase characters as backspace-space-backspace\n\
619 * crtkill kill all line by obeying the echoprt and echoe settings\n\
620 * -crtkill kill all line by obeying the echoctl and echok settings\n\
623 * [-]ctlecho echo control characters in hat notation (`^c')\n\
624 [-]echo echo input characters\n\
625 * [-]echoctl same as [-]ctlecho\n\
626 [-]echoe same as [-]crterase\n\
627 [-]echok echo a newline after a kill character\n\
630 * [-]echoke same as [-]crtkill\n\
631 [-]echonl echo newline even if not echoing other characters\n\
632 * [-]echoprt echo erased characters backward, between `\\' and '/'\n\
633 [-]icanon enable erase, kill, werase, and rprnt special characters\n\
634 [-]iexten enable non-POSIX special characters\n\
637 [-]isig enable interrupt, quit, and suspend special characters\n\
638 [-]noflsh disable flushing after interrupt and quit special characters\n\
639 * [-]prterase same as [-]echoprt\n\
640 * [-]tostop stop background jobs that try to write to the terminal\n\
641 * [-]xcase with icanon, escape with `\\' for uppercase characters\n\
645 Combination settings:\n\
646 * [-]LCASE same as [-]lcase\n\
647 cbreak same as -icanon\n\
648 -cbreak same as icanon\n\
651 cooked same as brkint ignpar istrip icrnl ixon opost isig\n\
652 icanon, eof and eol characters to their default values\n\
653 -cooked same as raw\n\
654 crt same as echoe echoctl echoke\n\
657 dec same as echoe echoctl echoke -ixany intr ^c erase 0177\n\
659 * [-]decctlq same as [-]ixany\n\
660 ek erase and kill characters to their default values\n\
661 evenp same as parenb -parodd cs7\n\
664 -evenp same as -parenb cs8\n\
665 * [-]lcase same as xcase iuclc olcuc\n\
666 litout same as -parenb -istrip -opost cs8\n\
667 -litout same as parenb istrip opost cs7\n\
668 nl same as -icrnl -onlcr\n\
669 -nl same as icrnl -inlcr -igncr onlcr -ocrnl -onlret\n\
672 oddp same as parenb parodd cs7\n\
673 -oddp same as -parenb cs8\n\
674 [-]parity same as [-]evenp\n\
675 pass8 same as -parenb -istrip cs8\n\
676 -pass8 same as parenb istrip cs7\n\
679 raw same as -ignbrk -brkint -ignpar -parmrk -inpck -istrip\n\
680 -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany\n\
681 -imaxbel -opost -isig -icanon -xcase min 1 time 0\n\
682 -raw same as cooked\n\
685 sane same as cread -ignbrk brkint -inlcr -igncr icrnl\n\
686 -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr\n\
687 -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0\n\
688 isig icanon iexten echo echoe echok -echonl -noflsh\n\
689 -xcase -tostop -echoprt echoctl echoke, all special\n\
690 characters to their default values.\n\
694 Handle the tty line connected to standard input. Without arguments,\n\
695 prints baud rate, line discipline, and deviations from stty sane. In\n\
696 settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
697 127; special values ^- or undef used to disable special characters.\n\
699 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
704 /* Return 1 if the string contains only valid options. */
706 valid_options (char *opt
, const char *valid_opts
,
707 const char *valid_arg_opts
)
711 if (*opt
++ != '-' || *opt
== 0)
717 if (strchr (valid_opts
, ch
))
719 if (strchr (valid_arg_opts
, ch
))
727 main (int argc
, char **argv
)
730 enum output_type output_type
;
732 int require_set_attr
;
735 int recoverable_output
;
738 char *file_name
= NULL
;
740 const char *device_name
;
741 const char *posixly_correct
= getenv ("POSIXLY_CORRECT");
742 int invalid_long_option
= 0;
744 initialize_main (&argc
, &argv
);
745 program_name
= argv
[0];
746 setlocale (LC_ALL
, "");
747 bindtextdomain (PACKAGE
, LOCALEDIR
);
748 textdomain (PACKAGE
);
750 atexit (close_stdout
);
752 parse_long_options (argc
, argv
, PROGRAM_NAME
, GNU_PACKAGE
, VERSION
,
753 usage
, AUTHORS
, (char const *) NULL
);
755 output_type
= changed
;
757 recoverable_output
= 0;
759 /* Don't print error messages for unrecognized options. */
762 while ((optc
= getopt_long (argc
, argv
, "agF:", longopts
, NULL
)) != -1)
764 int unrecognized_option
= 0;
773 recoverable_output
= 1;
774 output_type
= recoverable
;
779 error (EXIT_FAILURE
, 0, _("only one device may be specified"));
784 unrecognized_option
= 1;
788 if (unrecognized_option
)
792 /* FIXME: what is this?!? */
793 if (invalid_long_option
)
794 usage (EXIT_FAILURE
);
796 /* Clear out the options that have been parsed. This is really
797 gross, but it's needed because stty SETTINGS look like options to
798 getopt(), so we need to work around things in a really horrible
799 way. If any new options are ever added to stty, the short option
800 MUST NOT be a letter which is the first letter of one of the
801 possible stty settings. If you change anything about how stty
802 parses options, be sure it still works with combinations of
803 short and long options, --, POSIXLY_CORRECT, etc. */
804 for (k
= 1; k
< argc
; k
++)
812 /* Handle --, and reset noargs if there are arguments following it. */
813 if (STREQ (argv
[k
], "--"))
821 /* Handle "--file device" */
822 len
= strlen (argv
[k
]);
823 if (len
>= 3 && strstr ("--file", argv
[k
]))
830 /* Handle "--all" and "--save". */
832 && (strstr ("--all", argv
[k
])
833 || strstr ("--save", argv
[k
])))
839 /* Handle "--file=device". */
840 eq
= strchr (argv
[k
], '=');
841 if (eq
&& eq
- argv
[k
] >= 3)
844 if (strstr ("--file", argv
[k
]))
849 /* Put the equals sign back for the error message. */
853 /* Handle "-a", "-ag", "-aF/dev/foo", "-aF /dev/foo", etc. */
854 if (valid_options (argv
[k
], "ag", "F"))
856 /* FIXME: this loses when the device name ends in `F'.
857 e.g. `stty -F/dev/BARF nl' would clobber the `nl' argument. */
858 if (argv
[k
][strlen (argv
[k
]) - 1] == 'F')
862 /* Everything else must be a normal, non-option argument. */
871 /* Specifying both -a and -g gets an error. */
872 if (verbose_output
&& recoverable_output
)
873 error (EXIT_FAILURE
, 0,
874 _("the options for verbose and stty-readable output styles are\n\
875 mutually exclusive"));
877 /* Specifying any other arguments with -a or -g gets an error. */
878 if (!noargs
&& (verbose_output
|| recoverable_output
))
879 error (EXIT_FAILURE
, 0,
880 _("when specifying an output style, modes may not be set"));
882 /* FIXME: it'd be better not to open the file until we've verified
883 that all arguments are valid. Otherwise, we could end up doing
884 only some of the requested operations and then failing, probably
885 leaving things in an undesirable state. */
890 device_name
= file_name
;
891 fd
= open (device_name
, O_RDONLY
| O_NONBLOCK
);
893 error (EXIT_FAILURE
, errno
, "%s", device_name
);
894 if ((fdflags
= fcntl (fd
, F_GETFL
)) == -1
895 || fcntl (fd
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
896 error (EXIT_FAILURE
, errno
, _("%s: couldn't reset non-blocking mode"),
902 device_name
= _("standard input");
905 /* Initialize to all zeroes so there is no risk memcmp will report a
906 spurious difference in an uninitialized portion of the structure. */
907 memset (&mode
, 0, sizeof (mode
));
908 if (tcgetattr (fd
, &mode
))
909 error (EXIT_FAILURE
, errno
, "%s", device_name
);
911 if (verbose_output
|| recoverable_output
|| noargs
)
913 max_col
= screen_columns ();
915 display_settings (output_type
, &mode
, fd
, device_name
);
920 require_set_attr
= 0;
934 if (argv
[k
][0] == '-')
939 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
941 if (STREQ (argv
[k
], mode_info
[i
].name
))
943 match_found
= set_mode (&mode_info
[i
], reversed
, &mode
);
944 require_set_attr
= 1;
948 if (match_found
== 0 && reversed
)
950 error (0, 0, _("invalid argument `%s'"), --argv
[k
]);
951 usage (EXIT_FAILURE
);
953 if (match_found
== 0)
955 for (i
= 0; control_info
[i
].name
!= NULL
; ++i
)
957 if (STREQ (argv
[k
], control_info
[i
].name
))
961 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
962 usage (EXIT_FAILURE
);
966 set_control_char (&control_info
[i
], argv
[k
], &mode
);
967 require_set_attr
= 1;
972 if (match_found
== 0)
974 if (STREQ (argv
[k
], "ispeed"))
978 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
979 usage (EXIT_FAILURE
);
982 set_speed (input_speed
, argv
[k
], &mode
);
984 require_set_attr
= 1;
986 else if (STREQ (argv
[k
], "ospeed"))
990 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
991 usage (EXIT_FAILURE
);
994 set_speed (output_speed
, argv
[k
], &mode
);
996 require_set_attr
= 1;
999 else if (STREQ (argv
[k
], "rows"))
1003 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1004 usage (EXIT_FAILURE
);
1007 set_window_size ((int) integer_arg (argv
[k
]), -1,
1010 else if (STREQ (argv
[k
], "cols")
1011 || STREQ (argv
[k
], "columns"))
1015 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1016 usage (EXIT_FAILURE
);
1019 set_window_size (-1, (int) integer_arg (argv
[k
]),
1022 else if (STREQ (argv
[k
], "size"))
1024 max_col
= screen_columns ();
1026 display_window_size (0, fd
, device_name
);
1030 else if (STREQ (argv
[k
], "line"))
1034 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1035 usage (EXIT_FAILURE
);
1038 mode
.c_line
= integer_arg (argv
[k
]);
1039 require_set_attr
= 1;
1042 else if (STREQ (argv
[k
], "speed"))
1044 max_col
= screen_columns ();
1045 display_speed (&mode
, 0);
1047 else if (string_to_baud (argv
[k
]) != (speed_t
) -1)
1049 set_speed (both_speeds
, argv
[k
], &mode
);
1051 require_set_attr
= 1;
1055 if (recover_mode (argv
[k
], &mode
) == 0)
1057 error (0, 0, _("invalid argument `%s'"), argv
[k
]);
1058 usage (EXIT_FAILURE
);
1060 require_set_attr
= 1;
1066 if (require_set_attr
)
1068 struct termios new_mode
;
1070 if (tcsetattr (fd
, TCSADRAIN
, &mode
))
1071 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1073 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
1074 it performs *any* of the requested operations. This means it
1075 can report `success' when it has actually failed to perform
1076 some proper subset of the requested operations. To detect
1077 this partial failure, get the current terminal attributes and
1078 compare them to the requested ones. */
1080 /* Initialize to all zeroes so there is no risk memcmp will report a
1081 spurious difference in an uninitialized portion of the structure. */
1082 memset (&new_mode
, 0, sizeof (new_mode
));
1083 if (tcgetattr (fd
, &new_mode
))
1084 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1086 /* Normally, one shouldn't use memcmp to compare structures that
1087 may have `holes' containing uninitialized data, but we have been
1088 careful to initialize the storage of these two variables to all
1089 zeroes. One might think it more efficient simply to compare the
1090 modified fields, but that would require enumerating those fields --
1091 and not all systems have the same fields in this structure. */
1093 if (memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1096 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1097 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1098 sometimes (m1 != m2). The only difference is in the four bits
1099 of the c_cflag field corresponding to the baud rate. To save
1100 Sun users a little confusion, don't report an error if this
1101 happens. But suppress the error only if we haven't tried to
1102 set the baud rate explicitly -- otherwise we'd never give an
1103 error for a true failure to set the baud rate. */
1105 new_mode
.c_cflag
&= (~CIBAUD
);
1106 if (speed_was_set
|| memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1109 error (EXIT_FAILURE
, 0,
1110 _("%s: unable to perform all requested operations"),
1115 printf (_("new_mode: mode\n"));
1116 for (i
= 0; i
< sizeof (new_mode
); i
++)
1117 printf ("0x%02x: 0x%02x\n",
1118 *(((unsigned char *) &new_mode
) + i
),
1119 *(((unsigned char *) &mode
) + i
));
1126 exit (EXIT_SUCCESS
);
1129 /* Return 0 if not applied because not reversible; otherwise return 1. */
1132 set_mode (struct mode_info
*info
, int reversed
, struct termios
*mode
)
1136 if (reversed
&& (info
->flags
& REV
) == 0)
1139 bitsp
= mode_type_flag (info
->type
, mode
);
1143 /* Combination mode. */
1144 if (STREQ (info
->name
, "evenp") || STREQ (info
->name
, "parity"))
1147 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1149 mode
->c_cflag
= (mode
->c_cflag
& ~PARODD
& ~CSIZE
) | PARENB
| CS7
;
1151 else if (STREQ (info
->name
, "oddp"))
1154 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1156 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARODD
| PARENB
;
1158 else if (STREQ (info
->name
, "nl"))
1162 mode
->c_iflag
= (mode
->c_iflag
| ICRNL
) & ~INLCR
& ~IGNCR
;
1163 mode
->c_oflag
= (mode
->c_oflag
1178 mode
->c_iflag
= mode
->c_iflag
& ~ICRNL
;
1180 mode
->c_oflag
= mode
->c_oflag
& ~ONLCR
;
1184 else if (STREQ (info
->name
, "ek"))
1186 mode
->c_cc
[VERASE
] = CERASE
;
1187 mode
->c_cc
[VKILL
] = CKILL
;
1189 else if (STREQ (info
->name
, "sane"))
1191 else if (STREQ (info
->name
, "cbreak"))
1194 mode
->c_lflag
|= ICANON
;
1196 mode
->c_lflag
&= ~ICANON
;
1198 else if (STREQ (info
->name
, "pass8"))
1202 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1203 mode
->c_iflag
|= ISTRIP
;
1207 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1208 mode
->c_iflag
&= ~ISTRIP
;
1211 else if (STREQ (info
->name
, "litout"))
1215 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1216 mode
->c_iflag
|= ISTRIP
;
1217 mode
->c_oflag
|= OPOST
;
1221 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1222 mode
->c_iflag
&= ~ISTRIP
;
1223 mode
->c_oflag
&= ~OPOST
;
1226 else if (STREQ (info
->name
, "raw") || STREQ (info
->name
, "cooked"))
1228 if ((info
->name
[0] == 'r' && reversed
)
1229 || (info
->name
[0] == 'c' && !reversed
))
1232 mode
->c_iflag
|= BRKINT
| IGNPAR
| ISTRIP
| ICRNL
| IXON
;
1233 mode
->c_oflag
|= OPOST
;
1234 mode
->c_lflag
|= ISIG
| ICANON
;
1236 mode
->c_cc
[VEOF
] = CEOF
;
1239 mode
->c_cc
[VEOL
] = CEOL
;
1246 mode
->c_oflag
&= ~OPOST
;
1247 mode
->c_lflag
&= ~(ISIG
| ICANON
1252 mode
->c_cc
[VMIN
] = 1;
1253 mode
->c_cc
[VTIME
] = 0;
1257 else if (STREQ (info
->name
, "decctlq"))
1260 mode
->c_iflag
|= IXANY
;
1262 mode
->c_iflag
&= ~IXANY
;
1266 else if (STREQ (info
->name
, "tabs"))
1269 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB3
;
1271 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB0
;
1275 else if (STREQ (info
->name
, "tabs"))
1278 mode
->c_oflag
= mode
->c_oflag
| OXTABS
;
1280 mode
->c_oflag
= mode
->c_oflag
& ~OXTABS
;
1284 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
1285 else if (STREQ (info
->name
, "lcase")
1286 || STREQ (info
->name
, "LCASE"))
1290 mode
->c_lflag
&= ~XCASE
;
1291 mode
->c_iflag
&= ~IUCLC
;
1292 mode
->c_oflag
&= ~OLCUC
;
1296 mode
->c_lflag
|= XCASE
;
1297 mode
->c_iflag
|= IUCLC
;
1298 mode
->c_oflag
|= OLCUC
;
1302 else if (STREQ (info
->name
, "crt"))
1303 mode
->c_lflag
|= ECHOE
1311 else if (STREQ (info
->name
, "dec"))
1313 mode
->c_cc
[VINTR
] = 3; /* ^C */
1314 mode
->c_cc
[VERASE
] = 127; /* DEL */
1315 mode
->c_cc
[VKILL
] = 21; /* ^U */
1316 mode
->c_lflag
|= ECHOE
1325 mode
->c_iflag
&= ~IXANY
;
1330 *bitsp
= *bitsp
& ~info
->mask
& ~info
->bits
;
1332 *bitsp
= (*bitsp
& ~info
->mask
) | info
->bits
;
1338 set_control_char (struct control_info
*info
, const char *arg
,
1339 struct termios
*mode
)
1341 unsigned char value
;
1343 if (STREQ (info
->name
, "min") || STREQ (info
->name
, "time"))
1344 value
= integer_arg (arg
);
1345 else if (arg
[0] == '\0' || arg
[1] == '\0')
1347 else if (STREQ (arg
, "^-") || STREQ (arg
, "undef"))
1348 value
= _POSIX_VDISABLE
;
1349 else if (arg
[0] == '^' && arg
[1] != '\0') /* Ignore any trailing junk. */
1354 value
= arg
[1] & ~0140; /* Non-letters get weird results. */
1357 value
= integer_arg (arg
);
1358 mode
->c_cc
[info
->offset
] = value
;
1362 set_speed (enum speed_setting type
, const char *arg
, struct termios
*mode
)
1366 baud
= string_to_baud (arg
);
1367 if (type
== input_speed
|| type
== both_speeds
)
1368 cfsetispeed (mode
, baud
);
1369 if (type
== output_speed
|| type
== both_speeds
)
1370 cfsetospeed (mode
, baud
);
1376 get_win_size (int fd
, struct winsize
*win
)
1378 int err
= ioctl (fd
, TIOCGWINSZ
, (char *) win
);
1383 set_window_size (int rows
, int cols
, int fd
, const char *device_name
)
1387 if (get_win_size (fd
, &win
))
1389 if (errno
!= EINVAL
)
1390 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1391 memset (&win
, 0, sizeof (win
));
1400 /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote:
1401 The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.
1402 This comment from sys/ttold.h describes Sun's twisted logic - a better
1403 test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).
1404 At any rate, the problem is gone in Solaris 2.x.
1406 Unfortunately, the old TIOCSSIZE code does collide with TIOCSWINSZ,
1407 but they can be disambiguated by checking whether a "struct ttysize"
1408 structure's "ts_lines" field is greater than 64K or not. If so,
1409 it's almost certainly a "struct winsize" instead.
1411 At any rate, the bug manifests itself when ws_row == 0; the symptom is
1412 that ws_row is set to ws_col, and ws_col is set to (ws_xpixel<<16) +
1413 ws_ypixel. Since GNU stty sets rows and columns separately, this bug
1414 caused "stty rows 0 cols 0" to set rows to cols and cols to 0, while
1415 "stty cols 0 rows 0" would do the right thing. On a little-endian
1416 machine like the sun386i, the problem is the same, but for ws_col == 0.
1418 The workaround is to do the ioctl once with row and col = 1 to set the
1419 pixel info, and then do it again using a TIOCSSIZE to set rows/cols. */
1421 if (win
.ws_row
== 0 || win
.ws_col
== 0)
1423 struct ttysize ttysz
;
1425 ttysz
.ts_lines
= win
.ws_row
;
1426 ttysz
.ts_cols
= win
.ws_col
;
1431 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1432 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1434 if (ioctl (fd
, TIOCSSIZE
, (char *) &ttysz
))
1435 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1440 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1441 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1445 display_window_size (int fancy
, int fd
, const char *device_name
)
1449 if (get_win_size (fd
, &win
))
1451 if (errno
!= EINVAL
)
1452 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1454 error (EXIT_FAILURE
, 0,
1455 _("%s: no size information for this device"), device_name
);
1459 wrapf (fancy
? "rows %d; columns %d;" : "%d %d\n",
1460 win
.ws_row
, win
.ws_col
);
1468 screen_columns (void)
1473 /* With Solaris 2.[123], this ioctl fails and errno is set to
1474 EINVAL for telnet (but not rlogin) sessions.
1475 On ISC 3.0, it fails for the console and the serial port
1476 (but it works for ptys).
1477 It can also fail on any system when stdout isn't a tty.
1478 In case of any failure, just use the default. */
1479 if (get_win_size (STDOUT_FILENO
, &win
) == 0 && 0 < win
.ws_col
)
1483 /* Use $COLUMNS if it's in [1..INT_MAX-1]. */
1484 char *col_string
= getenv ("COLUMNS");
1486 if (!(col_string
!= NULL
1487 && xstrtol (col_string
, NULL
, 0, &n_columns
, "") == LONGINT_OK
1489 && n_columns
< INT_MAX
))
1496 mode_type_flag (enum mode_type type
, struct termios
*mode
)
1501 return &mode
->c_cflag
;
1504 return &mode
->c_iflag
;
1507 return &mode
->c_oflag
;
1510 return &mode
->c_lflag
;
1521 display_settings (enum output_type output_type
, struct termios
*mode
,
1522 int fd
, const char *device_name
)
1524 switch (output_type
)
1527 display_changed (mode
);
1531 display_all (mode
, fd
, device_name
);
1535 display_recoverable (mode
);
1541 display_changed (struct termios
*mode
)
1547 enum mode_type prev_type
= control
;
1549 display_speed (mode
, 1);
1551 wrapf ("line = %d;", mode
->c_line
);
1557 for (i
= 0; !STREQ (control_info
[i
].name
, "min"); ++i
)
1559 if (mode
->c_cc
[control_info
[i
].offset
] == control_info
[i
].saneval
)
1561 /* If swtch is the same as susp, don't print both. */
1563 if (STREQ (control_info
[i
].name
, "swtch"))
1566 /* If eof uses the same slot as min, only print whichever applies. */
1568 if ((mode
->c_lflag
& ICANON
) == 0
1569 && (STREQ (control_info
[i
].name
, "eof")
1570 || STREQ (control_info
[i
].name
, "eol")))
1575 wrapf ("%s = %s;", control_info
[i
].name
,
1576 visible (mode
->c_cc
[control_info
[i
].offset
]));
1578 if ((mode
->c_lflag
& ICANON
) == 0)
1580 wrapf ("min = %d; time = %d;\n", (int) mode
->c_cc
[VMIN
],
1581 (int) mode
->c_cc
[VTIME
]);
1583 else if (empty_line
== 0)
1588 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1590 if (mode_info
[i
].flags
& OMIT
)
1592 if (mode_info
[i
].type
!= prev_type
)
1594 if (empty_line
== 0)
1600 prev_type
= mode_info
[i
].type
;
1603 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1604 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1605 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1607 if (mode_info
[i
].flags
& SANE_UNSET
)
1609 wrapf ("%s", mode_info
[i
].name
);
1613 else if ((mode_info
[i
].flags
& (SANE_SET
| REV
)) == (SANE_SET
| REV
))
1615 wrapf ("-%s", mode_info
[i
].name
);
1619 if (empty_line
== 0)
1625 display_all (struct termios
*mode
, int fd
, const char *device_name
)
1630 enum mode_type prev_type
= control
;
1632 display_speed (mode
, 1);
1634 display_window_size (1, fd
, device_name
);
1637 wrapf ("line = %d;", mode
->c_line
);
1642 for (i
= 0; ! STREQ (control_info
[i
].name
, "min"); ++i
)
1644 /* If swtch is the same as susp, don't print both. */
1646 if (STREQ (control_info
[i
].name
, "swtch"))
1649 /* If eof uses the same slot as min, only print whichever applies. */
1651 if ((mode
->c_lflag
& ICANON
) == 0
1652 && (STREQ (control_info
[i
].name
, "eof")
1653 || STREQ (control_info
[i
].name
, "eol")))
1656 wrapf ("%s = %s;", control_info
[i
].name
,
1657 visible (mode
->c_cc
[control_info
[i
].offset
]));
1660 if ((mode
->c_lflag
& ICANON
) == 0)
1662 wrapf ("min = %d; time = %d;", mode
->c_cc
[VMIN
], mode
->c_cc
[VTIME
]);
1663 if (current_col
!= 0)
1667 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1669 if (mode_info
[i
].flags
& OMIT
)
1671 if (mode_info
[i
].type
!= prev_type
)
1675 prev_type
= mode_info
[i
].type
;
1678 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1679 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1680 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1681 wrapf ("%s", mode_info
[i
].name
);
1682 else if (mode_info
[i
].flags
& REV
)
1683 wrapf ("-%s", mode_info
[i
].name
);
1690 display_speed (struct termios
*mode
, int fancy
)
1692 if (cfgetispeed (mode
) == 0 || cfgetispeed (mode
) == cfgetospeed (mode
))
1693 wrapf (fancy
? "speed %lu baud;" : "%lu\n",
1694 baud_to_value (cfgetospeed (mode
)));
1696 wrapf (fancy
? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n",
1697 baud_to_value (cfgetispeed (mode
)),
1698 baud_to_value (cfgetospeed (mode
)));
1704 display_recoverable (struct termios
*mode
)
1708 printf ("%lx:%lx:%lx:%lx",
1709 (unsigned long) mode
->c_iflag
, (unsigned long) mode
->c_oflag
,
1710 (unsigned long) mode
->c_cflag
, (unsigned long) mode
->c_lflag
);
1711 for (i
= 0; i
< NCCS
; ++i
)
1712 printf (":%x", (unsigned int) mode
->c_cc
[i
]);
1717 recover_mode (char *arg
, struct termios
*mode
)
1721 unsigned long iflag
, oflag
, cflag
, lflag
;
1723 /* Scan into temporaries since it is too much trouble to figure out
1724 the right format for `tcflag_t'. */
1725 if (sscanf (arg
, "%lx:%lx:%lx:%lx%n",
1726 &iflag
, &oflag
, &cflag
, &lflag
, &n
) != 4)
1728 mode
->c_iflag
= iflag
;
1729 mode
->c_oflag
= oflag
;
1730 mode
->c_cflag
= cflag
;
1731 mode
->c_lflag
= lflag
;
1733 for (i
= 0; i
< NCCS
; ++i
)
1735 if (sscanf (arg
, ":%x%n", &chr
, &n
) != 1)
1737 mode
->c_cc
[i
] = chr
;
1741 /* Fail if there are too many fields. */
1750 const char *string
; /* ASCII representation. */
1751 speed_t speed
; /* Internal form. */
1752 unsigned long value
; /* Numeric value. */
1755 struct speed_map speeds
[] =
1762 {"134.5", B134
, 134},
1767 {"1200", B1200
, 1200},
1768 {"1800", B1800
, 1800},
1769 {"2400", B2400
, 2400},
1770 {"4800", B4800
, 4800},
1771 {"9600", B9600
, 9600},
1772 {"19200", B19200
, 19200},
1773 {"38400", B38400
, 38400},
1774 {"exta", B19200
, 19200},
1775 {"extb", B38400
, 38400},
1777 {"57600", B57600
, 57600},
1780 {"115200", B115200
, 115200},
1783 {"230400", B230400
, 230400},
1786 {"460800", B460800
, 460800},
1789 {"500000", B500000
, 500000},
1792 {"576000", B576000
, 576000},
1795 {"921600", B921600
, 921600},
1798 {"1000000", B1000000
, 1000000},
1801 {"1152000", B1152000
, 1152000},
1804 {"1500000", B1500000
, 1500000},
1807 {"2000000", B2000000
, 2000000},
1810 {"2500000", B2500000
, 2500000},
1813 {"3000000", B3000000
, 3000000},
1816 {"3500000", B3500000
, 3500000},
1819 {"4000000", B4000000
, 4000000},
1825 string_to_baud (const char *arg
)
1829 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1830 if (STREQ (arg
, speeds
[i
].string
))
1831 return speeds
[i
].speed
;
1832 return (speed_t
) -1;
1835 static unsigned long
1836 baud_to_value (speed_t speed
)
1840 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1841 if (speed
== speeds
[i
].speed
)
1842 return speeds
[i
].value
;
1847 sane_mode (struct termios
*mode
)
1852 for (i
= 0; control_info
[i
].name
; ++i
)
1855 if (STREQ (control_info
[i
].name
, "min"))
1858 mode
->c_cc
[control_info
[i
].offset
] = control_info
[i
].saneval
;
1861 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1863 if (mode_info
[i
].flags
& SANE_SET
)
1865 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1866 *bitsp
= (*bitsp
& ~mode_info
[i
].mask
) | mode_info
[i
].bits
;
1868 else if (mode_info
[i
].flags
& SANE_UNSET
)
1870 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1871 *bitsp
= *bitsp
& ~mode_info
[i
].mask
& ~mode_info
[i
].bits
;
1876 /* Return a string that is the printable representation of character CH. */
1877 /* Adapted from `cat' by Torbjorn Granlund. */
1880 visible (unsigned int ch
)
1882 static char buf
[10];
1885 if (ch
== _POSIX_VDISABLE
)
1904 *bpout
++ = ch
- 128;
1914 *bpout
++ = ch
- 128 + 64;
1924 return (const char *) buf
;
1927 /* Parse string S as an integer, using decimal radix by default,
1928 but allowing octal and hex numbers as in C. */
1929 /* From `od' by Richard Stallman. */
1932 integer_arg (const char *s
)
1935 if (xstrtol (s
, NULL
, 0, &value
, "bB") != LONGINT_OK
)
1937 error (0, 0, _("invalid integer argument `%s'"), s
);
1938 usage (EXIT_FAILURE
);