1 /* stty -- change and print terminal line settings
2 Copyright (C) 1990-2002 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"
69 /* The official name of this program (e.g., no `g' prefix). */
70 #define PROGRAM_NAME "stty"
72 #define AUTHORS "David MacKenzie"
74 #ifndef _POSIX_VDISABLE
75 # define _POSIX_VDISABLE ((unsigned char) 0)
78 #define Control(c) ((c) & 0x1f)
79 /* Canonical values for control characters. */
81 # define CINTR Control ('c')
90 # define CKILL Control ('u')
93 # define CEOF Control ('d')
96 # define CEOL _POSIX_VDISABLE
99 # define CSTART Control ('q')
102 # define CSTOP Control ('s')
105 # define CSUSP Control ('z')
107 #if defined(VEOL2) && !defined(CEOL2)
108 # define CEOL2 _POSIX_VDISABLE
110 /* ISC renamed swtch to susp for termios, but we'll accept either name. */
111 #if defined(VSUSP) && !defined(VSWTCH)
112 # define VSWTCH VSUSP
113 # define CSWTCH CSUSP
115 #if defined(VSWTCH) && !defined(CSWTCH)
116 # define CSWTCH _POSIX_VDISABLE
119 /* SunOS 5.3 loses (^Z doesn't work) if `swtch' is the same as `susp'.
120 So the default is to disable `swtch.' */
121 #if defined (__sparc__) && defined (__svr4__)
123 # define CSWTCH _POSIX_VDISABLE
126 #if defined(VWERSE) && !defined (VWERASE) /* AIX-3.2.5 */
127 # define VWERASE VWERSE
129 #if defined(VDSUSP) && !defined (CDSUSP)
130 # define CDSUSP Control ('y')
132 #if !defined(VREPRINT) && defined(VRPRNT) /* Irix 4.0.5 */
133 # define VREPRINT VRPRNT
135 #if defined(VREPRINT) && !defined(CRPRNT)
136 # define CRPRNT Control ('r')
138 #if defined(CREPRINT) && !defined(CRPRNT)
139 # define CRPRNT Control ('r')
141 #if defined(VWERASE) && !defined(CWERASE)
142 # define CWERASE Control ('w')
144 #if defined(VLNEXT) && !defined(CLNEXT)
145 # define CLNEXT Control ('v')
147 #if defined(VDISCARD) && !defined(VFLUSHO)
148 # define VFLUSHO VDISCARD
150 #if defined(VFLUSH) && !defined(VFLUSHO) /* Ultrix 4.2 */
151 # define VFLUSHO VFLUSH
153 #if defined(CTLECH) && !defined(ECHOCTL) /* Ultrix 4.3 */
154 # define ECHOCTL CTLECH
156 #if defined(TCTLECH) && !defined(ECHOCTL) /* Ultrix 4.2 */
157 # define ECHOCTL TCTLECH
159 #if defined(CRTKIL) && !defined(ECHOKE) /* Ultrix 4.2 and 4.3 */
160 # define ECHOKE CRTKIL
162 #if defined(VFLUSHO) && !defined(CFLUSHO)
163 # define CFLUSHO Control ('o')
165 #if defined(VSTATUS) && !defined(CSTATUS)
166 # define CSTATUS Control ('t')
169 /* Which speeds to set. */
172 input_speed
, output_speed
, both_speeds
175 /* What to output and how. */
178 changed
, all
, recoverable
/* Default, -a, -g. */
181 /* Which member(s) of `struct termios' a mode uses. */
184 control
, input
, output
, local
, combination
187 /* Flags for `struct mode_info'. */
188 #define SANE_SET 1 /* Set in `sane' mode. */
189 #define SANE_UNSET 2 /* Unset in `sane' mode. */
190 #define REV 4 /* Can be turned off by prepending `-'. */
191 #define OMIT 8 /* Don't display value. */
196 const char *name
; /* Name given on command line. */
197 enum mode_type type
; /* Which structure element to change. */
198 char flags
; /* Setting and display options. */
199 unsigned long bits
; /* Bits to set for this mode. */
200 unsigned long mask
; /* Other bits to turn off for this mode. */
203 static struct mode_info mode_info
[] =
205 {"parenb", control
, REV
, PARENB
, 0},
206 {"parodd", control
, REV
, PARODD
, 0},
207 {"cs5", control
, 0, CS5
, CSIZE
},
208 {"cs6", control
, 0, CS6
, CSIZE
},
209 {"cs7", control
, 0, CS7
, CSIZE
},
210 {"cs8", control
, 0, CS8
, CSIZE
},
211 {"hupcl", control
, REV
, HUPCL
, 0},
212 {"hup", control
, REV
| OMIT
, HUPCL
, 0},
213 {"cstopb", control
, REV
, CSTOPB
, 0},
214 {"cread", control
, SANE_SET
| REV
, CREAD
, 0},
215 {"clocal", control
, REV
, CLOCAL
, 0},
217 {"crtscts", control
, REV
, CRTSCTS
, 0},
220 {"ignbrk", input
, SANE_UNSET
| REV
, IGNBRK
, 0},
221 {"brkint", input
, SANE_SET
| REV
, BRKINT
, 0},
222 {"ignpar", input
, REV
, IGNPAR
, 0},
223 {"parmrk", input
, REV
, PARMRK
, 0},
224 {"inpck", input
, REV
, INPCK
, 0},
225 {"istrip", input
, REV
, ISTRIP
, 0},
226 {"inlcr", input
, SANE_UNSET
| REV
, INLCR
, 0},
227 {"igncr", input
, SANE_UNSET
| REV
, IGNCR
, 0},
228 {"icrnl", input
, SANE_SET
| REV
, ICRNL
, 0},
229 {"ixon", input
, REV
, IXON
, 0},
230 {"ixoff", input
, SANE_UNSET
| REV
, IXOFF
, 0},
231 {"tandem", input
, REV
| OMIT
, IXOFF
, 0},
233 {"iuclc", input
, SANE_UNSET
| REV
, IUCLC
, 0},
236 {"ixany", input
, SANE_UNSET
| REV
, IXANY
, 0},
239 {"imaxbel", input
, SANE_SET
| REV
, IMAXBEL
, 0},
242 {"opost", output
, SANE_SET
| REV
, OPOST
, 0},
244 {"olcuc", output
, SANE_UNSET
| REV
, OLCUC
, 0},
247 {"ocrnl", output
, SANE_UNSET
| REV
, OCRNL
, 0},
250 {"onlcr", output
, SANE_SET
| REV
, ONLCR
, 0},
253 {"onocr", output
, SANE_UNSET
| REV
, ONOCR
, 0},
256 {"onlret", output
, SANE_UNSET
| REV
, ONLRET
, 0},
259 {"ofill", output
, SANE_UNSET
| REV
, OFILL
, 0},
262 {"ofdel", output
, SANE_UNSET
| REV
, OFDEL
, 0},
265 {"nl1", output
, SANE_UNSET
, NL1
, NLDLY
},
266 {"nl0", output
, SANE_SET
, NL0
, NLDLY
},
269 {"cr3", output
, SANE_UNSET
, CR3
, CRDLY
},
270 {"cr2", output
, SANE_UNSET
, CR2
, CRDLY
},
271 {"cr1", output
, SANE_UNSET
, CR1
, CRDLY
},
272 {"cr0", output
, SANE_SET
, CR0
, CRDLY
},
275 {"tab3", output
, SANE_UNSET
, TAB3
, TABDLY
},
276 {"tab2", output
, SANE_UNSET
, TAB2
, TABDLY
},
277 {"tab1", output
, SANE_UNSET
, TAB1
, TABDLY
},
278 {"tab0", output
, SANE_SET
, TAB0
, TABDLY
},
281 {"tab3", output
, SANE_UNSET
, OXTABS
, 0},
285 {"bs1", output
, SANE_UNSET
, BS1
, BSDLY
},
286 {"bs0", output
, SANE_SET
, BS0
, BSDLY
},
289 {"vt1", output
, SANE_UNSET
, VT1
, VTDLY
},
290 {"vt0", output
, SANE_SET
, VT0
, VTDLY
},
293 {"ff1", output
, SANE_UNSET
, FF1
, FFDLY
},
294 {"ff0", output
, SANE_SET
, FF0
, FFDLY
},
297 {"isig", local
, SANE_SET
| REV
, ISIG
, 0},
298 {"icanon", local
, SANE_SET
| REV
, ICANON
, 0},
300 {"iexten", local
, SANE_SET
| REV
, IEXTEN
, 0},
302 {"echo", local
, SANE_SET
| REV
, ECHO
, 0},
303 {"echoe", local
, SANE_SET
| REV
, ECHOE
, 0},
304 {"crterase", local
, REV
| OMIT
, ECHOE
, 0},
305 {"echok", local
, SANE_SET
| REV
, ECHOK
, 0},
306 {"echonl", local
, SANE_UNSET
| REV
, ECHONL
, 0},
307 {"noflsh", local
, SANE_UNSET
| REV
, NOFLSH
, 0},
309 {"xcase", local
, SANE_UNSET
| REV
, XCASE
, 0},
312 {"tostop", local
, SANE_UNSET
| REV
, TOSTOP
, 0},
315 {"echoprt", local
, SANE_UNSET
| REV
, ECHOPRT
, 0},
316 {"prterase", local
, REV
| OMIT
, ECHOPRT
, 0},
319 {"echoctl", local
, SANE_SET
| REV
, ECHOCTL
, 0},
320 {"ctlecho", local
, REV
| OMIT
, ECHOCTL
, 0},
323 {"echoke", local
, SANE_SET
| REV
, ECHOKE
, 0},
324 {"crtkill", local
, REV
| OMIT
, ECHOKE
, 0},
327 {"evenp", combination
, REV
| OMIT
, 0, 0},
328 {"parity", combination
, REV
| OMIT
, 0, 0},
329 {"oddp", combination
, REV
| OMIT
, 0, 0},
330 {"nl", combination
, REV
| OMIT
, 0, 0},
331 {"ek", combination
, OMIT
, 0, 0},
332 {"sane", combination
, OMIT
, 0, 0},
333 {"cooked", combination
, REV
| OMIT
, 0, 0},
334 {"raw", combination
, REV
| OMIT
, 0, 0},
335 {"pass8", combination
, REV
| OMIT
, 0, 0},
336 {"litout", combination
, REV
| OMIT
, 0, 0},
337 {"cbreak", combination
, REV
| OMIT
, 0, 0},
339 {"decctlq", combination
, REV
| OMIT
, 0, 0},
341 #if defined (TABDLY) || defined (OXTABS)
342 {"tabs", combination
, REV
| OMIT
, 0, 0},
344 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
345 {"lcase", combination
, REV
| OMIT
, 0, 0},
346 {"LCASE", combination
, REV
| OMIT
, 0, 0},
348 {"crt", combination
, OMIT
, 0, 0},
349 {"dec", combination
, OMIT
, 0, 0},
351 {NULL
, control
, 0, 0, 0}
354 /* Control character settings. */
357 const char *name
; /* Name given on command line. */
358 unsigned char saneval
; /* Value to set for `stty sane'. */
359 int offset
; /* Offset in c_cc. */
362 /* Control characters. */
364 static struct control_info control_info
[] =
366 {"intr", CINTR
, VINTR
},
367 {"quit", CQUIT
, VQUIT
},
368 {"erase", CERASE
, VERASE
},
369 {"kill", CKILL
, VKILL
},
373 {"eol2", CEOL2
, VEOL2
},
376 {"swtch", CSWTCH
, VSWTCH
},
378 {"start", CSTART
, VSTART
},
379 {"stop", CSTOP
, VSTOP
},
380 {"susp", CSUSP
, VSUSP
},
382 {"dsusp", CDSUSP
, VDSUSP
},
385 {"rprnt", CRPRNT
, VREPRINT
},
387 # ifdef CREPRINT /* HPUX 10.20 needs this */
388 {"rprnt", CRPRNT
, CREPRINT
},
392 {"werase", CWERASE
, VWERASE
},
395 {"lnext", CLNEXT
, VLNEXT
},
398 {"flush", CFLUSHO
, VFLUSHO
},
401 {"status", CSTATUS
, VSTATUS
},
404 /* These must be last because of the display routines. */
410 static const char *visible (unsigned int ch
);
411 static unsigned long baud_to_value (speed_t speed
);
412 static int recover_mode (char *arg
, struct termios
*mode
);
413 static int screen_columns (void);
414 static int set_mode (struct mode_info
*info
, int reversed
,
415 struct termios
*mode
);
416 static long integer_arg (const char *s
);
417 static speed_t
string_to_baud (const char *arg
);
418 static tcflag_t
*mode_type_flag (enum mode_type type
, struct termios
*mode
);
419 static void display_all (struct termios
*mode
, int fd
, const char *device_name
);
420 static void display_changed (struct termios
*mode
);
421 static void display_recoverable (struct termios
*mode
);
422 static void display_settings (enum output_type output_type
,
423 struct termios
*mode
, int fd
,
424 const char *device_name
);
425 static void display_speed (struct termios
*mode
, int fancy
);
426 static void display_window_size (int fancy
, int fd
, const char *device_name
);
427 static void sane_mode (struct termios
*mode
);
428 static void set_control_char (struct control_info
*info
,
430 struct termios
*mode
);
431 static void set_speed (enum speed_setting type
, const char *arg
,
432 struct termios
*mode
);
433 static void set_window_size (int rows
, int cols
, int fd
,
434 const char *device_name
);
436 /* The width of the screen, for output wrapping. */
439 /* Current position, to know when to wrap. */
440 static int current_col
;
442 static struct option longopts
[] =
444 {"all", no_argument
, NULL
, 'a'},
445 {"save", no_argument
, NULL
, 'g'},
446 {"file", required_argument
, NULL
, 'F'},
450 /* The name this program was run with. */
453 /* Print format string MESSAGE and optional args.
454 Wrap to next line first if it won't fit.
455 Print a space first unless MESSAGE will start a new line. */
460 wrapf (const char *message
,...)
462 wrapf (message
, va_alist
)
468 char buf
[1024]; /* Plenty long for our needs. */
471 VA_START (args
, message
);
472 vsprintf (buf
, message
, args
);
474 buflen
= strlen (buf
);
476 && max_col
<= current_col
+ (0 < current_col
) + buflen
)
487 current_col
+= buflen
;
494 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
499 Usage: %s [-F DEVICE] [--file=DEVICE] [SETTING]...\n\
500 or: %s [-F DEVICE] [--file=DEVICE] [-a|--all]\n\
501 or: %s [-F DEVICE] [--file=DEVICE] [-g|--save]\n\
503 program_name
, program_name
, program_name
);
505 Print or change terminal characteristics.\n\
507 -a, --all print all current settings in human-readable form\n\
508 -g, --save print all current settings in a stty-readable form\n\
509 -F, --file=DEVICE open and use the specified DEVICE instead of stdin\n\
511 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
512 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
515 Optional - before SETTING indicates negation. An * marks non-POSIX\n\
516 settings. The underlying system defines which settings are available.\n\
520 Special characters:\n\
521 * dsusp CHAR CHAR will send a terminal stop signal once input flushed\n\
522 eof CHAR CHAR will send an end of file (terminate the input)\n\
523 eol CHAR CHAR will end the line\n\
526 * eol2 CHAR alternate CHAR for ending the line\n\
527 erase CHAR CHAR will erase the last character typed\n\
528 intr CHAR CHAR will send an interrupt signal\n\
529 kill CHAR CHAR will erase the current line\n\
532 * lnext CHAR CHAR will enter the next character quoted\n\
533 quit CHAR CHAR will send a quit signal\n\
534 * rprnt CHAR CHAR will redraw the current line\n\
535 start CHAR CHAR will restart the output after stopping it\n\
538 stop CHAR CHAR will stop the output\n\
539 susp CHAR CHAR will send a terminal stop signal\n\
540 * swtch CHAR CHAR will switch to a different shell layer\n\
541 * werase CHAR CHAR will erase the last word typed\n\
546 N set the input and output speeds to N bauds\n\
547 * cols N tell the kernel that the terminal has N columns\n\
548 * columns N same as cols N\n\
551 ispeed N set the input speed to N\n\
552 * line N use line discipline N\n\
553 min N with -icanon, set N characters minimum for a completed read\n\
554 ospeed N set the output speed to N\n\
557 * rows N tell the kernel that the terminal has N rows\n\
558 * size print the number of rows and columns according to the kernel\n\
559 speed print the terminal speed\n\
560 time N with -icanon, set read timeout of N tenths of a second\n\
565 [-]clocal disable modem control signals\n\
566 [-]cread allow input to be received\n\
567 * [-]crtscts enable RTS/CTS handshaking\n\
568 csN set character size to N bits, N in [5..8]\n\
571 [-]cstopb use two stop bits per character (one with `-')\n\
572 [-]hup send a hangup signal when the last process closes the tty\n\
573 [-]hupcl same as [-]hup\n\
574 [-]parenb generate parity bit in output and expect parity bit in input\n\
575 [-]parodd set odd parity (even with `-')\n\
580 [-]brkint breaks cause an interrupt signal\n\
581 [-]icrnl translate carriage return to newline\n\
582 [-]ignbrk ignore break characters\n\
583 [-]igncr ignore carriage return\n\
586 [-]ignpar ignore characters with parity errors\n\
587 * [-]imaxbel beep and do not flush a full input buffer on a character\n\
588 [-]inlcr translate newline to carriage return\n\
589 [-]inpck enable input parity checking\n\
590 [-]istrip clear high (8th) bit of input characters\n\
593 * [-]iuclc translate uppercase characters to lowercase\n\
594 * [-]ixany let any character restart output, not only start character\n\
595 [-]ixoff enable sending of start/stop characters\n\
596 [-]ixon enable XON/XOFF flow control\n\
597 [-]parmrk mark parity errors (with a 255-0-character sequence)\n\
598 [-]tandem same as [-]ixoff\n\
603 * bsN backspace delay style, N in [0..1]\n\
604 * crN carriage return delay style, N in [0..3]\n\
605 * ffN form feed delay style, N in [0..1]\n\
606 * nlN newline delay style, N in [0..1]\n\
609 * [-]ocrnl translate carriage return to newline\n\
610 * [-]ofdel use delete characters for fill instead of null characters\n\
611 * [-]ofill use fill (padding) characters instead of timing for delays\n\
612 * [-]olcuc translate lowercase characters to uppercase\n\
613 * [-]onlcr translate newline to carriage return-newline\n\
614 * [-]onlret newline performs a carriage return\n\
617 * [-]onocr do not print carriage returns in the first column\n\
618 [-]opost postprocess output\n\
619 * tabN horizontal tab delay style, N in [0..3]\n\
620 * tabs same as tab0\n\
621 * -tabs same as tab3\n\
622 * vtN vertical tab delay style, N in [0..1]\n\
627 [-]crterase echo erase characters as backspace-space-backspace\n\
628 * crtkill kill all line by obeying the echoprt and echoe settings\n\
629 * -crtkill kill all line by obeying the echoctl and echok settings\n\
632 * [-]ctlecho echo control characters in hat notation (`^c')\n\
633 [-]echo echo input characters\n\
634 * [-]echoctl same as [-]ctlecho\n\
635 [-]echoe same as [-]crterase\n\
636 [-]echok echo a newline after a kill character\n\
639 * [-]echoke same as [-]crtkill\n\
640 [-]echonl echo newline even if not echoing other characters\n\
641 * [-]echoprt echo erased characters backward, between `\\' and '/'\n\
642 [-]icanon enable erase, kill, werase, and rprnt special characters\n\
643 [-]iexten enable non-POSIX special characters\n\
646 [-]isig enable interrupt, quit, and suspend special characters\n\
647 [-]noflsh disable flushing after interrupt and quit special characters\n\
648 * [-]prterase same as [-]echoprt\n\
649 * [-]tostop stop background jobs that try to write to the terminal\n\
650 * [-]xcase with icanon, escape with `\\' for uppercase characters\n\
654 Combination settings:\n\
655 * [-]LCASE same as [-]lcase\n\
656 cbreak same as -icanon\n\
657 -cbreak same as icanon\n\
660 cooked same as brkint ignpar istrip icrnl ixon opost isig\n\
661 icanon, eof and eol characters to their default values\n\
662 -cooked same as raw\n\
663 crt same as echoe echoctl echoke\n\
666 dec same as echoe echoctl echoke -ixany intr ^c erase 0177\n\
668 * [-]decctlq same as [-]ixany\n\
669 ek erase and kill characters to their default values\n\
670 evenp same as parenb -parodd cs7\n\
673 -evenp same as -parenb cs8\n\
674 * [-]lcase same as xcase iuclc olcuc\n\
675 litout same as -parenb -istrip -opost cs8\n\
676 -litout same as parenb istrip opost cs7\n\
677 nl same as -icrnl -onlcr\n\
678 -nl same as icrnl -inlcr -igncr onlcr -ocrnl -onlret\n\
681 oddp same as parenb parodd cs7\n\
682 -oddp same as -parenb cs8\n\
683 [-]parity same as [-]evenp\n\
684 pass8 same as -parenb -istrip cs8\n\
685 -pass8 same as parenb istrip cs7\n\
688 raw same as -ignbrk -brkint -ignpar -parmrk -inpck -istrip\n\
689 -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany\n\
690 -imaxbel -opost -isig -icanon -xcase min 1 time 0\n\
691 -raw same as cooked\n\
694 sane same as cread -ignbrk brkint -inlcr -igncr icrnl\n\
695 -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr\n\
696 -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0\n\
697 isig icanon iexten echo echoe echok -echonl -noflsh\n\
698 -xcase -tostop -echoprt echoctl echoke, all special\n\
699 characters to their default values.\n\
703 Handle the tty line connected to standard input. Without arguments,\n\
704 prints baud rate, line discipline, and deviations from stty sane. In\n\
705 settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
706 127; special values ^- or undef used to disable special characters.\n\
708 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
713 /* Return 1 if the string contains only valid options. */
715 valid_options (char *opt
, const char *valid_opts
,
716 const char *valid_arg_opts
)
720 if (*opt
++ != '-' || *opt
== 0)
726 if (strchr (valid_opts
, ch
))
728 if (strchr (valid_arg_opts
, ch
))
736 main (int argc
, char **argv
)
739 enum output_type output_type
;
741 int require_set_attr
;
744 int recoverable_output
;
747 char *file_name
= NULL
;
749 const char *device_name
;
750 const char *posixly_correct
= getenv ("POSIXLY_CORRECT");
751 int invalid_long_option
= 0;
753 program_name
= argv
[0];
754 setlocale (LC_ALL
, "");
755 bindtextdomain (PACKAGE
, LOCALEDIR
);
756 textdomain (PACKAGE
);
758 atexit (close_stdout
);
760 parse_long_options (argc
, argv
, PROGRAM_NAME
, GNU_PACKAGE
, VERSION
,
763 output_type
= changed
;
765 recoverable_output
= 0;
767 /* Don't print error messages for unrecognized options. */
770 while ((optc
= getopt_long (argc
, argv
, "agF:", longopts
, NULL
)) != -1)
772 int unrecognized_option
= 0;
781 recoverable_output
= 1;
782 output_type
= recoverable
;
787 error (2, 0, _("only one device may be specified"));
792 unrecognized_option
= 1;
796 if (unrecognized_option
)
800 /* FIXME: what is this?!? */
801 if (invalid_long_option
)
802 usage (EXIT_FAILURE
);
804 /* Clear out the options that have been parsed. This is really
805 gross, but it's needed because stty SETTINGS look like options to
806 getopt(), so we need to work around things in a really horrible
807 way. If any new options are ever added to stty, the short option
808 MUST NOT be a letter which is the first letter of one of the
809 possible stty settings. If you change anything about how stty
810 parses options, be sure it still works with combinations of
811 short and long options, --, POSIXLY_CORRECT, etc. */
812 for (k
= 1; k
< argc
; k
++)
820 /* Handle --, and reset noargs if there are arguments following it. */
821 if (STREQ (argv
[k
], "--"))
829 /* Handle "--file device" */
830 len
= strlen (argv
[k
]);
831 if (len
>= 3 && strstr ("--file", argv
[k
]))
838 /* Handle "--all" and "--save". */
840 && (strstr ("--all", argv
[k
])
841 || strstr ("--save", argv
[k
])))
847 /* Handle "--file=device". */
848 eq
= strchr (argv
[k
], '=');
849 if (eq
&& eq
- argv
[k
] >= 3)
852 if (strstr ("--file", argv
[k
]))
857 /* Put the equals sign back for the error message. */
861 /* Handle "-a", "-ag", "-aF/dev/foo", "-aF /dev/foo", etc. */
862 if (valid_options (argv
[k
], "ag", "F"))
864 /* FIXME: this loses when the device name ends in `F'.
865 e.g. `stty -F/dev/BARF nl' would clobber the `nl' argument. */
866 if (argv
[k
][strlen (argv
[k
]) - 1] == 'F')
870 /* Everything else must be a normal, non-option argument. */
879 /* Specifying both -a and -g gets an error. */
880 if (verbose_output
&& recoverable_output
)
882 _("the options for verbose and stty-readable output styles are\n\
883 mutually exclusive"));
885 /* Specifying any other arguments with -a or -g gets an error. */
886 if (!noargs
&& (verbose_output
|| recoverable_output
))
887 error (2, 0, _("when specifying an output style, modes may not be set"));
889 /* FIXME: it'd be better not to open the file until we've verified
890 that all arguments are valid. Otherwise, we could end up doing
891 only some of the requested operations and then failing, probably
892 leaving things in an undesirable state. */
897 device_name
= file_name
;
898 fd
= open (device_name
, O_RDONLY
| O_NONBLOCK
);
900 error (EXIT_FAILURE
, errno
, "%s", device_name
);
901 if ((fdflags
= fcntl (fd
, F_GETFL
)) == -1
902 || fcntl (fd
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
903 error (EXIT_FAILURE
, errno
, _("%s: couldn't reset non-blocking mode"),
909 device_name
= _("standard input");
912 /* Initialize to all zeroes so there is no risk memcmp will report a
913 spurious difference in an uninitialized portion of the structure. */
914 memset (&mode
, 0, sizeof (mode
));
915 if (tcgetattr (fd
, &mode
))
916 error (EXIT_FAILURE
, errno
, "%s", device_name
);
918 if (verbose_output
|| recoverable_output
|| noargs
)
920 max_col
= screen_columns ();
922 display_settings (output_type
, &mode
, fd
, device_name
);
927 require_set_attr
= 0;
941 if (argv
[k
][0] == '-')
946 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
948 if (STREQ (argv
[k
], mode_info
[i
].name
))
950 match_found
= set_mode (&mode_info
[i
], reversed
, &mode
);
951 require_set_attr
= 1;
955 if (match_found
== 0 && reversed
)
957 error (0, 0, _("invalid argument `%s'"), --argv
[k
]);
958 usage (EXIT_FAILURE
);
960 if (match_found
== 0)
962 for (i
= 0; control_info
[i
].name
!= NULL
; ++i
)
964 if (STREQ (argv
[k
], control_info
[i
].name
))
968 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
969 usage (EXIT_FAILURE
);
973 set_control_char (&control_info
[i
], argv
[k
], &mode
);
974 require_set_attr
= 1;
979 if (match_found
== 0)
981 if (STREQ (argv
[k
], "ispeed"))
985 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
986 usage (EXIT_FAILURE
);
989 set_speed (input_speed
, argv
[k
], &mode
);
991 require_set_attr
= 1;
993 else if (STREQ (argv
[k
], "ospeed"))
997 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
998 usage (EXIT_FAILURE
);
1001 set_speed (output_speed
, argv
[k
], &mode
);
1003 require_set_attr
= 1;
1006 else if (STREQ (argv
[k
], "rows"))
1010 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1011 usage (EXIT_FAILURE
);
1014 set_window_size ((int) integer_arg (argv
[k
]), -1,
1017 else if (STREQ (argv
[k
], "cols")
1018 || STREQ (argv
[k
], "columns"))
1022 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1023 usage (EXIT_FAILURE
);
1026 set_window_size (-1, (int) integer_arg (argv
[k
]),
1029 else if (STREQ (argv
[k
], "size"))
1031 max_col
= screen_columns ();
1033 display_window_size (0, fd
, device_name
);
1037 else if (STREQ (argv
[k
], "line"))
1041 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1042 usage (EXIT_FAILURE
);
1045 mode
.c_line
= integer_arg (argv
[k
]);
1046 require_set_attr
= 1;
1049 else if (STREQ (argv
[k
], "speed"))
1051 max_col
= screen_columns ();
1052 display_speed (&mode
, 0);
1054 else if (string_to_baud (argv
[k
]) != (speed_t
) -1)
1056 set_speed (both_speeds
, argv
[k
], &mode
);
1058 require_set_attr
= 1;
1062 if (recover_mode (argv
[k
], &mode
) == 0)
1064 error (0, 0, _("invalid argument `%s'"), argv
[k
]);
1065 usage (EXIT_FAILURE
);
1067 require_set_attr
= 1;
1073 if (require_set_attr
)
1075 struct termios new_mode
;
1077 if (tcsetattr (fd
, TCSADRAIN
, &mode
))
1078 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1080 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
1081 it performs *any* of the requested operations. This means it
1082 can report `success' when it has actually failed to perform
1083 some proper subset of the requested operations. To detect
1084 this partial failure, get the current terminal attributes and
1085 compare them to the requested ones. */
1087 /* Initialize to all zeroes so there is no risk memcmp will report a
1088 spurious difference in an uninitialized portion of the structure. */
1089 memset (&new_mode
, 0, sizeof (new_mode
));
1090 if (tcgetattr (fd
, &new_mode
))
1091 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1093 /* Normally, one shouldn't use memcmp to compare structures that
1094 may have `holes' containing uninitialized data, but we have been
1095 careful to initialize the storage of these two variables to all
1096 zeroes. One might think it more efficient simply to compare the
1097 modified fields, but that would require enumerating those fields --
1098 and not all systems have the same fields in this structure. */
1100 if (memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1103 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1104 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1105 sometimes (m1 != m2). The only difference is in the four bits
1106 of the c_cflag field corresponding to the baud rate. To save
1107 Sun users a little confusion, don't report an error if this
1108 happens. But suppress the error only if we haven't tried to
1109 set the baud rate explicitly -- otherwise we'd never give an
1110 error for a true failure to set the baud rate. */
1112 new_mode
.c_cflag
&= (~CIBAUD
);
1113 if (speed_was_set
|| memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1116 error (EXIT_FAILURE
, 0,
1117 _("%s: unable to perform all requested operations"),
1122 printf (_("new_mode: mode\n"));
1123 for (i
= 0; i
< sizeof (new_mode
); i
++)
1124 printf ("0x%02x: 0x%02x\n",
1125 *(((unsigned char *) &new_mode
) + i
),
1126 *(((unsigned char *) &mode
) + i
));
1133 exit (EXIT_SUCCESS
);
1136 /* Return 0 if not applied because not reversible; otherwise return 1. */
1139 set_mode (struct mode_info
*info
, int reversed
, struct termios
*mode
)
1143 if (reversed
&& (info
->flags
& REV
) == 0)
1146 bitsp
= mode_type_flag (info
->type
, mode
);
1150 /* Combination mode. */
1151 if (STREQ (info
->name
, "evenp") || STREQ (info
->name
, "parity"))
1154 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1156 mode
->c_cflag
= (mode
->c_cflag
& ~PARODD
& ~CSIZE
) | PARENB
| CS7
;
1158 else if (STREQ (info
->name
, "oddp"))
1161 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1163 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARODD
| PARENB
;
1165 else if (STREQ (info
->name
, "nl"))
1169 mode
->c_iflag
= (mode
->c_iflag
| ICRNL
) & ~INLCR
& ~IGNCR
;
1170 mode
->c_oflag
= (mode
->c_oflag
1185 mode
->c_iflag
= mode
->c_iflag
& ~ICRNL
;
1187 mode
->c_oflag
= mode
->c_oflag
& ~ONLCR
;
1191 else if (STREQ (info
->name
, "ek"))
1193 mode
->c_cc
[VERASE
] = CERASE
;
1194 mode
->c_cc
[VKILL
] = CKILL
;
1196 else if (STREQ (info
->name
, "sane"))
1198 else if (STREQ (info
->name
, "cbreak"))
1201 mode
->c_lflag
|= ICANON
;
1203 mode
->c_lflag
&= ~ICANON
;
1205 else if (STREQ (info
->name
, "pass8"))
1209 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1210 mode
->c_iflag
|= ISTRIP
;
1214 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1215 mode
->c_iflag
&= ~ISTRIP
;
1218 else if (STREQ (info
->name
, "litout"))
1222 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1223 mode
->c_iflag
|= ISTRIP
;
1224 mode
->c_oflag
|= OPOST
;
1228 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1229 mode
->c_iflag
&= ~ISTRIP
;
1230 mode
->c_oflag
&= ~OPOST
;
1233 else if (STREQ (info
->name
, "raw") || STREQ (info
->name
, "cooked"))
1235 if ((info
->name
[0] == 'r' && reversed
)
1236 || (info
->name
[0] == 'c' && !reversed
))
1239 mode
->c_iflag
|= BRKINT
| IGNPAR
| ISTRIP
| ICRNL
| IXON
;
1240 mode
->c_oflag
|= OPOST
;
1241 mode
->c_lflag
|= ISIG
| ICANON
;
1243 mode
->c_cc
[VEOF
] = CEOF
;
1246 mode
->c_cc
[VEOL
] = CEOL
;
1253 mode
->c_oflag
&= ~OPOST
;
1254 mode
->c_lflag
&= ~(ISIG
| ICANON
1259 mode
->c_cc
[VMIN
] = 1;
1260 mode
->c_cc
[VTIME
] = 0;
1264 else if (STREQ (info
->name
, "decctlq"))
1267 mode
->c_iflag
|= IXANY
;
1269 mode
->c_iflag
&= ~IXANY
;
1273 else if (STREQ (info
->name
, "tabs"))
1276 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB3
;
1278 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB0
;
1282 else if (STREQ (info
->name
, "tabs"))
1285 mode
->c_oflag
= mode
->c_oflag
| OXTABS
;
1287 mode
->c_oflag
= mode
->c_oflag
& ~OXTABS
;
1291 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
1292 else if (STREQ (info
->name
, "lcase")
1293 || STREQ (info
->name
, "LCASE"))
1297 mode
->c_lflag
&= ~XCASE
;
1298 mode
->c_iflag
&= ~IUCLC
;
1299 mode
->c_oflag
&= ~OLCUC
;
1303 mode
->c_lflag
|= XCASE
;
1304 mode
->c_iflag
|= IUCLC
;
1305 mode
->c_oflag
|= OLCUC
;
1309 else if (STREQ (info
->name
, "crt"))
1310 mode
->c_lflag
|= ECHOE
1318 else if (STREQ (info
->name
, "dec"))
1320 mode
->c_cc
[VINTR
] = 3; /* ^C */
1321 mode
->c_cc
[VERASE
] = 127; /* DEL */
1322 mode
->c_cc
[VKILL
] = 21; /* ^U */
1323 mode
->c_lflag
|= ECHOE
1332 mode
->c_iflag
&= ~IXANY
;
1337 *bitsp
= *bitsp
& ~info
->mask
& ~info
->bits
;
1339 *bitsp
= (*bitsp
& ~info
->mask
) | info
->bits
;
1345 set_control_char (struct control_info
*info
, const char *arg
,
1346 struct termios
*mode
)
1348 unsigned char value
;
1350 if (STREQ (info
->name
, "min") || STREQ (info
->name
, "time"))
1351 value
= integer_arg (arg
);
1352 else if (arg
[0] == '\0' || arg
[1] == '\0')
1354 else if (STREQ (arg
, "^-") || STREQ (arg
, "undef"))
1355 value
= _POSIX_VDISABLE
;
1356 else if (arg
[0] == '^' && arg
[1] != '\0') /* Ignore any trailing junk. */
1361 value
= arg
[1] & ~0140; /* Non-letters get weird results. */
1364 value
= integer_arg (arg
);
1365 mode
->c_cc
[info
->offset
] = value
;
1369 set_speed (enum speed_setting type
, const char *arg
, struct termios
*mode
)
1373 baud
= string_to_baud (arg
);
1374 if (type
== input_speed
|| type
== both_speeds
)
1375 cfsetispeed (mode
, baud
);
1376 if (type
== output_speed
|| type
== both_speeds
)
1377 cfsetospeed (mode
, baud
);
1383 get_win_size (int fd
, struct winsize
*win
)
1385 int err
= ioctl (fd
, TIOCGWINSZ
, (char *) win
);
1390 set_window_size (int rows
, int cols
, int fd
, const char *device_name
)
1394 if (get_win_size (fd
, &win
))
1396 if (errno
!= EINVAL
)
1397 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1398 memset (&win
, 0, sizeof (win
));
1407 /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote:
1408 The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.
1409 This comment from sys/ttold.h describes Sun's twisted logic - a better
1410 test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).
1411 At any rate, the problem is gone in Solaris 2.x.
1413 Unfortunately, the old TIOCSSIZE code does collide with TIOCSWINSZ,
1414 but they can be disambiguated by checking whether a "struct ttysize"
1415 structure's "ts_lines" field is greater than 64K or not. If so,
1416 it's almost certainly a "struct winsize" instead.
1418 At any rate, the bug manifests itself when ws_row == 0; the symptom is
1419 that ws_row is set to ws_col, and ws_col is set to (ws_xpixel<<16) +
1420 ws_ypixel. Since GNU stty sets rows and columns separately, this bug
1421 caused "stty rows 0 cols 0" to set rows to cols and cols to 0, while
1422 "stty cols 0 rows 0" would do the right thing. On a little-endian
1423 machine like the sun386i, the problem is the same, but for ws_col == 0.
1425 The workaround is to do the ioctl once with row and col = 1 to set the
1426 pixel info, and then do it again using a TIOCSSIZE to set rows/cols. */
1428 if (win
.ws_row
== 0 || win
.ws_col
== 0)
1430 struct ttysize ttysz
;
1432 ttysz
.ts_lines
= win
.ws_row
;
1433 ttysz
.ts_cols
= win
.ws_col
;
1438 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1439 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1441 if (ioctl (fd
, TIOCSSIZE
, (char *) &ttysz
))
1442 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1447 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1448 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1452 display_window_size (int fancy
, int fd
, const char *device_name
)
1456 if (get_win_size (fd
, &win
))
1458 if (errno
!= EINVAL
)
1459 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1461 error (EXIT_FAILURE
, 0,
1462 _("%s: no size information for this device"), device_name
);
1466 wrapf (fancy
? "rows %d; columns %d;" : "%d %d\n",
1467 win
.ws_row
, win
.ws_col
);
1475 screen_columns (void)
1480 /* With Solaris 2.[123], this ioctl fails and errno is set to
1481 EINVAL for telnet (but not rlogin) sessions.
1482 On ISC 3.0, it fails for the console and the serial port
1483 (but it works for ptys).
1484 It can also fail on any system when stdout isn't a tty.
1485 In case of any failure, just use the default. */
1486 if (get_win_size (STDOUT_FILENO
, &win
) == 0 && 0 < win
.ws_col
)
1490 /* Use $COLUMNS if it's in [1..INT_MAX-1]. */
1491 char *col_string
= getenv ("COLUMNS");
1493 if (!(col_string
!= NULL
1494 && xstrtol (col_string
, NULL
, 0, &n_columns
, "") == LONGINT_OK
1496 && n_columns
< INT_MAX
))
1503 mode_type_flag (enum mode_type type
, struct termios
*mode
)
1508 return &mode
->c_cflag
;
1511 return &mode
->c_iflag
;
1514 return &mode
->c_oflag
;
1517 return &mode
->c_lflag
;
1528 display_settings (enum output_type output_type
, struct termios
*mode
,
1529 int fd
, const char *device_name
)
1531 switch (output_type
)
1534 display_changed (mode
);
1538 display_all (mode
, fd
, device_name
);
1542 display_recoverable (mode
);
1548 display_changed (struct termios
*mode
)
1554 enum mode_type prev_type
= control
;
1556 display_speed (mode
, 1);
1558 wrapf ("line = %d;", mode
->c_line
);
1564 for (i
= 0; !STREQ (control_info
[i
].name
, "min"); ++i
)
1566 if (mode
->c_cc
[control_info
[i
].offset
] == control_info
[i
].saneval
)
1568 /* If swtch is the same as susp, don't print both. */
1570 if (STREQ (control_info
[i
].name
, "swtch"))
1573 /* If eof uses the same slot as min, only print whichever applies. */
1575 if ((mode
->c_lflag
& ICANON
) == 0
1576 && (STREQ (control_info
[i
].name
, "eof")
1577 || STREQ (control_info
[i
].name
, "eol")))
1582 wrapf ("%s = %s;", control_info
[i
].name
,
1583 visible (mode
->c_cc
[control_info
[i
].offset
]));
1585 if ((mode
->c_lflag
& ICANON
) == 0)
1587 wrapf ("min = %d; time = %d;\n", (int) mode
->c_cc
[VMIN
],
1588 (int) mode
->c_cc
[VTIME
]);
1590 else if (empty_line
== 0)
1595 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1597 if (mode_info
[i
].flags
& OMIT
)
1599 if (mode_info
[i
].type
!= prev_type
)
1601 if (empty_line
== 0)
1607 prev_type
= mode_info
[i
].type
;
1610 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1611 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1612 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1614 if (mode_info
[i
].flags
& SANE_UNSET
)
1616 wrapf ("%s", mode_info
[i
].name
);
1620 else if ((mode_info
[i
].flags
& (SANE_SET
| REV
)) == (SANE_SET
| REV
))
1622 wrapf ("-%s", mode_info
[i
].name
);
1626 if (empty_line
== 0)
1632 display_all (struct termios
*mode
, int fd
, const char *device_name
)
1637 enum mode_type prev_type
= control
;
1639 display_speed (mode
, 1);
1641 display_window_size (1, fd
, device_name
);
1644 wrapf ("line = %d;", mode
->c_line
);
1649 for (i
= 0; ! STREQ (control_info
[i
].name
, "min"); ++i
)
1651 /* If swtch is the same as susp, don't print both. */
1653 if (STREQ (control_info
[i
].name
, "swtch"))
1656 /* If eof uses the same slot as min, only print whichever applies. */
1658 if ((mode
->c_lflag
& ICANON
) == 0
1659 && (STREQ (control_info
[i
].name
, "eof")
1660 || STREQ (control_info
[i
].name
, "eol")))
1663 wrapf ("%s = %s;", control_info
[i
].name
,
1664 visible (mode
->c_cc
[control_info
[i
].offset
]));
1667 if ((mode
->c_lflag
& ICANON
) == 0)
1669 wrapf ("min = %d; time = %d;", mode
->c_cc
[VMIN
], mode
->c_cc
[VTIME
]);
1670 if (current_col
!= 0)
1674 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1676 if (mode_info
[i
].flags
& OMIT
)
1678 if (mode_info
[i
].type
!= prev_type
)
1682 prev_type
= mode_info
[i
].type
;
1685 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1686 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1687 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1688 wrapf ("%s", mode_info
[i
].name
);
1689 else if (mode_info
[i
].flags
& REV
)
1690 wrapf ("-%s", mode_info
[i
].name
);
1697 display_speed (struct termios
*mode
, int fancy
)
1699 if (cfgetispeed (mode
) == 0 || cfgetispeed (mode
) == cfgetospeed (mode
))
1700 wrapf (fancy
? "speed %lu baud;" : "%lu\n",
1701 baud_to_value (cfgetospeed (mode
)));
1703 wrapf (fancy
? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n",
1704 baud_to_value (cfgetispeed (mode
)),
1705 baud_to_value (cfgetospeed (mode
)));
1711 display_recoverable (struct termios
*mode
)
1715 printf ("%lx:%lx:%lx:%lx",
1716 (unsigned long) mode
->c_iflag
, (unsigned long) mode
->c_oflag
,
1717 (unsigned long) mode
->c_cflag
, (unsigned long) mode
->c_lflag
);
1718 for (i
= 0; i
< NCCS
; ++i
)
1719 printf (":%x", (unsigned int) mode
->c_cc
[i
]);
1724 recover_mode (char *arg
, struct termios
*mode
)
1728 unsigned long iflag
, oflag
, cflag
, lflag
;
1730 /* Scan into temporaries since it is too much trouble to figure out
1731 the right format for `tcflag_t'. */
1732 if (sscanf (arg
, "%lx:%lx:%lx:%lx%n",
1733 &iflag
, &oflag
, &cflag
, &lflag
, &n
) != 4)
1735 mode
->c_iflag
= iflag
;
1736 mode
->c_oflag
= oflag
;
1737 mode
->c_cflag
= cflag
;
1738 mode
->c_lflag
= lflag
;
1740 for (i
= 0; i
< NCCS
; ++i
)
1742 if (sscanf (arg
, ":%x%n", &chr
, &n
) != 1)
1744 mode
->c_cc
[i
] = chr
;
1748 /* Fail if there are too many fields. */
1757 const char *string
; /* ASCII representation. */
1758 speed_t speed
; /* Internal form. */
1759 unsigned long value
; /* Numeric value. */
1762 struct speed_map speeds
[] =
1769 {"134.5", B134
, 134},
1774 {"1200", B1200
, 1200},
1775 {"1800", B1800
, 1800},
1776 {"2400", B2400
, 2400},
1777 {"4800", B4800
, 4800},
1778 {"9600", B9600
, 9600},
1779 {"19200", B19200
, 19200},
1780 {"38400", B38400
, 38400},
1781 {"exta", B19200
, 19200},
1782 {"extb", B38400
, 38400},
1784 {"57600", B57600
, 57600},
1787 {"115200", B115200
, 115200},
1790 {"230400", B230400
, 230400},
1793 {"460800", B460800
, 460800},
1796 {"500000", B500000
, 500000},
1799 {"576000", B576000
, 576000},
1802 {"921600", B921600
, 921600},
1805 {"1000000", B1000000
, 1000000},
1808 {"1152000", B1152000
, 1152000},
1811 {"1500000", B1500000
, 1500000},
1814 {"2000000", B2000000
, 2000000},
1817 {"2500000", B2500000
, 2500000},
1820 {"3000000", B3000000
, 3000000},
1823 {"3500000", B3500000
, 3500000},
1826 {"4000000", B4000000
, 4000000},
1832 string_to_baud (const char *arg
)
1836 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1837 if (STREQ (arg
, speeds
[i
].string
))
1838 return speeds
[i
].speed
;
1839 return (speed_t
) -1;
1842 static unsigned long
1843 baud_to_value (speed_t speed
)
1847 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1848 if (speed
== speeds
[i
].speed
)
1849 return speeds
[i
].value
;
1854 sane_mode (struct termios
*mode
)
1859 for (i
= 0; control_info
[i
].name
; ++i
)
1862 if (STREQ (control_info
[i
].name
, "min"))
1865 mode
->c_cc
[control_info
[i
].offset
] = control_info
[i
].saneval
;
1868 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1870 if (mode_info
[i
].flags
& SANE_SET
)
1872 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1873 *bitsp
= (*bitsp
& ~mode_info
[i
].mask
) | mode_info
[i
].bits
;
1875 else if (mode_info
[i
].flags
& SANE_UNSET
)
1877 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1878 *bitsp
= *bitsp
& ~mode_info
[i
].mask
& ~mode_info
[i
].bits
;
1883 /* Return a string that is the printable representation of character CH. */
1884 /* Adapted from `cat' by Torbjorn Granlund. */
1887 visible (unsigned int ch
)
1889 static char buf
[10];
1892 if (ch
== _POSIX_VDISABLE
)
1911 *bpout
++ = ch
- 128;
1921 *bpout
++ = ch
- 128 + 64;
1931 return (const char *) buf
;
1934 /* Parse string S as an integer, using decimal radix by default,
1935 but allowing octal and hex numbers as in C. */
1936 /* From `od' by Richard Stallman. */
1939 integer_arg (const char *s
)
1942 if (xstrtol (s
, NULL
, 0, &value
, "bB") != LONGINT_OK
)
1944 error (0, 0, _("invalid integer argument `%s'"), s
);
1945 usage (EXIT_FAILURE
);