1 /* stty -- change and print terminal line settings
2 Copyright (C) 1990-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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>
46 #ifdef HAVE_SYS_IOCTL_H
47 # include <sys/ioctl.h>
50 #ifdef WINSIZE_IN_PTEM
51 # include <sys/stream.h>
52 # include <sys/ptem.h>
54 #ifdef GWINSZ_IN_SYS_PTY
63 #include "fd-reopen.h"
65 #include "vasprintf.h"
68 /* The official name of this program (e.g., no `g' prefix). */
69 #define PROGRAM_NAME "stty"
71 #define AUTHORS "David MacKenzie"
73 #ifndef _POSIX_VDISABLE
74 # define _POSIX_VDISABLE 0
77 #define Control(c) ((c) & 0x1f)
78 /* Canonical values for control characters. */
80 # define CINTR Control ('c')
89 # define CKILL Control ('u')
92 # define CEOF Control ('d')
95 # define CEOL _POSIX_VDISABLE
98 # define CSTART Control ('q')
101 # define CSTOP Control ('s')
104 # define CSUSP Control ('z')
106 #if defined VEOL2 && !defined CEOL2
107 # define CEOL2 _POSIX_VDISABLE
109 /* Some platforms have VSWTC, others VSWTCH. In both cases, this control
110 character is initialized by CSWTCH, if present. */
111 #if defined VSWTC && !defined VSWTCH
112 # define VSWTCH VSWTC
114 /* ISC renamed swtch to susp for termios, but we'll accept either name. */
115 #if defined VSUSP && !defined VSWTCH
116 # define VSWTCH VSUSP
117 # if defined CSUSP && !defined CSWTCH
118 # define CSWTCH CSUSP
121 #if defined VSWTCH && !defined CSWTCH
122 # define CSWTCH _POSIX_VDISABLE
125 /* SunOS 5.3 loses (^Z doesn't work) if `swtch' is the same as `susp'.
126 So the default is to disable `swtch.' */
127 #if defined __sparc__ && defined __svr4__
129 # define CSWTCH _POSIX_VDISABLE
132 #if defined VWERSE && !defined VWERASE /* AIX-3.2.5 */
133 # define VWERASE VWERSE
135 #if defined VDSUSP && !defined CDSUSP
136 # define CDSUSP Control ('y')
138 #if !defined VREPRINT && defined VRPRNT /* Irix 4.0.5 */
139 # define VREPRINT VRPRNT
141 #if defined VREPRINT && !defined CRPRNT
142 # define CRPRNT Control ('r')
144 #if defined CREPRINT && !defined CRPRNT
145 # define CRPRNT Control ('r')
147 #if defined VWERASE && !defined CWERASE
148 # define CWERASE Control ('w')
150 #if defined VLNEXT && !defined CLNEXT
151 # define CLNEXT Control ('v')
153 #if defined VDISCARD && !defined VFLUSHO
154 # define VFLUSHO VDISCARD
156 #if defined VFLUSH && !defined VFLUSHO /* Ultrix 4.2 */
157 # define VFLUSHO VFLUSH
159 #if defined CTLECH && !defined ECHOCTL /* Ultrix 4.3 */
160 # define ECHOCTL CTLECH
162 #if defined TCTLECH && !defined ECHOCTL /* Ultrix 4.2 */
163 # define ECHOCTL TCTLECH
165 #if defined CRTKIL && !defined ECHOKE /* Ultrix 4.2 and 4.3 */
166 # define ECHOKE CRTKIL
168 #if defined VFLUSHO && !defined CFLUSHO
169 # define CFLUSHO Control ('o')
171 #if defined VSTATUS && !defined CSTATUS
172 # define CSTATUS Control ('t')
175 /* Which speeds to set. */
178 input_speed
, output_speed
, both_speeds
181 /* What to output and how. */
184 changed
, all
, recoverable
/* Default, -a, -g. */
187 /* Which member(s) of `struct termios' a mode uses. */
190 control
, input
, output
, local
, combination
193 /* Flags for `struct mode_info'. */
194 #define SANE_SET 1 /* Set in `sane' mode. */
195 #define SANE_UNSET 2 /* Unset in `sane' mode. */
196 #define REV 4 /* Can be turned off by prepending `-'. */
197 #define OMIT 8 /* Don't display value. */
202 const char *name
; /* Name given on command line. */
203 enum mode_type type
; /* Which structure element to change. */
204 char flags
; /* Setting and display options. */
205 unsigned long bits
; /* Bits to set for this mode. */
206 unsigned long mask
; /* Other bits to turn off for this mode. */
209 static struct mode_info mode_info
[] =
211 {"parenb", control
, REV
, PARENB
, 0},
212 {"parodd", control
, REV
, PARODD
, 0},
213 {"cs5", control
, 0, CS5
, CSIZE
},
214 {"cs6", control
, 0, CS6
, CSIZE
},
215 {"cs7", control
, 0, CS7
, CSIZE
},
216 {"cs8", control
, 0, CS8
, CSIZE
},
217 {"hupcl", control
, REV
, HUPCL
, 0},
218 {"hup", control
, REV
| OMIT
, HUPCL
, 0},
219 {"cstopb", control
, REV
, CSTOPB
, 0},
220 {"cread", control
, SANE_SET
| REV
, CREAD
, 0},
221 {"clocal", control
, REV
, CLOCAL
, 0},
223 {"crtscts", control
, REV
, CRTSCTS
, 0},
226 {"ignbrk", input
, SANE_UNSET
| REV
, IGNBRK
, 0},
227 {"brkint", input
, SANE_SET
| REV
, BRKINT
, 0},
228 {"ignpar", input
, REV
, IGNPAR
, 0},
229 {"parmrk", input
, REV
, PARMRK
, 0},
230 {"inpck", input
, REV
, INPCK
, 0},
231 {"istrip", input
, REV
, ISTRIP
, 0},
232 {"inlcr", input
, SANE_UNSET
| REV
, INLCR
, 0},
233 {"igncr", input
, SANE_UNSET
| REV
, IGNCR
, 0},
234 {"icrnl", input
, SANE_SET
| REV
, ICRNL
, 0},
235 {"ixon", input
, REV
, IXON
, 0},
236 {"ixoff", input
, SANE_UNSET
| REV
, IXOFF
, 0},
237 {"tandem", input
, REV
| OMIT
, IXOFF
, 0},
239 {"iuclc", input
, SANE_UNSET
| REV
, IUCLC
, 0},
242 {"ixany", input
, SANE_UNSET
| REV
, IXANY
, 0},
245 {"imaxbel", input
, SANE_SET
| REV
, IMAXBEL
, 0},
248 {"iutf8", input
, SANE_UNSET
| REV
, IUTF8
, 0},
251 {"opost", output
, SANE_SET
| REV
, OPOST
, 0},
253 {"olcuc", output
, SANE_UNSET
| REV
, OLCUC
, 0},
256 {"ocrnl", output
, SANE_UNSET
| REV
, OCRNL
, 0},
259 {"onlcr", output
, SANE_SET
| REV
, ONLCR
, 0},
262 {"onocr", output
, SANE_UNSET
| REV
, ONOCR
, 0},
265 {"onlret", output
, SANE_UNSET
| REV
, ONLRET
, 0},
268 {"ofill", output
, SANE_UNSET
| REV
, OFILL
, 0},
271 {"ofdel", output
, SANE_UNSET
| REV
, OFDEL
, 0},
274 {"nl1", output
, SANE_UNSET
, NL1
, NLDLY
},
275 {"nl0", output
, SANE_SET
, NL0
, NLDLY
},
278 {"cr3", output
, SANE_UNSET
, CR3
, CRDLY
},
279 {"cr2", output
, SANE_UNSET
, CR2
, CRDLY
},
280 {"cr1", output
, SANE_UNSET
, CR1
, CRDLY
},
281 {"cr0", output
, SANE_SET
, CR0
, CRDLY
},
284 {"tab3", output
, SANE_UNSET
, TAB3
, TABDLY
},
285 {"tab2", output
, SANE_UNSET
, TAB2
, TABDLY
},
286 {"tab1", output
, SANE_UNSET
, TAB1
, TABDLY
},
287 {"tab0", output
, SANE_SET
, TAB0
, TABDLY
},
290 {"tab3", output
, SANE_UNSET
, OXTABS
, 0},
294 {"bs1", output
, SANE_UNSET
, BS1
, BSDLY
},
295 {"bs0", output
, SANE_SET
, BS0
, BSDLY
},
298 {"vt1", output
, SANE_UNSET
, VT1
, VTDLY
},
299 {"vt0", output
, SANE_SET
, VT0
, VTDLY
},
302 {"ff1", output
, SANE_UNSET
, FF1
, FFDLY
},
303 {"ff0", output
, SANE_SET
, FF0
, FFDLY
},
306 {"isig", local
, SANE_SET
| REV
, ISIG
, 0},
307 {"icanon", local
, SANE_SET
| REV
, ICANON
, 0},
309 {"iexten", local
, SANE_SET
| REV
, IEXTEN
, 0},
311 {"echo", local
, SANE_SET
| REV
, ECHO
, 0},
312 {"echoe", local
, SANE_SET
| REV
, ECHOE
, 0},
313 {"crterase", local
, REV
| OMIT
, ECHOE
, 0},
314 {"echok", local
, SANE_SET
| REV
, ECHOK
, 0},
315 {"echonl", local
, SANE_UNSET
| REV
, ECHONL
, 0},
316 {"noflsh", local
, SANE_UNSET
| REV
, NOFLSH
, 0},
318 {"xcase", local
, SANE_UNSET
| REV
, XCASE
, 0},
321 {"tostop", local
, SANE_UNSET
| REV
, TOSTOP
, 0},
324 {"echoprt", local
, SANE_UNSET
| REV
, ECHOPRT
, 0},
325 {"prterase", local
, REV
| OMIT
, ECHOPRT
, 0},
328 {"echoctl", local
, SANE_SET
| REV
, ECHOCTL
, 0},
329 {"ctlecho", local
, REV
| OMIT
, ECHOCTL
, 0},
332 {"echoke", local
, SANE_SET
| REV
, ECHOKE
, 0},
333 {"crtkill", local
, REV
| OMIT
, ECHOKE
, 0},
336 {"evenp", combination
, REV
| OMIT
, 0, 0},
337 {"parity", combination
, REV
| OMIT
, 0, 0},
338 {"oddp", combination
, REV
| OMIT
, 0, 0},
339 {"nl", combination
, REV
| OMIT
, 0, 0},
340 {"ek", combination
, OMIT
, 0, 0},
341 {"sane", combination
, OMIT
, 0, 0},
342 {"cooked", combination
, REV
| OMIT
, 0, 0},
343 {"raw", combination
, REV
| OMIT
, 0, 0},
344 {"pass8", combination
, REV
| OMIT
, 0, 0},
345 {"litout", combination
, REV
| OMIT
, 0, 0},
346 {"cbreak", combination
, REV
| OMIT
, 0, 0},
348 {"decctlq", combination
, REV
| OMIT
, 0, 0},
350 #if defined TABDLY || defined OXTABS
351 {"tabs", combination
, REV
| OMIT
, 0, 0},
353 #if defined XCASE && defined IUCLC && defined OLCUC
354 {"lcase", combination
, REV
| OMIT
, 0, 0},
355 {"LCASE", combination
, REV
| OMIT
, 0, 0},
357 {"crt", combination
, OMIT
, 0, 0},
358 {"dec", combination
, OMIT
, 0, 0},
360 {NULL
, control
, 0, 0, 0}
363 /* Control character settings. */
366 const char *name
; /* Name given on command line. */
367 cc_t saneval
; /* Value to set for `stty sane'. */
368 size_t offset
; /* Offset in c_cc. */
371 /* Control characters. */
373 static struct control_info control_info
[] =
375 {"intr", CINTR
, VINTR
},
376 {"quit", CQUIT
, VQUIT
},
377 {"erase", CERASE
, VERASE
},
378 {"kill", CKILL
, VKILL
},
382 {"eol2", CEOL2
, VEOL2
},
385 {"swtch", CSWTCH
, VSWTCH
},
387 {"start", CSTART
, VSTART
},
388 {"stop", CSTOP
, VSTOP
},
389 {"susp", CSUSP
, VSUSP
},
391 {"dsusp", CDSUSP
, VDSUSP
},
394 {"rprnt", CRPRNT
, VREPRINT
},
396 # ifdef CREPRINT /* HPUX 10.20 needs this */
397 {"rprnt", CRPRNT
, CREPRINT
},
401 {"werase", CWERASE
, VWERASE
},
404 {"lnext", CLNEXT
, VLNEXT
},
407 {"flush", CFLUSHO
, VFLUSHO
},
410 {"status", CSTATUS
, VSTATUS
},
413 /* These must be last because of the display routines. */
419 static char const *visible (cc_t ch
);
420 static unsigned long int baud_to_value (speed_t speed
);
421 static bool recover_mode (char const *arg
, struct termios
*mode
);
422 static int screen_columns (void);
423 static bool set_mode (struct mode_info
*info
, bool reversed
,
424 struct termios
*mode
);
425 static unsigned long int integer_arg (const char *s
, unsigned long int max
);
426 static speed_t
string_to_baud (const char *arg
);
427 static tcflag_t
*mode_type_flag (enum mode_type type
, struct termios
*mode
);
428 static void display_all (struct termios
*mode
, char const *device_name
);
429 static void display_changed (struct termios
*mode
);
430 static void display_recoverable (struct termios
*mode
);
431 static void display_settings (enum output_type output_type
,
432 struct termios
*mode
,
433 const char *device_name
);
434 static void display_speed (struct termios
*mode
, bool fancy
);
435 static void display_window_size (bool fancy
, char const *device_name
);
436 static void sane_mode (struct termios
*mode
);
437 static void set_control_char (struct control_info
*info
,
439 struct termios
*mode
);
440 static void set_speed (enum speed_setting type
, const char *arg
,
441 struct termios
*mode
);
442 static void set_window_size (int rows
, int cols
, char const *device_name
);
444 /* The width of the screen, for output wrapping. */
447 /* Current position, to know when to wrap. */
448 static int current_col
;
450 static struct option longopts
[] =
452 {"all", no_argument
, NULL
, 'a'},
453 {"save", no_argument
, NULL
, 'g'},
454 {"file", required_argument
, NULL
, 'F'},
455 {GETOPT_HELP_OPTION_DECL
},
456 {GETOPT_VERSION_OPTION_DECL
},
460 /* The name this program was run with. */
463 static void wrapf (const char *message
, ...)
464 __attribute__ ((__format__ (__printf__
, 1, 2)));
466 /* Print format string MESSAGE and optional args.
467 Wrap to next line first if it won't fit.
468 Print a space first unless MESSAGE will start a new line. */
471 wrapf (const char *message
,...)
477 va_start (args
, message
);
478 buflen
= vasprintf (&buf
, message
, args
);
486 if (max_col
- current_col
< buflen
)
500 current_col
+= buflen
;
506 if (status
!= EXIT_SUCCESS
)
507 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
512 Usage: %s [-F DEVICE] [--file=DEVICE] [SETTING]...\n\
513 or: %s [-F DEVICE] [--file=DEVICE] [-a|--all]\n\
514 or: %s [-F DEVICE] [--file=DEVICE] [-g|--save]\n\
516 program_name
, program_name
, program_name
);
518 Print or change terminal characteristics.\n\
520 -a, --all print all current settings in human-readable form\n\
521 -g, --save print all current settings in a stty-readable form\n\
522 -F, --file=DEVICE open and use the specified DEVICE instead of stdin\n\
524 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
525 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
528 Optional - before SETTING indicates negation. An * marks non-POSIX\n\
529 settings. The underlying system defines which settings are available.\n\
533 Special characters:\n\
534 * dsusp CHAR CHAR will send a terminal stop signal once input flushed\n\
535 eof CHAR CHAR will send an end of file (terminate the input)\n\
536 eol CHAR CHAR will end the line\n\
539 * eol2 CHAR alternate CHAR for ending the line\n\
540 erase CHAR CHAR will erase the last character typed\n\
541 intr CHAR CHAR will send an interrupt signal\n\
542 kill CHAR CHAR will erase the current line\n\
545 * lnext CHAR CHAR will enter the next character quoted\n\
546 quit CHAR CHAR will send a quit signal\n\
547 * rprnt CHAR CHAR will redraw the current line\n\
548 start CHAR CHAR will restart the output after stopping it\n\
551 stop CHAR CHAR will stop the output\n\
552 susp CHAR CHAR will send a terminal stop signal\n\
553 * swtch CHAR CHAR will switch to a different shell layer\n\
554 * werase CHAR CHAR will erase the last word typed\n\
559 N set the input and output speeds to N bauds\n\
560 * cols N tell the kernel that the terminal has N columns\n\
561 * columns N same as cols N\n\
564 ispeed N set the input speed to N\n\
565 * line N use line discipline N\n\
566 min N with -icanon, set N characters minimum for a completed read\n\
567 ospeed N set the output speed to N\n\
570 * rows N tell the kernel that the terminal has N rows\n\
571 * size print the number of rows and columns according to the kernel\n\
572 speed print the terminal speed\n\
573 time N with -icanon, set read timeout of N tenths of a second\n\
578 [-]clocal disable modem control signals\n\
579 [-]cread allow input to be received\n\
580 * [-]crtscts enable RTS/CTS handshaking\n\
581 csN set character size to N bits, N in [5..8]\n\
584 [-]cstopb use two stop bits per character (one with `-')\n\
585 [-]hup send a hangup signal when the last process closes the tty\n\
586 [-]hupcl same as [-]hup\n\
587 [-]parenb generate parity bit in output and expect parity bit in input\n\
588 [-]parodd set odd parity (even with `-')\n\
593 [-]brkint breaks cause an interrupt signal\n\
594 [-]icrnl translate carriage return to newline\n\
595 [-]ignbrk ignore break characters\n\
596 [-]igncr ignore carriage return\n\
599 [-]ignpar ignore characters with parity errors\n\
600 * [-]imaxbel beep and do not flush a full input buffer on a character\n\
601 [-]inlcr translate newline to carriage return\n\
602 [-]inpck enable input parity checking\n\
603 [-]istrip clear high (8th) bit of input characters\n\
606 * [-]iutf8 assume input characters are UTF-8 encoded\n\
609 * [-]iuclc translate uppercase characters to lowercase\n\
610 * [-]ixany let any character restart output, not only start character\n\
611 [-]ixoff enable sending of start/stop characters\n\
612 [-]ixon enable XON/XOFF flow control\n\
613 [-]parmrk mark parity errors (with a 255-0-character sequence)\n\
614 [-]tandem same as [-]ixoff\n\
619 * bsN backspace delay style, N in [0..1]\n\
620 * crN carriage return delay style, N in [0..3]\n\
621 * ffN form feed delay style, N in [0..1]\n\
622 * nlN newline delay style, N in [0..1]\n\
625 * [-]ocrnl translate carriage return to newline\n\
626 * [-]ofdel use delete characters for fill instead of null characters\n\
627 * [-]ofill use fill (padding) characters instead of timing for delays\n\
628 * [-]olcuc translate lowercase characters to uppercase\n\
629 * [-]onlcr translate newline to carriage return-newline\n\
630 * [-]onlret newline performs a carriage return\n\
633 * [-]onocr do not print carriage returns in the first column\n\
634 [-]opost postprocess output\n\
635 * tabN horizontal tab delay style, N in [0..3]\n\
636 * tabs same as tab0\n\
637 * -tabs same as tab3\n\
638 * vtN vertical tab delay style, N in [0..1]\n\
643 [-]crterase echo erase characters as backspace-space-backspace\n\
644 * crtkill kill all line by obeying the echoprt and echoe settings\n\
645 * -crtkill kill all line by obeying the echoctl and echok settings\n\
648 * [-]ctlecho echo control characters in hat notation (`^c')\n\
649 [-]echo echo input characters\n\
650 * [-]echoctl same as [-]ctlecho\n\
651 [-]echoe same as [-]crterase\n\
652 [-]echok echo a newline after a kill character\n\
655 * [-]echoke same as [-]crtkill\n\
656 [-]echonl echo newline even if not echoing other characters\n\
657 * [-]echoprt echo erased characters backward, between `\\' and '/'\n\
658 [-]icanon enable erase, kill, werase, and rprnt special characters\n\
659 [-]iexten enable non-POSIX special characters\n\
662 [-]isig enable interrupt, quit, and suspend special characters\n\
663 [-]noflsh disable flushing after interrupt and quit special characters\n\
664 * [-]prterase same as [-]echoprt\n\
665 * [-]tostop stop background jobs that try to write to the terminal\n\
666 * [-]xcase with icanon, escape with `\\' for uppercase characters\n\
670 Combination settings:\n\
671 * [-]LCASE same as [-]lcase\n\
672 cbreak same as -icanon\n\
673 -cbreak same as icanon\n\
676 cooked same as brkint ignpar istrip icrnl ixon opost isig\n\
677 icanon, eof and eol characters to their default values\n\
678 -cooked same as raw\n\
679 crt same as echoe echoctl echoke\n\
682 dec same as echoe echoctl echoke -ixany intr ^c erase 0177\n\
684 * [-]decctlq same as [-]ixany\n\
685 ek erase and kill characters to their default values\n\
686 evenp same as parenb -parodd cs7\n\
689 -evenp same as -parenb cs8\n\
690 * [-]lcase same as xcase iuclc olcuc\n\
691 litout same as -parenb -istrip -opost cs8\n\
692 -litout same as parenb istrip opost cs7\n\
693 nl same as -icrnl -onlcr\n\
694 -nl same as icrnl -inlcr -igncr onlcr -ocrnl -onlret\n\
697 oddp same as parenb parodd cs7\n\
698 -oddp same as -parenb cs8\n\
699 [-]parity same as [-]evenp\n\
700 pass8 same as -parenb -istrip cs8\n\
701 -pass8 same as parenb istrip cs7\n\
704 raw same as -ignbrk -brkint -ignpar -parmrk -inpck -istrip\n\
705 -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany\n\
706 -imaxbel -opost -isig -icanon -xcase min 1 time 0\n\
707 -raw same as cooked\n\
710 sane same as cread -ignbrk brkint -inlcr -igncr icrnl -iutf8\n\
711 -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr\n\
712 -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0\n\
713 isig icanon iexten echo echoe echok -echonl -noflsh\n\
714 -xcase -tostop -echoprt echoctl echoke, all special\n\
715 characters to their default values.\n\
719 Handle the tty line connected to standard input. Without arguments,\n\
720 prints baud rate, line discipline, and deviations from stty sane. In\n\
721 settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
722 127; special values ^- or undef used to disable special characters.\n\
724 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
730 main (int argc
, char **argv
)
732 /* Initialize to all zeroes so there is no risk memcmp will report a
733 spurious difference in an uninitialized portion of the structure. */
734 struct termios mode
= { 0, };
736 enum output_type output_type
;
740 bool require_set_attr
;
743 bool recoverable_output
;
746 char *file_name
= NULL
;
747 const char *device_name
;
749 initialize_main (&argc
, &argv
);
750 program_name
= argv
[0];
751 setlocale (LC_ALL
, "");
752 bindtextdomain (PACKAGE
, LOCALEDIR
);
753 textdomain (PACKAGE
);
755 atexit (close_stdout
);
757 output_type
= changed
;
758 verbose_output
= false;
759 recoverable_output
= false;
761 /* Don't print error messages for unrecognized options. */
764 /* If any new options are ever added to stty, the short options MUST
765 NOT allow any ambiguity with the stty settings. For example, the
766 stty setting "-gagFork" would not be feasible, since it will be
767 parsed as "-g -a -g -F ork". If you change anything about how
768 stty parses options, be sure it still works with combinations of
769 short and long options, --, POSIXLY_CORRECT, etc. */
771 while ((optc
= getopt_long (argc
- argi
, argv
+ argi
, "-agF:",
778 verbose_output
= true;
783 recoverable_output
= true;
784 output_type
= recoverable
;
789 error (EXIT_FAILURE
, 0, _("only one device may be specified"));
793 case_GETOPT_HELP_CHAR
;
795 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
800 /* Skip the argument containing this unrecognized option;
801 the 2nd pass will analyze it. */
804 /* Restart getopt_long from the first unskipped argument. */
811 /* Clear fully-parsed arguments, so they don't confuse the 2nd pass. */
812 while (opti
< optind
)
813 argv
[argi
+ opti
++] = NULL
;
816 /* Specifying both -a and -g gets an error. */
817 if (verbose_output
& recoverable_output
)
818 error (EXIT_FAILURE
, 0,
819 _("the options for verbose and stty-readable output styles are\n"
820 "mutually exclusive"));
822 /* Specifying any other arguments with -a or -g gets an error. */
823 if (!noargs
& (verbose_output
| recoverable_output
))
824 error (EXIT_FAILURE
, 0,
825 _("when specifying an output style, modes may not be set"));
827 /* FIXME: it'd be better not to open the file until we've verified
828 that all arguments are valid. Otherwise, we could end up doing
829 only some of the requested operations and then failing, probably
830 leaving things in an undesirable state. */
835 device_name
= file_name
;
836 if (fd_reopen (STDIN_FILENO
, device_name
, O_RDONLY
| O_NONBLOCK
, 0) < 0)
837 error (EXIT_FAILURE
, errno
, "%s", device_name
);
838 if ((fdflags
= fcntl (STDIN_FILENO
, F_GETFL
)) == -1
839 || fcntl (STDIN_FILENO
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
840 error (EXIT_FAILURE
, errno
, _("%s: couldn't reset non-blocking mode"),
844 device_name
= _("standard input");
846 if (tcgetattr (STDIN_FILENO
, &mode
))
847 error (EXIT_FAILURE
, errno
, "%s", device_name
);
849 if (verbose_output
| recoverable_output
| noargs
)
851 max_col
= screen_columns ();
853 display_settings (output_type
, &mode
, device_name
);
857 speed_was_set
= false;
858 require_set_attr
= false;
859 for (k
= 1; k
< argc
; k
++)
861 char const *arg
= argv
[k
];
862 bool match_found
= false;
863 bool reversed
= false;
874 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
876 if (STREQ (arg
, mode_info
[i
].name
))
878 match_found
= set_mode (&mode_info
[i
], reversed
, &mode
);
879 require_set_attr
= true;
883 if (!match_found
& reversed
)
885 error (0, 0, _("invalid argument %s"), quote (arg
- 1));
886 usage (EXIT_FAILURE
);
890 for (i
= 0; control_info
[i
].name
!= NULL
; ++i
)
892 if (STREQ (arg
, control_info
[i
].name
))
896 error (0, 0, _("missing argument to %s"), quote (arg
));
897 usage (EXIT_FAILURE
);
901 set_control_char (&control_info
[i
], argv
[k
], &mode
);
902 require_set_attr
= true;
909 if (STREQ (arg
, "ispeed"))
913 error (0, 0, _("missing argument to %s"), quote (arg
));
914 usage (EXIT_FAILURE
);
917 set_speed (input_speed
, argv
[k
], &mode
);
918 speed_was_set
= true;
919 require_set_attr
= true;
921 else if (STREQ (arg
, "ospeed"))
925 error (0, 0, _("missing argument to %s"), quote (arg
));
926 usage (EXIT_FAILURE
);
929 set_speed (output_speed
, argv
[k
], &mode
);
930 speed_was_set
= true;
931 require_set_attr
= true;
934 else if (STREQ (arg
, "rows"))
938 error (0, 0, _("missing argument to %s"), quote (arg
));
939 usage (EXIT_FAILURE
);
942 set_window_size (integer_arg (argv
[k
], INT_MAX
), -1,
945 else if (STREQ (arg
, "cols")
946 || STREQ (arg
, "columns"))
950 error (0, 0, _("missing argument to %s"), quote (arg
));
951 usage (EXIT_FAILURE
);
954 set_window_size (-1, integer_arg (argv
[k
], INT_MAX
),
957 else if (STREQ (arg
, "size"))
959 max_col
= screen_columns ();
961 display_window_size (false, device_name
);
965 else if (STREQ (arg
, "line"))
967 unsigned long int value
;
970 error (0, 0, _("missing argument to %s"), quote (arg
));
971 usage (EXIT_FAILURE
);
974 mode
.c_line
= value
= integer_arg (argv
[k
], ULONG_MAX
);
975 if (mode
.c_line
!= value
)
976 error (0, 0, _("invalid line discipline %s"), quote (argv
[k
]));
977 require_set_attr
= true;
980 else if (STREQ (arg
, "speed"))
982 max_col
= screen_columns ();
983 display_speed (&mode
, false);
985 else if (string_to_baud (arg
) != (speed_t
) -1)
987 set_speed (both_speeds
, arg
, &mode
);
988 speed_was_set
= true;
989 require_set_attr
= true;
993 if (! recover_mode (arg
, &mode
))
995 error (0, 0, _("invalid argument %s"), quote (arg
));
996 usage (EXIT_FAILURE
);
998 require_set_attr
= true;
1003 if (require_set_attr
)
1005 /* Initialize to all zeroes so there is no risk memcmp will report a
1006 spurious difference in an uninitialized portion of the structure. */
1007 struct termios new_mode
= { 0, };
1009 if (tcsetattr (STDIN_FILENO
, TCSADRAIN
, &mode
))
1010 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1012 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
1013 it performs *any* of the requested operations. This means it
1014 can report `success' when it has actually failed to perform
1015 some proper subset of the requested operations. To detect
1016 this partial failure, get the current terminal attributes and
1017 compare them to the requested ones. */
1019 if (tcgetattr (STDIN_FILENO
, &new_mode
))
1020 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1022 /* Normally, one shouldn't use memcmp to compare structures that
1023 may have `holes' containing uninitialized data, but we have been
1024 careful to initialize the storage of these two variables to all
1025 zeroes. One might think it more efficient simply to compare the
1026 modified fields, but that would require enumerating those fields --
1027 and not all systems have the same fields in this structure. */
1029 if (memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1032 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1033 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1034 sometimes (m1 != m2). The only difference is in the four bits
1035 of the c_cflag field corresponding to the baud rate. To save
1036 Sun users a little confusion, don't report an error if this
1037 happens. But suppress the error only if we haven't tried to
1038 set the baud rate explicitly -- otherwise we'd never give an
1039 error for a true failure to set the baud rate. */
1041 new_mode
.c_cflag
&= (~CIBAUD
);
1042 if (speed_was_set
|| memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1045 error (EXIT_FAILURE
, 0,
1046 _("%s: unable to perform all requested operations"),
1051 printf (_("new_mode: mode\n"));
1052 for (i
= 0; i
< sizeof (new_mode
); i
++)
1053 printf ("0x%02x: 0x%02x\n",
1054 *(((unsigned char *) &new_mode
) + i
),
1055 *(((unsigned char *) &mode
) + i
));
1062 exit (EXIT_SUCCESS
);
1065 /* Return false if not applied because not reversible; otherwise
1069 set_mode (struct mode_info
*info
, bool reversed
, struct termios
*mode
)
1073 if (reversed
&& (info
->flags
& REV
) == 0)
1076 bitsp
= mode_type_flag (info
->type
, mode
);
1080 /* Combination mode. */
1081 if (STREQ (info
->name
, "evenp") || STREQ (info
->name
, "parity"))
1084 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1086 mode
->c_cflag
= (mode
->c_cflag
& ~PARODD
& ~CSIZE
) | PARENB
| CS7
;
1088 else if (STREQ (info
->name
, "oddp"))
1091 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1093 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARODD
| PARENB
;
1095 else if (STREQ (info
->name
, "nl"))
1099 mode
->c_iflag
= (mode
->c_iflag
| ICRNL
) & ~INLCR
& ~IGNCR
;
1100 mode
->c_oflag
= (mode
->c_oflag
1115 mode
->c_iflag
= mode
->c_iflag
& ~ICRNL
;
1117 mode
->c_oflag
= mode
->c_oflag
& ~ONLCR
;
1121 else if (STREQ (info
->name
, "ek"))
1123 mode
->c_cc
[VERASE
] = CERASE
;
1124 mode
->c_cc
[VKILL
] = CKILL
;
1126 else if (STREQ (info
->name
, "sane"))
1128 else if (STREQ (info
->name
, "cbreak"))
1131 mode
->c_lflag
|= ICANON
;
1133 mode
->c_lflag
&= ~ICANON
;
1135 else if (STREQ (info
->name
, "pass8"))
1139 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1140 mode
->c_iflag
|= ISTRIP
;
1144 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1145 mode
->c_iflag
&= ~ISTRIP
;
1148 else if (STREQ (info
->name
, "litout"))
1152 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1153 mode
->c_iflag
|= ISTRIP
;
1154 mode
->c_oflag
|= OPOST
;
1158 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1159 mode
->c_iflag
&= ~ISTRIP
;
1160 mode
->c_oflag
&= ~OPOST
;
1163 else if (STREQ (info
->name
, "raw") || STREQ (info
->name
, "cooked"))
1165 if ((info
->name
[0] == 'r' && reversed
)
1166 || (info
->name
[0] == 'c' && !reversed
))
1169 mode
->c_iflag
|= BRKINT
| IGNPAR
| ISTRIP
| ICRNL
| IXON
;
1170 mode
->c_oflag
|= OPOST
;
1171 mode
->c_lflag
|= ISIG
| ICANON
;
1173 mode
->c_cc
[VEOF
] = CEOF
;
1176 mode
->c_cc
[VEOL
] = CEOL
;
1183 mode
->c_oflag
&= ~OPOST
;
1184 mode
->c_lflag
&= ~(ISIG
| ICANON
1189 mode
->c_cc
[VMIN
] = 1;
1190 mode
->c_cc
[VTIME
] = 0;
1194 else if (STREQ (info
->name
, "decctlq"))
1197 mode
->c_iflag
|= IXANY
;
1199 mode
->c_iflag
&= ~IXANY
;
1203 else if (STREQ (info
->name
, "tabs"))
1206 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB3
;
1208 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB0
;
1212 else if (STREQ (info
->name
, "tabs"))
1215 mode
->c_oflag
= mode
->c_oflag
| OXTABS
;
1217 mode
->c_oflag
= mode
->c_oflag
& ~OXTABS
;
1221 #if defined XCASE && defined IUCLC && defined OLCUC
1222 else if (STREQ (info
->name
, "lcase")
1223 || STREQ (info
->name
, "LCASE"))
1227 mode
->c_lflag
&= ~XCASE
;
1228 mode
->c_iflag
&= ~IUCLC
;
1229 mode
->c_oflag
&= ~OLCUC
;
1233 mode
->c_lflag
|= XCASE
;
1234 mode
->c_iflag
|= IUCLC
;
1235 mode
->c_oflag
|= OLCUC
;
1239 else if (STREQ (info
->name
, "crt"))
1240 mode
->c_lflag
|= ECHOE
1248 else if (STREQ (info
->name
, "dec"))
1250 mode
->c_cc
[VINTR
] = 3; /* ^C */
1251 mode
->c_cc
[VERASE
] = 127; /* DEL */
1252 mode
->c_cc
[VKILL
] = 21; /* ^U */
1253 mode
->c_lflag
|= ECHOE
1262 mode
->c_iflag
&= ~IXANY
;
1267 *bitsp
= *bitsp
& ~info
->mask
& ~info
->bits
;
1269 *bitsp
= (*bitsp
& ~info
->mask
) | info
->bits
;
1275 set_control_char (struct control_info
*info
, const char *arg
,
1276 struct termios
*mode
)
1278 unsigned long int value
;
1280 if (STREQ (info
->name
, "min") || STREQ (info
->name
, "time"))
1281 value
= integer_arg (arg
, TYPE_MAXIMUM (cc_t
));
1282 else if (arg
[0] == '\0' || arg
[1] == '\0')
1283 value
= to_uchar (arg
[0]);
1284 else if (STREQ (arg
, "^-") || STREQ (arg
, "undef"))
1285 value
= _POSIX_VDISABLE
;
1286 else if (arg
[0] == '^' && arg
[1] != '\0') /* Ignore any trailing junk. */
1291 value
= to_uchar (arg
[1]) & ~0140; /* Non-letters get weird results. */
1294 value
= integer_arg (arg
, TYPE_MAXIMUM (cc_t
));
1295 mode
->c_cc
[info
->offset
] = value
;
1299 set_speed (enum speed_setting type
, const char *arg
, struct termios
*mode
)
1303 baud
= string_to_baud (arg
);
1304 if (type
== input_speed
|| type
== both_speeds
)
1305 cfsetispeed (mode
, baud
);
1306 if (type
== output_speed
|| type
== both_speeds
)
1307 cfsetospeed (mode
, baud
);
1313 get_win_size (int fd
, struct winsize
*win
)
1315 int err
= ioctl (fd
, TIOCGWINSZ
, (char *) win
);
1320 set_window_size (int rows
, int cols
, char const *device_name
)
1324 if (get_win_size (STDIN_FILENO
, &win
))
1326 if (errno
!= EINVAL
)
1327 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1328 memset (&win
, 0, sizeof (win
));
1337 /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote:
1338 The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.
1339 This comment from sys/ttold.h describes Sun's twisted logic - a better
1340 test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).
1341 At any rate, the problem is gone in Solaris 2.x.
1343 Unfortunately, the old TIOCSSIZE code does collide with TIOCSWINSZ,
1344 but they can be disambiguated by checking whether a "struct ttysize"
1345 structure's "ts_lines" field is greater than 64K or not. If so,
1346 it's almost certainly a "struct winsize" instead.
1348 At any rate, the bug manifests itself when ws_row == 0; the symptom is
1349 that ws_row is set to ws_col, and ws_col is set to (ws_xpixel<<16) +
1350 ws_ypixel. Since GNU stty sets rows and columns separately, this bug
1351 caused "stty rows 0 cols 0" to set rows to cols and cols to 0, while
1352 "stty cols 0 rows 0" would do the right thing. On a little-endian
1353 machine like the sun386i, the problem is the same, but for ws_col == 0.
1355 The workaround is to do the ioctl once with row and col = 1 to set the
1356 pixel info, and then do it again using a TIOCSSIZE to set rows/cols. */
1358 if (win
.ws_row
== 0 || win
.ws_col
== 0)
1360 struct ttysize ttysz
;
1362 ttysz
.ts_lines
= win
.ws_row
;
1363 ttysz
.ts_cols
= win
.ws_col
;
1368 if (ioctl (STDIN_FILENO
, TIOCSWINSZ
, (char *) &win
))
1369 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1371 if (ioctl (STDIN_FILENO
, TIOCSSIZE
, (char *) &ttysz
))
1372 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1377 if (ioctl (STDIN_FILENO
, TIOCSWINSZ
, (char *) &win
))
1378 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1382 display_window_size (bool fancy
, char const *device_name
)
1386 if (get_win_size (STDIN_FILENO
, &win
))
1388 if (errno
!= EINVAL
)
1389 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1391 error (EXIT_FAILURE
, 0,
1392 _("%s: no size information for this device"), device_name
);
1396 wrapf (fancy
? "rows %d; columns %d;" : "%d %d\n",
1397 win
.ws_row
, win
.ws_col
);
1405 screen_columns (void)
1410 /* With Solaris 2.[123], this ioctl fails and errno is set to
1411 EINVAL for telnet (but not rlogin) sessions.
1412 On ISC 3.0, it fails for the console and the serial port
1413 (but it works for ptys).
1414 It can also fail on any system when stdout isn't a tty.
1415 In case of any failure, just use the default. */
1416 if (get_win_size (STDOUT_FILENO
, &win
) == 0 && 0 < win
.ws_col
)
1420 /* Use $COLUMNS if it's in [1..INT_MAX]. */
1421 char *col_string
= getenv ("COLUMNS");
1423 if (!(col_string
!= NULL
1424 && xstrtol (col_string
, NULL
, 0, &n_columns
, "") == LONGINT_OK
1426 && n_columns
<= INT_MAX
))
1433 mode_type_flag (enum mode_type type
, struct termios
*mode
)
1438 return &mode
->c_cflag
;
1441 return &mode
->c_iflag
;
1444 return &mode
->c_oflag
;
1447 return &mode
->c_lflag
;
1458 display_settings (enum output_type output_type
, struct termios
*mode
,
1459 char const *device_name
)
1461 switch (output_type
)
1464 display_changed (mode
);
1468 display_all (mode
, device_name
);
1472 display_recoverable (mode
);
1478 display_changed (struct termios
*mode
)
1484 enum mode_type prev_type
= control
;
1486 display_speed (mode
, true);
1488 wrapf ("line = %d;", mode
->c_line
);
1494 for (i
= 0; !STREQ (control_info
[i
].name
, "min"); ++i
)
1496 if (mode
->c_cc
[control_info
[i
].offset
] == control_info
[i
].saneval
)
1498 /* If swtch is the same as susp, don't print both. */
1500 if (STREQ (control_info
[i
].name
, "swtch"))
1503 /* If eof uses the same slot as min, only print whichever applies. */
1505 if ((mode
->c_lflag
& ICANON
) == 0
1506 && (STREQ (control_info
[i
].name
, "eof")
1507 || STREQ (control_info
[i
].name
, "eol")))
1512 wrapf ("%s = %s;", control_info
[i
].name
,
1513 visible (mode
->c_cc
[control_info
[i
].offset
]));
1515 if ((mode
->c_lflag
& ICANON
) == 0)
1517 wrapf ("min = %lu; time = %lu;\n",
1518 (unsigned long int) mode
->c_cc
[VMIN
],
1519 (unsigned long int) mode
->c_cc
[VTIME
]);
1521 else if (!empty_line
)
1526 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1528 if (mode_info
[i
].flags
& OMIT
)
1530 if (mode_info
[i
].type
!= prev_type
)
1538 prev_type
= mode_info
[i
].type
;
1541 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1542 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1543 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1545 if (mode_info
[i
].flags
& SANE_UNSET
)
1547 wrapf ("%s", mode_info
[i
].name
);
1551 else if ((mode_info
[i
].flags
& (SANE_SET
| REV
)) == (SANE_SET
| REV
))
1553 wrapf ("-%s", mode_info
[i
].name
);
1563 display_all (struct termios
*mode
, char const *device_name
)
1568 enum mode_type prev_type
= control
;
1570 display_speed (mode
, true);
1572 display_window_size (true, device_name
);
1575 wrapf ("line = %d;", mode
->c_line
);
1580 for (i
= 0; ! STREQ (control_info
[i
].name
, "min"); ++i
)
1582 /* If swtch is the same as susp, don't print both. */
1584 if (STREQ (control_info
[i
].name
, "swtch"))
1587 /* If eof uses the same slot as min, only print whichever applies. */
1589 if ((mode
->c_lflag
& ICANON
) == 0
1590 && (STREQ (control_info
[i
].name
, "eof")
1591 || STREQ (control_info
[i
].name
, "eol")))
1594 wrapf ("%s = %s;", control_info
[i
].name
,
1595 visible (mode
->c_cc
[control_info
[i
].offset
]));
1598 if ((mode
->c_lflag
& ICANON
) == 0)
1600 wrapf ("min = %lu; time = %lu;",
1601 (unsigned long int) mode
->c_cc
[VMIN
],
1602 (unsigned long int) mode
->c_cc
[VTIME
]);
1603 if (current_col
!= 0)
1607 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1609 if (mode_info
[i
].flags
& OMIT
)
1611 if (mode_info
[i
].type
!= prev_type
)
1615 prev_type
= mode_info
[i
].type
;
1618 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1619 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1620 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1621 wrapf ("%s", mode_info
[i
].name
);
1622 else if (mode_info
[i
].flags
& REV
)
1623 wrapf ("-%s", mode_info
[i
].name
);
1630 display_speed (struct termios
*mode
, bool fancy
)
1632 if (cfgetispeed (mode
) == 0 || cfgetispeed (mode
) == cfgetospeed (mode
))
1633 wrapf (fancy
? "speed %lu baud;" : "%lu\n",
1634 baud_to_value (cfgetospeed (mode
)));
1636 wrapf (fancy
? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n",
1637 baud_to_value (cfgetispeed (mode
)),
1638 baud_to_value (cfgetospeed (mode
)));
1644 display_recoverable (struct termios
*mode
)
1648 printf ("%lx:%lx:%lx:%lx",
1649 (unsigned long int) mode
->c_iflag
,
1650 (unsigned long int) mode
->c_oflag
,
1651 (unsigned long int) mode
->c_cflag
,
1652 (unsigned long int) mode
->c_lflag
);
1653 for (i
= 0; i
< NCCS
; ++i
)
1654 printf (":%lx", (unsigned long int) mode
->c_cc
[i
]);
1659 recover_mode (char const *arg
, struct termios
*mode
)
1663 unsigned long int chr
;
1664 unsigned long int iflag
, oflag
, cflag
, lflag
;
1666 /* Scan into temporaries since it is too much trouble to figure out
1667 the right format for `tcflag_t'. */
1668 if (sscanf (arg
, "%lx:%lx:%lx:%lx%n",
1669 &iflag
, &oflag
, &cflag
, &lflag
, &n
) != 4)
1671 mode
->c_iflag
= iflag
;
1672 mode
->c_oflag
= oflag
;
1673 mode
->c_cflag
= cflag
;
1674 mode
->c_lflag
= lflag
;
1675 if (mode
->c_iflag
!= iflag
1676 || mode
->c_oflag
!= oflag
1677 || mode
->c_cflag
!= cflag
1678 || mode
->c_lflag
!= lflag
)
1681 for (i
= 0; i
< NCCS
; ++i
)
1683 if (sscanf (arg
, ":%lx%n", &chr
, &n
) != 1)
1685 mode
->c_cc
[i
] = chr
;
1686 if (mode
->c_cc
[i
] != chr
)
1691 /* Fail if there are too many fields. */
1700 const char *string
; /* ASCII representation. */
1701 speed_t speed
; /* Internal form. */
1702 unsigned long int value
; /* Numeric value. */
1705 static struct speed_map speeds
[] =
1712 {"134.5", B134
, 134},
1717 {"1200", B1200
, 1200},
1718 {"1800", B1800
, 1800},
1719 {"2400", B2400
, 2400},
1720 {"4800", B4800
, 4800},
1721 {"9600", B9600
, 9600},
1722 {"19200", B19200
, 19200},
1723 {"38400", B38400
, 38400},
1724 {"exta", B19200
, 19200},
1725 {"extb", B38400
, 38400},
1727 {"57600", B57600
, 57600},
1730 {"115200", B115200
, 115200},
1733 {"230400", B230400
, 230400},
1736 {"460800", B460800
, 460800},
1739 {"500000", B500000
, 500000},
1742 {"576000", B576000
, 576000},
1745 {"921600", B921600
, 921600},
1748 {"1000000", B1000000
, 1000000},
1751 {"1152000", B1152000
, 1152000},
1754 {"1500000", B1500000
, 1500000},
1757 {"2000000", B2000000
, 2000000},
1760 {"2500000", B2500000
, 2500000},
1763 {"3000000", B3000000
, 3000000},
1766 {"3500000", B3500000
, 3500000},
1769 {"4000000", B4000000
, 4000000},
1775 string_to_baud (const char *arg
)
1779 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1780 if (STREQ (arg
, speeds
[i
].string
))
1781 return speeds
[i
].speed
;
1782 return (speed_t
) -1;
1785 static unsigned long int
1786 baud_to_value (speed_t speed
)
1790 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1791 if (speed
== speeds
[i
].speed
)
1792 return speeds
[i
].value
;
1797 sane_mode (struct termios
*mode
)
1802 for (i
= 0; control_info
[i
].name
; ++i
)
1805 if (STREQ (control_info
[i
].name
, "min"))
1808 mode
->c_cc
[control_info
[i
].offset
] = control_info
[i
].saneval
;
1811 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1813 if (mode_info
[i
].flags
& SANE_SET
)
1815 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1816 *bitsp
= (*bitsp
& ~mode_info
[i
].mask
) | mode_info
[i
].bits
;
1818 else if (mode_info
[i
].flags
& SANE_UNSET
)
1820 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1821 *bitsp
= *bitsp
& ~mode_info
[i
].mask
& ~mode_info
[i
].bits
;
1826 /* Return a string that is the printable representation of character CH. */
1827 /* Adapted from `cat' by Torbjorn Granlund. */
1832 static char buf
[10];
1835 if (ch
== _POSIX_VDISABLE
)
1854 *bpout
++ = ch
- 128;
1864 *bpout
++ = ch
- 128 + 64;
1874 return (const char *) buf
;
1877 /* Parse string S as an integer, using decimal radix by default,
1878 but allowing octal and hex numbers as in C. Reject values
1879 larger than MAXVAL. */
1881 static unsigned long int
1882 integer_arg (const char *s
, unsigned long int maxval
)
1884 unsigned long int value
;
1885 if (xstrtoul (s
, NULL
, 0, &value
, "bB") != LONGINT_OK
1888 error (0, 0, _("invalid integer argument %s"), quote (s
));
1889 usage (EXIT_FAILURE
);