1 /* stty -- change and print terminal line settings
2 Copyright (C) 1990-2005, 2007 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"
67 /* The official name of this program (e.g., no `g' prefix). */
68 #define PROGRAM_NAME "stty"
70 #define AUTHORS "David MacKenzie"
72 #ifndef _POSIX_VDISABLE
73 # define _POSIX_VDISABLE 0
76 #define Control(c) ((c) & 0x1f)
77 /* Canonical values for control characters. */
79 # define CINTR Control ('c')
88 # define CKILL Control ('u')
91 # define CEOF Control ('d')
94 # define CEOL _POSIX_VDISABLE
97 # define CSTART Control ('q')
100 # define CSTOP Control ('s')
103 # define CSUSP Control ('z')
105 #if defined VEOL2 && !defined CEOL2
106 # define CEOL2 _POSIX_VDISABLE
108 /* Some platforms have VSWTC, others VSWTCH. In both cases, this control
109 character is initialized by CSWTCH, if present. */
110 #if defined VSWTC && !defined VSWTCH
111 # define VSWTCH VSWTC
113 /* ISC renamed swtch to susp for termios, but we'll accept either name. */
114 #if defined VSUSP && !defined VSWTCH
115 # define VSWTCH VSUSP
116 # if defined CSUSP && !defined CSWTCH
117 # define CSWTCH CSUSP
120 #if defined VSWTCH && !defined CSWTCH
121 # define CSWTCH _POSIX_VDISABLE
124 /* SunOS 5.3 loses (^Z doesn't work) if `swtch' is the same as `susp'.
125 So the default is to disable `swtch.' */
126 #if defined __sparc__ && defined __svr4__
128 # define CSWTCH _POSIX_VDISABLE
131 #if defined VWERSE && !defined VWERASE /* AIX-3.2.5 */
132 # define VWERASE VWERSE
134 #if defined VDSUSP && !defined CDSUSP
135 # define CDSUSP Control ('y')
137 #if !defined VREPRINT && defined VRPRNT /* Irix 4.0.5 */
138 # define VREPRINT VRPRNT
140 #if defined VREPRINT && !defined CRPRNT
141 # define CRPRNT Control ('r')
143 #if defined CREPRINT && !defined CRPRNT
144 # define CRPRNT Control ('r')
146 #if defined VWERASE && !defined CWERASE
147 # define CWERASE Control ('w')
149 #if defined VLNEXT && !defined CLNEXT
150 # define CLNEXT Control ('v')
152 #if defined VDISCARD && !defined VFLUSHO
153 # define VFLUSHO VDISCARD
155 #if defined VFLUSH && !defined VFLUSHO /* Ultrix 4.2 */
156 # define VFLUSHO VFLUSH
158 #if defined CTLECH && !defined ECHOCTL /* Ultrix 4.3 */
159 # define ECHOCTL CTLECH
161 #if defined TCTLECH && !defined ECHOCTL /* Ultrix 4.2 */
162 # define ECHOCTL TCTLECH
164 #if defined CRTKIL && !defined ECHOKE /* Ultrix 4.2 and 4.3 */
165 # define ECHOKE CRTKIL
167 #if defined VFLUSHO && !defined CFLUSHO
168 # define CFLUSHO Control ('o')
170 #if defined VSTATUS && !defined CSTATUS
171 # define CSTATUS Control ('t')
174 /* Which speeds to set. */
177 input_speed
, output_speed
, both_speeds
180 /* What to output and how. */
183 changed
, all
, recoverable
/* Default, -a, -g. */
186 /* Which member(s) of `struct termios' a mode uses. */
189 control
, input
, output
, local
, combination
192 /* Flags for `struct mode_info'. */
193 #define SANE_SET 1 /* Set in `sane' mode. */
194 #define SANE_UNSET 2 /* Unset in `sane' mode. */
195 #define REV 4 /* Can be turned off by prepending `-'. */
196 #define OMIT 8 /* Don't display value. */
201 const char *name
; /* Name given on command line. */
202 enum mode_type type
; /* Which structure element to change. */
203 char flags
; /* Setting and display options. */
204 unsigned long bits
; /* Bits to set for this mode. */
205 unsigned long mask
; /* Other bits to turn off for this mode. */
208 static struct mode_info mode_info
[] =
210 {"parenb", control
, REV
, PARENB
, 0},
211 {"parodd", control
, REV
, PARODD
, 0},
212 {"cs5", control
, 0, CS5
, CSIZE
},
213 {"cs6", control
, 0, CS6
, CSIZE
},
214 {"cs7", control
, 0, CS7
, CSIZE
},
215 {"cs8", control
, 0, CS8
, CSIZE
},
216 {"hupcl", control
, REV
, HUPCL
, 0},
217 {"hup", control
, REV
| OMIT
, HUPCL
, 0},
218 {"cstopb", control
, REV
, CSTOPB
, 0},
219 {"cread", control
, SANE_SET
| REV
, CREAD
, 0},
220 {"clocal", control
, REV
, CLOCAL
, 0},
222 {"crtscts", control
, REV
, CRTSCTS
, 0},
225 {"ignbrk", input
, SANE_UNSET
| REV
, IGNBRK
, 0},
226 {"brkint", input
, SANE_SET
| REV
, BRKINT
, 0},
227 {"ignpar", input
, REV
, IGNPAR
, 0},
228 {"parmrk", input
, REV
, PARMRK
, 0},
229 {"inpck", input
, REV
, INPCK
, 0},
230 {"istrip", input
, REV
, ISTRIP
, 0},
231 {"inlcr", input
, SANE_UNSET
| REV
, INLCR
, 0},
232 {"igncr", input
, SANE_UNSET
| REV
, IGNCR
, 0},
233 {"icrnl", input
, SANE_SET
| REV
, ICRNL
, 0},
234 {"ixon", input
, REV
, IXON
, 0},
235 {"ixoff", input
, SANE_UNSET
| REV
, IXOFF
, 0},
236 {"tandem", input
, REV
| OMIT
, IXOFF
, 0},
238 {"iuclc", input
, SANE_UNSET
| REV
, IUCLC
, 0},
241 {"ixany", input
, SANE_UNSET
| REV
, IXANY
, 0},
244 {"imaxbel", input
, SANE_SET
| REV
, IMAXBEL
, 0},
247 {"iutf8", input
, SANE_UNSET
| REV
, IUTF8
, 0},
250 {"opost", output
, SANE_SET
| REV
, OPOST
, 0},
252 {"olcuc", output
, SANE_UNSET
| REV
, OLCUC
, 0},
255 {"ocrnl", output
, SANE_UNSET
| REV
, OCRNL
, 0},
258 {"onlcr", output
, SANE_SET
| REV
, ONLCR
, 0},
261 {"onocr", output
, SANE_UNSET
| REV
, ONOCR
, 0},
264 {"onlret", output
, SANE_UNSET
| REV
, ONLRET
, 0},
267 {"ofill", output
, SANE_UNSET
| REV
, OFILL
, 0},
270 {"ofdel", output
, SANE_UNSET
| REV
, OFDEL
, 0},
273 {"nl1", output
, SANE_UNSET
, NL1
, NLDLY
},
274 {"nl0", output
, SANE_SET
, NL0
, NLDLY
},
277 {"cr3", output
, SANE_UNSET
, CR3
, CRDLY
},
278 {"cr2", output
, SANE_UNSET
, CR2
, CRDLY
},
279 {"cr1", output
, SANE_UNSET
, CR1
, CRDLY
},
280 {"cr0", output
, SANE_SET
, CR0
, CRDLY
},
283 {"tab3", output
, SANE_UNSET
, TAB3
, TABDLY
},
284 {"tab2", output
, SANE_UNSET
, TAB2
, TABDLY
},
285 {"tab1", output
, SANE_UNSET
, TAB1
, TABDLY
},
286 {"tab0", output
, SANE_SET
, TAB0
, TABDLY
},
289 {"tab3", output
, SANE_UNSET
, OXTABS
, 0},
293 {"bs1", output
, SANE_UNSET
, BS1
, BSDLY
},
294 {"bs0", output
, SANE_SET
, BS0
, BSDLY
},
297 {"vt1", output
, SANE_UNSET
, VT1
, VTDLY
},
298 {"vt0", output
, SANE_SET
, VT0
, VTDLY
},
301 {"ff1", output
, SANE_UNSET
, FF1
, FFDLY
},
302 {"ff0", output
, SANE_SET
, FF0
, FFDLY
},
305 {"isig", local
, SANE_SET
| REV
, ISIG
, 0},
306 {"icanon", local
, SANE_SET
| REV
, ICANON
, 0},
308 {"iexten", local
, SANE_SET
| REV
, IEXTEN
, 0},
310 {"echo", local
, SANE_SET
| REV
, ECHO
, 0},
311 {"echoe", local
, SANE_SET
| REV
, ECHOE
, 0},
312 {"crterase", local
, REV
| OMIT
, ECHOE
, 0},
313 {"echok", local
, SANE_SET
| REV
, ECHOK
, 0},
314 {"echonl", local
, SANE_UNSET
| REV
, ECHONL
, 0},
315 {"noflsh", local
, SANE_UNSET
| REV
, NOFLSH
, 0},
317 {"xcase", local
, SANE_UNSET
| REV
, XCASE
, 0},
320 {"tostop", local
, SANE_UNSET
| REV
, TOSTOP
, 0},
323 {"echoprt", local
, SANE_UNSET
| REV
, ECHOPRT
, 0},
324 {"prterase", local
, REV
| OMIT
, ECHOPRT
, 0},
327 {"echoctl", local
, SANE_SET
| REV
, ECHOCTL
, 0},
328 {"ctlecho", local
, REV
| OMIT
, ECHOCTL
, 0},
331 {"echoke", local
, SANE_SET
| REV
, ECHOKE
, 0},
332 {"crtkill", local
, REV
| OMIT
, ECHOKE
, 0},
335 {"evenp", combination
, REV
| OMIT
, 0, 0},
336 {"parity", combination
, REV
| OMIT
, 0, 0},
337 {"oddp", combination
, REV
| OMIT
, 0, 0},
338 {"nl", combination
, REV
| OMIT
, 0, 0},
339 {"ek", combination
, OMIT
, 0, 0},
340 {"sane", combination
, OMIT
, 0, 0},
341 {"cooked", combination
, REV
| OMIT
, 0, 0},
342 {"raw", combination
, REV
| OMIT
, 0, 0},
343 {"pass8", combination
, REV
| OMIT
, 0, 0},
344 {"litout", combination
, REV
| OMIT
, 0, 0},
345 {"cbreak", combination
, REV
| OMIT
, 0, 0},
347 {"decctlq", combination
, REV
| OMIT
, 0, 0},
349 #if defined TABDLY || defined OXTABS
350 {"tabs", combination
, REV
| OMIT
, 0, 0},
352 #if defined XCASE && defined IUCLC && defined OLCUC
353 {"lcase", combination
, REV
| OMIT
, 0, 0},
354 {"LCASE", combination
, REV
| OMIT
, 0, 0},
356 {"crt", combination
, OMIT
, 0, 0},
357 {"dec", combination
, OMIT
, 0, 0},
359 {NULL
, control
, 0, 0, 0}
362 /* Control character settings. */
365 const char *name
; /* Name given on command line. */
366 cc_t saneval
; /* Value to set for `stty sane'. */
367 size_t offset
; /* Offset in c_cc. */
370 /* Control characters. */
372 static struct control_info control_info
[] =
374 {"intr", CINTR
, VINTR
},
375 {"quit", CQUIT
, VQUIT
},
376 {"erase", CERASE
, VERASE
},
377 {"kill", CKILL
, VKILL
},
381 {"eol2", CEOL2
, VEOL2
},
384 {"swtch", CSWTCH
, VSWTCH
},
386 {"start", CSTART
, VSTART
},
387 {"stop", CSTOP
, VSTOP
},
388 {"susp", CSUSP
, VSUSP
},
390 {"dsusp", CDSUSP
, VDSUSP
},
393 {"rprnt", CRPRNT
, VREPRINT
},
395 # ifdef CREPRINT /* HPUX 10.20 needs this */
396 {"rprnt", CRPRNT
, CREPRINT
},
400 {"werase", CWERASE
, VWERASE
},
403 {"lnext", CLNEXT
, VLNEXT
},
406 {"flush", CFLUSHO
, VFLUSHO
},
409 {"status", CSTATUS
, VSTATUS
},
412 /* These must be last because of the display routines. */
418 static char const *visible (cc_t ch
);
419 static unsigned long int baud_to_value (speed_t speed
);
420 static bool recover_mode (char const *arg
, struct termios
*mode
);
421 static int screen_columns (void);
422 static bool set_mode (struct mode_info
*info
, bool reversed
,
423 struct termios
*mode
);
424 static unsigned long int integer_arg (const char *s
, unsigned long int max
);
425 static speed_t
string_to_baud (const char *arg
);
426 static tcflag_t
*mode_type_flag (enum mode_type type
, struct termios
*mode
);
427 static void display_all (struct termios
*mode
, char const *device_name
);
428 static void display_changed (struct termios
*mode
);
429 static void display_recoverable (struct termios
*mode
);
430 static void display_settings (enum output_type output_type
,
431 struct termios
*mode
,
432 const char *device_name
);
433 static void display_speed (struct termios
*mode
, bool fancy
);
434 static void display_window_size (bool fancy
, char const *device_name
);
435 static void sane_mode (struct termios
*mode
);
436 static void set_control_char (struct control_info
*info
,
438 struct termios
*mode
);
439 static void set_speed (enum speed_setting type
, const char *arg
,
440 struct termios
*mode
);
441 static void set_window_size (int rows
, int cols
, char const *device_name
);
443 /* The width of the screen, for output wrapping. */
446 /* Current position, to know when to wrap. */
447 static int current_col
;
449 static struct option longopts
[] =
451 {"all", no_argument
, NULL
, 'a'},
452 {"save", no_argument
, NULL
, 'g'},
453 {"file", required_argument
, NULL
, 'F'},
454 {GETOPT_HELP_OPTION_DECL
},
455 {GETOPT_VERSION_OPTION_DECL
},
459 /* The name this program was run with. */
462 static void wrapf (const char *message
, ...)
463 __attribute__ ((__format__ (__printf__
, 1, 2)));
465 /* Print format string MESSAGE and optional args.
466 Wrap to next line first if it won't fit.
467 Print a space first unless MESSAGE will start a new line. */
470 wrapf (const char *message
,...)
476 va_start (args
, message
);
477 buflen
= vasprintf (&buf
, message
, args
);
485 if (max_col
- current_col
< buflen
)
499 current_col
+= buflen
;
505 if (status
!= EXIT_SUCCESS
)
506 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
511 Usage: %s [-F DEVICE] [--file=DEVICE] [SETTING]...\n\
512 or: %s [-F DEVICE] [--file=DEVICE] [-a|--all]\n\
513 or: %s [-F DEVICE] [--file=DEVICE] [-g|--save]\n\
515 program_name
, program_name
, program_name
);
517 Print or change terminal characteristics.\n\
519 -a, --all print all current settings in human-readable form\n\
520 -g, --save print all current settings in a stty-readable form\n\
521 -F, --file=DEVICE open and use the specified DEVICE instead of stdin\n\
523 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
524 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
527 Optional - before SETTING indicates negation. An * marks non-POSIX\n\
528 settings. The underlying system defines which settings are available.\n\
532 Special characters:\n\
533 * dsusp CHAR CHAR will send a terminal stop signal once input flushed\n\
534 eof CHAR CHAR will send an end of file (terminate the input)\n\
535 eol CHAR CHAR will end the line\n\
538 * eol2 CHAR alternate CHAR for ending the line\n\
539 erase CHAR CHAR will erase the last character typed\n\
540 intr CHAR CHAR will send an interrupt signal\n\
541 kill CHAR CHAR will erase the current line\n\
544 * lnext CHAR CHAR will enter the next character quoted\n\
545 quit CHAR CHAR will send a quit signal\n\
546 * rprnt CHAR CHAR will redraw the current line\n\
547 start CHAR CHAR will restart the output after stopping it\n\
550 stop CHAR CHAR will stop the output\n\
551 susp CHAR CHAR will send a terminal stop signal\n\
552 * swtch CHAR CHAR will switch to a different shell layer\n\
553 * werase CHAR CHAR will erase the last word typed\n\
558 N set the input and output speeds to N bauds\n\
559 * cols N tell the kernel that the terminal has N columns\n\
560 * columns N same as cols N\n\
563 ispeed N set the input speed to N\n\
564 * line N use line discipline N\n\
565 min N with -icanon, set N characters minimum for a completed read\n\
566 ospeed N set the output speed to N\n\
569 * rows N tell the kernel that the terminal has N rows\n\
570 * size print the number of rows and columns according to the kernel\n\
571 speed print the terminal speed\n\
572 time N with -icanon, set read timeout of N tenths of a second\n\
577 [-]clocal disable modem control signals\n\
578 [-]cread allow input to be received\n\
579 * [-]crtscts enable RTS/CTS handshaking\n\
580 csN set character size to N bits, N in [5..8]\n\
583 [-]cstopb use two stop bits per character (one with `-')\n\
584 [-]hup send a hangup signal when the last process closes the tty\n\
585 [-]hupcl same as [-]hup\n\
586 [-]parenb generate parity bit in output and expect parity bit in input\n\
587 [-]parodd set odd parity (even with `-')\n\
592 [-]brkint breaks cause an interrupt signal\n\
593 [-]icrnl translate carriage return to newline\n\
594 [-]ignbrk ignore break characters\n\
595 [-]igncr ignore carriage return\n\
598 [-]ignpar ignore characters with parity errors\n\
599 * [-]imaxbel beep and do not flush a full input buffer on a character\n\
600 [-]inlcr translate newline to carriage return\n\
601 [-]inpck enable input parity checking\n\
602 [-]istrip clear high (8th) bit of input characters\n\
605 * [-]iutf8 assume input characters are UTF-8 encoded\n\
608 * [-]iuclc translate uppercase characters to lowercase\n\
609 * [-]ixany let any character restart output, not only start character\n\
610 [-]ixoff enable sending of start/stop characters\n\
611 [-]ixon enable XON/XOFF flow control\n\
612 [-]parmrk mark parity errors (with a 255-0-character sequence)\n\
613 [-]tandem same as [-]ixoff\n\
618 * bsN backspace delay style, N in [0..1]\n\
619 * crN carriage return delay style, N in [0..3]\n\
620 * ffN form feed delay style, N in [0..1]\n\
621 * nlN newline delay style, N in [0..1]\n\
624 * [-]ocrnl translate carriage return to newline\n\
625 * [-]ofdel use delete characters for fill instead of null characters\n\
626 * [-]ofill use fill (padding) characters instead of timing for delays\n\
627 * [-]olcuc translate lowercase characters to uppercase\n\
628 * [-]onlcr translate newline to carriage return-newline\n\
629 * [-]onlret newline performs a carriage return\n\
632 * [-]onocr do not print carriage returns in the first column\n\
633 [-]opost postprocess output\n\
634 * tabN horizontal tab delay style, N in [0..3]\n\
635 * tabs same as tab0\n\
636 * -tabs same as tab3\n\
637 * vtN vertical tab delay style, N in [0..1]\n\
642 [-]crterase echo erase characters as backspace-space-backspace\n\
643 * crtkill kill all line by obeying the echoprt and echoe settings\n\
644 * -crtkill kill all line by obeying the echoctl and echok settings\n\
647 * [-]ctlecho echo control characters in hat notation (`^c')\n\
648 [-]echo echo input characters\n\
649 * [-]echoctl same as [-]ctlecho\n\
650 [-]echoe same as [-]crterase\n\
651 [-]echok echo a newline after a kill character\n\
654 * [-]echoke same as [-]crtkill\n\
655 [-]echonl echo newline even if not echoing other characters\n\
656 * [-]echoprt echo erased characters backward, between `\\' and '/'\n\
657 [-]icanon enable erase, kill, werase, and rprnt special characters\n\
658 [-]iexten enable non-POSIX special characters\n\
661 [-]isig enable interrupt, quit, and suspend special characters\n\
662 [-]noflsh disable flushing after interrupt and quit special characters\n\
663 * [-]prterase same as [-]echoprt\n\
664 * [-]tostop stop background jobs that try to write to the terminal\n\
665 * [-]xcase with icanon, escape with `\\' for uppercase characters\n\
669 Combination settings:\n\
670 * [-]LCASE same as [-]lcase\n\
671 cbreak same as -icanon\n\
672 -cbreak same as icanon\n\
675 cooked same as brkint ignpar istrip icrnl ixon opost isig\n\
676 icanon, eof and eol characters to their default values\n\
677 -cooked same as raw\n\
678 crt same as echoe echoctl echoke\n\
681 dec same as echoe echoctl echoke -ixany intr ^c erase 0177\n\
683 * [-]decctlq same as [-]ixany\n\
684 ek erase and kill characters to their default values\n\
685 evenp same as parenb -parodd cs7\n\
688 -evenp same as -parenb cs8\n\
689 * [-]lcase same as xcase iuclc olcuc\n\
690 litout same as -parenb -istrip -opost cs8\n\
691 -litout same as parenb istrip opost cs7\n\
692 nl same as -icrnl -onlcr\n\
693 -nl same as icrnl -inlcr -igncr onlcr -ocrnl -onlret\n\
696 oddp same as parenb parodd cs7\n\
697 -oddp same as -parenb cs8\n\
698 [-]parity same as [-]evenp\n\
699 pass8 same as -parenb -istrip cs8\n\
700 -pass8 same as parenb istrip cs7\n\
703 raw same as -ignbrk -brkint -ignpar -parmrk -inpck -istrip\n\
704 -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany\n\
705 -imaxbel -opost -isig -icanon -xcase min 1 time 0\n\
706 -raw same as cooked\n\
709 sane same as cread -ignbrk brkint -inlcr -igncr icrnl -iutf8\n\
710 -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr\n\
711 -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0\n\
712 isig icanon iexten echo echoe echok -echonl -noflsh\n\
713 -xcase -tostop -echoprt echoctl echoke, all special\n\
714 characters to their default values.\n\
718 Handle the tty line connected to standard input. Without arguments,\n\
719 prints baud rate, line discipline, and deviations from stty sane. In\n\
720 settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
721 127; special values ^- or undef used to disable special characters.\n\
723 emit_bug_reporting_address ();
729 main (int argc
, char **argv
)
731 /* Initialize to all zeroes so there is no risk memcmp will report a
732 spurious difference in an uninitialized portion of the structure. */
733 struct termios mode
= { 0, };
735 enum output_type output_type
;
739 bool require_set_attr
;
742 bool recoverable_output
;
745 char *file_name
= NULL
;
746 const char *device_name
;
748 initialize_main (&argc
, &argv
);
749 program_name
= argv
[0];
750 setlocale (LC_ALL
, "");
751 bindtextdomain (PACKAGE
, LOCALEDIR
);
752 textdomain (PACKAGE
);
754 atexit (close_stdout
);
756 output_type
= changed
;
757 verbose_output
= false;
758 recoverable_output
= false;
760 /* Don't print error messages for unrecognized options. */
763 /* If any new options are ever added to stty, the short options MUST
764 NOT allow any ambiguity with the stty settings. For example, the
765 stty setting "-gagFork" would not be feasible, since it will be
766 parsed as "-g -a -g -F ork". If you change anything about how
767 stty parses options, be sure it still works with combinations of
768 short and long options, --, POSIXLY_CORRECT, etc. */
770 while ((optc
= getopt_long (argc
- argi
, argv
+ argi
, "-agF:",
777 verbose_output
= true;
782 recoverable_output
= true;
783 output_type
= recoverable
;
788 error (EXIT_FAILURE
, 0, _("only one device may be specified"));
792 case_GETOPT_HELP_CHAR
;
794 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
799 /* Skip the argument containing this unrecognized option;
800 the 2nd pass will analyze it. */
803 /* Restart getopt_long from the first unskipped argument. */
810 /* Clear fully-parsed arguments, so they don't confuse the 2nd pass. */
811 while (opti
< optind
)
812 argv
[argi
+ opti
++] = NULL
;
815 /* Specifying both -a and -g gets an error. */
816 if (verbose_output
& recoverable_output
)
817 error (EXIT_FAILURE
, 0,
818 _("the options for verbose and stty-readable output styles are\n"
819 "mutually exclusive"));
821 /* Specifying any other arguments with -a or -g gets an error. */
822 if (!noargs
& (verbose_output
| recoverable_output
))
823 error (EXIT_FAILURE
, 0,
824 _("when specifying an output style, modes may not be set"));
826 /* FIXME: it'd be better not to open the file until we've verified
827 that all arguments are valid. Otherwise, we could end up doing
828 only some of the requested operations and then failing, probably
829 leaving things in an undesirable state. */
834 device_name
= file_name
;
835 if (fd_reopen (STDIN_FILENO
, device_name
, O_RDONLY
| O_NONBLOCK
, 0) < 0)
836 error (EXIT_FAILURE
, errno
, "%s", device_name
);
837 if ((fdflags
= fcntl (STDIN_FILENO
, F_GETFL
)) == -1
838 || fcntl (STDIN_FILENO
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
839 error (EXIT_FAILURE
, errno
, _("%s: couldn't reset non-blocking mode"),
843 device_name
= _("standard input");
845 if (tcgetattr (STDIN_FILENO
, &mode
))
846 error (EXIT_FAILURE
, errno
, "%s", device_name
);
848 if (verbose_output
| recoverable_output
| noargs
)
850 max_col
= screen_columns ();
852 display_settings (output_type
, &mode
, device_name
);
856 speed_was_set
= false;
857 require_set_attr
= false;
858 for (k
= 1; k
< argc
; k
++)
860 char const *arg
= argv
[k
];
861 bool match_found
= false;
862 bool reversed
= false;
873 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
875 if (STREQ (arg
, mode_info
[i
].name
))
877 match_found
= set_mode (&mode_info
[i
], reversed
, &mode
);
878 require_set_attr
= true;
882 if (!match_found
& reversed
)
884 error (0, 0, _("invalid argument %s"), quote (arg
- 1));
885 usage (EXIT_FAILURE
);
889 for (i
= 0; control_info
[i
].name
!= NULL
; ++i
)
891 if (STREQ (arg
, control_info
[i
].name
))
895 error (0, 0, _("missing argument to %s"), quote (arg
));
896 usage (EXIT_FAILURE
);
900 set_control_char (&control_info
[i
], argv
[k
], &mode
);
901 require_set_attr
= true;
908 if (STREQ (arg
, "ispeed"))
912 error (0, 0, _("missing argument to %s"), quote (arg
));
913 usage (EXIT_FAILURE
);
916 set_speed (input_speed
, argv
[k
], &mode
);
917 speed_was_set
= true;
918 require_set_attr
= true;
920 else if (STREQ (arg
, "ospeed"))
924 error (0, 0, _("missing argument to %s"), quote (arg
));
925 usage (EXIT_FAILURE
);
928 set_speed (output_speed
, argv
[k
], &mode
);
929 speed_was_set
= true;
930 require_set_attr
= true;
933 else if (STREQ (arg
, "rows"))
937 error (0, 0, _("missing argument to %s"), quote (arg
));
938 usage (EXIT_FAILURE
);
941 set_window_size (integer_arg (argv
[k
], INT_MAX
), -1,
944 else if (STREQ (arg
, "cols")
945 || STREQ (arg
, "columns"))
949 error (0, 0, _("missing argument to %s"), quote (arg
));
950 usage (EXIT_FAILURE
);
953 set_window_size (-1, integer_arg (argv
[k
], INT_MAX
),
956 else if (STREQ (arg
, "size"))
958 max_col
= screen_columns ();
960 display_window_size (false, device_name
);
964 else if (STREQ (arg
, "line"))
966 unsigned long int value
;
969 error (0, 0, _("missing argument to %s"), quote (arg
));
970 usage (EXIT_FAILURE
);
973 mode
.c_line
= value
= integer_arg (argv
[k
], ULONG_MAX
);
974 if (mode
.c_line
!= value
)
975 error (0, 0, _("invalid line discipline %s"), quote (argv
[k
]));
976 require_set_attr
= true;
979 else if (STREQ (arg
, "speed"))
981 max_col
= screen_columns ();
982 display_speed (&mode
, false);
984 else if (string_to_baud (arg
) != (speed_t
) -1)
986 set_speed (both_speeds
, arg
, &mode
);
987 speed_was_set
= true;
988 require_set_attr
= true;
992 if (! recover_mode (arg
, &mode
))
994 error (0, 0, _("invalid argument %s"), quote (arg
));
995 usage (EXIT_FAILURE
);
997 require_set_attr
= true;
1002 if (require_set_attr
)
1004 /* Initialize to all zeroes so there is no risk memcmp will report a
1005 spurious difference in an uninitialized portion of the structure. */
1006 struct termios new_mode
= { 0, };
1008 if (tcsetattr (STDIN_FILENO
, TCSADRAIN
, &mode
))
1009 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1011 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
1012 it performs *any* of the requested operations. This means it
1013 can report `success' when it has actually failed to perform
1014 some proper subset of the requested operations. To detect
1015 this partial failure, get the current terminal attributes and
1016 compare them to the requested ones. */
1018 if (tcgetattr (STDIN_FILENO
, &new_mode
))
1019 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1021 /* Normally, one shouldn't use memcmp to compare structures that
1022 may have `holes' containing uninitialized data, but we have been
1023 careful to initialize the storage of these two variables to all
1024 zeroes. One might think it more efficient simply to compare the
1025 modified fields, but that would require enumerating those fields --
1026 and not all systems have the same fields in this structure. */
1028 if (memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1031 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1032 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1033 sometimes (m1 != m2). The only difference is in the four bits
1034 of the c_cflag field corresponding to the baud rate. To save
1035 Sun users a little confusion, don't report an error if this
1036 happens. But suppress the error only if we haven't tried to
1037 set the baud rate explicitly -- otherwise we'd never give an
1038 error for a true failure to set the baud rate. */
1040 new_mode
.c_cflag
&= (~CIBAUD
);
1041 if (speed_was_set
|| memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1044 error (EXIT_FAILURE
, 0,
1045 _("%s: unable to perform all requested operations"),
1050 printf (_("new_mode: mode\n"));
1051 for (i
= 0; i
< sizeof (new_mode
); i
++)
1052 printf ("0x%02x: 0x%02x\n",
1053 *(((unsigned char *) &new_mode
) + i
),
1054 *(((unsigned char *) &mode
) + i
));
1061 exit (EXIT_SUCCESS
);
1064 /* Return false if not applied because not reversible; otherwise
1068 set_mode (struct mode_info
*info
, bool reversed
, struct termios
*mode
)
1072 if (reversed
&& (info
->flags
& REV
) == 0)
1075 bitsp
= mode_type_flag (info
->type
, mode
);
1079 /* Combination mode. */
1080 if (STREQ (info
->name
, "evenp") || STREQ (info
->name
, "parity"))
1083 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1085 mode
->c_cflag
= (mode
->c_cflag
& ~PARODD
& ~CSIZE
) | PARENB
| CS7
;
1087 else if (STREQ (info
->name
, "oddp"))
1090 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1092 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARODD
| PARENB
;
1094 else if (STREQ (info
->name
, "nl"))
1098 mode
->c_iflag
= (mode
->c_iflag
| ICRNL
) & ~INLCR
& ~IGNCR
;
1099 mode
->c_oflag
= (mode
->c_oflag
1114 mode
->c_iflag
= mode
->c_iflag
& ~ICRNL
;
1116 mode
->c_oflag
= mode
->c_oflag
& ~ONLCR
;
1120 else if (STREQ (info
->name
, "ek"))
1122 mode
->c_cc
[VERASE
] = CERASE
;
1123 mode
->c_cc
[VKILL
] = CKILL
;
1125 else if (STREQ (info
->name
, "sane"))
1127 else if (STREQ (info
->name
, "cbreak"))
1130 mode
->c_lflag
|= ICANON
;
1132 mode
->c_lflag
&= ~ICANON
;
1134 else if (STREQ (info
->name
, "pass8"))
1138 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1139 mode
->c_iflag
|= ISTRIP
;
1143 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1144 mode
->c_iflag
&= ~ISTRIP
;
1147 else if (STREQ (info
->name
, "litout"))
1151 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1152 mode
->c_iflag
|= ISTRIP
;
1153 mode
->c_oflag
|= OPOST
;
1157 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1158 mode
->c_iflag
&= ~ISTRIP
;
1159 mode
->c_oflag
&= ~OPOST
;
1162 else if (STREQ (info
->name
, "raw") || STREQ (info
->name
, "cooked"))
1164 if ((info
->name
[0] == 'r' && reversed
)
1165 || (info
->name
[0] == 'c' && !reversed
))
1168 mode
->c_iflag
|= BRKINT
| IGNPAR
| ISTRIP
| ICRNL
| IXON
;
1169 mode
->c_oflag
|= OPOST
;
1170 mode
->c_lflag
|= ISIG
| ICANON
;
1172 mode
->c_cc
[VEOF
] = CEOF
;
1175 mode
->c_cc
[VEOL
] = CEOL
;
1182 mode
->c_oflag
&= ~OPOST
;
1183 mode
->c_lflag
&= ~(ISIG
| ICANON
1188 mode
->c_cc
[VMIN
] = 1;
1189 mode
->c_cc
[VTIME
] = 0;
1193 else if (STREQ (info
->name
, "decctlq"))
1196 mode
->c_iflag
|= IXANY
;
1198 mode
->c_iflag
&= ~IXANY
;
1202 else if (STREQ (info
->name
, "tabs"))
1205 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB3
;
1207 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB0
;
1211 else if (STREQ (info
->name
, "tabs"))
1214 mode
->c_oflag
= mode
->c_oflag
| OXTABS
;
1216 mode
->c_oflag
= mode
->c_oflag
& ~OXTABS
;
1220 #if defined XCASE && defined IUCLC && defined OLCUC
1221 else if (STREQ (info
->name
, "lcase")
1222 || STREQ (info
->name
, "LCASE"))
1226 mode
->c_lflag
&= ~XCASE
;
1227 mode
->c_iflag
&= ~IUCLC
;
1228 mode
->c_oflag
&= ~OLCUC
;
1232 mode
->c_lflag
|= XCASE
;
1233 mode
->c_iflag
|= IUCLC
;
1234 mode
->c_oflag
|= OLCUC
;
1238 else if (STREQ (info
->name
, "crt"))
1239 mode
->c_lflag
|= ECHOE
1247 else if (STREQ (info
->name
, "dec"))
1249 mode
->c_cc
[VINTR
] = 3; /* ^C */
1250 mode
->c_cc
[VERASE
] = 127; /* DEL */
1251 mode
->c_cc
[VKILL
] = 21; /* ^U */
1252 mode
->c_lflag
|= ECHOE
1261 mode
->c_iflag
&= ~IXANY
;
1266 *bitsp
= *bitsp
& ~info
->mask
& ~info
->bits
;
1268 *bitsp
= (*bitsp
& ~info
->mask
) | info
->bits
;
1274 set_control_char (struct control_info
*info
, const char *arg
,
1275 struct termios
*mode
)
1277 unsigned long int value
;
1279 if (STREQ (info
->name
, "min") || STREQ (info
->name
, "time"))
1280 value
= integer_arg (arg
, TYPE_MAXIMUM (cc_t
));
1281 else if (arg
[0] == '\0' || arg
[1] == '\0')
1282 value
= to_uchar (arg
[0]);
1283 else if (STREQ (arg
, "^-") || STREQ (arg
, "undef"))
1284 value
= _POSIX_VDISABLE
;
1285 else if (arg
[0] == '^' && arg
[1] != '\0') /* Ignore any trailing junk. */
1290 value
= to_uchar (arg
[1]) & ~0140; /* Non-letters get weird results. */
1293 value
= integer_arg (arg
, TYPE_MAXIMUM (cc_t
));
1294 mode
->c_cc
[info
->offset
] = value
;
1298 set_speed (enum speed_setting type
, const char *arg
, struct termios
*mode
)
1302 baud
= string_to_baud (arg
);
1303 if (type
== input_speed
|| type
== both_speeds
)
1304 cfsetispeed (mode
, baud
);
1305 if (type
== output_speed
|| type
== both_speeds
)
1306 cfsetospeed (mode
, baud
);
1312 get_win_size (int fd
, struct winsize
*win
)
1314 int err
= ioctl (fd
, TIOCGWINSZ
, (char *) win
);
1319 set_window_size (int rows
, int cols
, char const *device_name
)
1323 if (get_win_size (STDIN_FILENO
, &win
))
1325 if (errno
!= EINVAL
)
1326 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1327 memset (&win
, 0, sizeof (win
));
1336 /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote:
1337 The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.
1338 This comment from sys/ttold.h describes Sun's twisted logic - a better
1339 test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).
1340 At any rate, the problem is gone in Solaris 2.x.
1342 Unfortunately, the old TIOCSSIZE code does collide with TIOCSWINSZ,
1343 but they can be disambiguated by checking whether a "struct ttysize"
1344 structure's "ts_lines" field is greater than 64K or not. If so,
1345 it's almost certainly a "struct winsize" instead.
1347 At any rate, the bug manifests itself when ws_row == 0; the symptom is
1348 that ws_row is set to ws_col, and ws_col is set to (ws_xpixel<<16) +
1349 ws_ypixel. Since GNU stty sets rows and columns separately, this bug
1350 caused "stty rows 0 cols 0" to set rows to cols and cols to 0, while
1351 "stty cols 0 rows 0" would do the right thing. On a little-endian
1352 machine like the sun386i, the problem is the same, but for ws_col == 0.
1354 The workaround is to do the ioctl once with row and col = 1 to set the
1355 pixel info, and then do it again using a TIOCSSIZE to set rows/cols. */
1357 if (win
.ws_row
== 0 || win
.ws_col
== 0)
1359 struct ttysize ttysz
;
1361 ttysz
.ts_lines
= win
.ws_row
;
1362 ttysz
.ts_cols
= win
.ws_col
;
1367 if (ioctl (STDIN_FILENO
, TIOCSWINSZ
, (char *) &win
))
1368 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1370 if (ioctl (STDIN_FILENO
, TIOCSSIZE
, (char *) &ttysz
))
1371 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1376 if (ioctl (STDIN_FILENO
, TIOCSWINSZ
, (char *) &win
))
1377 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1381 display_window_size (bool fancy
, char const *device_name
)
1385 if (get_win_size (STDIN_FILENO
, &win
))
1387 if (errno
!= EINVAL
)
1388 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1390 error (EXIT_FAILURE
, 0,
1391 _("%s: no size information for this device"), device_name
);
1395 wrapf (fancy
? "rows %d; columns %d;" : "%d %d\n",
1396 win
.ws_row
, win
.ws_col
);
1404 screen_columns (void)
1409 /* With Solaris 2.[123], this ioctl fails and errno is set to
1410 EINVAL for telnet (but not rlogin) sessions.
1411 On ISC 3.0, it fails for the console and the serial port
1412 (but it works for ptys).
1413 It can also fail on any system when stdout isn't a tty.
1414 In case of any failure, just use the default. */
1415 if (get_win_size (STDOUT_FILENO
, &win
) == 0 && 0 < win
.ws_col
)
1419 /* Use $COLUMNS if it's in [1..INT_MAX]. */
1420 char *col_string
= getenv ("COLUMNS");
1422 if (!(col_string
!= NULL
1423 && xstrtol (col_string
, NULL
, 0, &n_columns
, "") == LONGINT_OK
1425 && n_columns
<= INT_MAX
))
1432 mode_type_flag (enum mode_type type
, struct termios
*mode
)
1437 return &mode
->c_cflag
;
1440 return &mode
->c_iflag
;
1443 return &mode
->c_oflag
;
1446 return &mode
->c_lflag
;
1457 display_settings (enum output_type output_type
, struct termios
*mode
,
1458 char const *device_name
)
1460 switch (output_type
)
1463 display_changed (mode
);
1467 display_all (mode
, device_name
);
1471 display_recoverable (mode
);
1477 display_changed (struct termios
*mode
)
1483 enum mode_type prev_type
= control
;
1485 display_speed (mode
, true);
1487 wrapf ("line = %d;", mode
->c_line
);
1493 for (i
= 0; !STREQ (control_info
[i
].name
, "min"); ++i
)
1495 if (mode
->c_cc
[control_info
[i
].offset
] == control_info
[i
].saneval
)
1497 /* If swtch is the same as susp, don't print both. */
1499 if (STREQ (control_info
[i
].name
, "swtch"))
1502 /* If eof uses the same slot as min, only print whichever applies. */
1504 if ((mode
->c_lflag
& ICANON
) == 0
1505 && (STREQ (control_info
[i
].name
, "eof")
1506 || STREQ (control_info
[i
].name
, "eol")))
1511 wrapf ("%s = %s;", control_info
[i
].name
,
1512 visible (mode
->c_cc
[control_info
[i
].offset
]));
1514 if ((mode
->c_lflag
& ICANON
) == 0)
1516 wrapf ("min = %lu; time = %lu;\n",
1517 (unsigned long int) mode
->c_cc
[VMIN
],
1518 (unsigned long int) mode
->c_cc
[VTIME
]);
1520 else if (!empty_line
)
1525 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1527 if (mode_info
[i
].flags
& OMIT
)
1529 if (mode_info
[i
].type
!= prev_type
)
1537 prev_type
= mode_info
[i
].type
;
1540 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1541 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1542 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1544 if (mode_info
[i
].flags
& SANE_UNSET
)
1546 wrapf ("%s", mode_info
[i
].name
);
1550 else if ((mode_info
[i
].flags
& (SANE_SET
| REV
)) == (SANE_SET
| REV
))
1552 wrapf ("-%s", mode_info
[i
].name
);
1562 display_all (struct termios
*mode
, char const *device_name
)
1567 enum mode_type prev_type
= control
;
1569 display_speed (mode
, true);
1571 display_window_size (true, device_name
);
1574 wrapf ("line = %d;", mode
->c_line
);
1579 for (i
= 0; ! STREQ (control_info
[i
].name
, "min"); ++i
)
1581 /* If swtch is the same as susp, don't print both. */
1583 if (STREQ (control_info
[i
].name
, "swtch"))
1586 /* If eof uses the same slot as min, only print whichever applies. */
1588 if ((mode
->c_lflag
& ICANON
) == 0
1589 && (STREQ (control_info
[i
].name
, "eof")
1590 || STREQ (control_info
[i
].name
, "eol")))
1593 wrapf ("%s = %s;", control_info
[i
].name
,
1594 visible (mode
->c_cc
[control_info
[i
].offset
]));
1597 if ((mode
->c_lflag
& ICANON
) == 0)
1599 wrapf ("min = %lu; time = %lu;",
1600 (unsigned long int) mode
->c_cc
[VMIN
],
1601 (unsigned long int) mode
->c_cc
[VTIME
]);
1602 if (current_col
!= 0)
1606 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1608 if (mode_info
[i
].flags
& OMIT
)
1610 if (mode_info
[i
].type
!= prev_type
)
1614 prev_type
= mode_info
[i
].type
;
1617 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1618 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1619 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1620 wrapf ("%s", mode_info
[i
].name
);
1621 else if (mode_info
[i
].flags
& REV
)
1622 wrapf ("-%s", mode_info
[i
].name
);
1629 display_speed (struct termios
*mode
, bool fancy
)
1631 if (cfgetispeed (mode
) == 0 || cfgetispeed (mode
) == cfgetospeed (mode
))
1632 wrapf (fancy
? "speed %lu baud;" : "%lu\n",
1633 baud_to_value (cfgetospeed (mode
)));
1635 wrapf (fancy
? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n",
1636 baud_to_value (cfgetispeed (mode
)),
1637 baud_to_value (cfgetospeed (mode
)));
1643 display_recoverable (struct termios
*mode
)
1647 printf ("%lx:%lx:%lx:%lx",
1648 (unsigned long int) mode
->c_iflag
,
1649 (unsigned long int) mode
->c_oflag
,
1650 (unsigned long int) mode
->c_cflag
,
1651 (unsigned long int) mode
->c_lflag
);
1652 for (i
= 0; i
< NCCS
; ++i
)
1653 printf (":%lx", (unsigned long int) mode
->c_cc
[i
]);
1658 recover_mode (char const *arg
, struct termios
*mode
)
1662 unsigned long int chr
;
1663 unsigned long int iflag
, oflag
, cflag
, lflag
;
1665 /* Scan into temporaries since it is too much trouble to figure out
1666 the right format for `tcflag_t'. */
1667 if (sscanf (arg
, "%lx:%lx:%lx:%lx%n",
1668 &iflag
, &oflag
, &cflag
, &lflag
, &n
) != 4)
1670 mode
->c_iflag
= iflag
;
1671 mode
->c_oflag
= oflag
;
1672 mode
->c_cflag
= cflag
;
1673 mode
->c_lflag
= lflag
;
1674 if (mode
->c_iflag
!= iflag
1675 || mode
->c_oflag
!= oflag
1676 || mode
->c_cflag
!= cflag
1677 || mode
->c_lflag
!= lflag
)
1680 for (i
= 0; i
< NCCS
; ++i
)
1682 if (sscanf (arg
, ":%lx%n", &chr
, &n
) != 1)
1684 mode
->c_cc
[i
] = chr
;
1685 if (mode
->c_cc
[i
] != chr
)
1690 /* Fail if there are too many fields. */
1699 const char *string
; /* ASCII representation. */
1700 speed_t speed
; /* Internal form. */
1701 unsigned long int value
; /* Numeric value. */
1704 static struct speed_map speeds
[] =
1711 {"134.5", B134
, 134},
1716 {"1200", B1200
, 1200},
1717 {"1800", B1800
, 1800},
1718 {"2400", B2400
, 2400},
1719 {"4800", B4800
, 4800},
1720 {"9600", B9600
, 9600},
1721 {"19200", B19200
, 19200},
1722 {"38400", B38400
, 38400},
1723 {"exta", B19200
, 19200},
1724 {"extb", B38400
, 38400},
1726 {"57600", B57600
, 57600},
1729 {"115200", B115200
, 115200},
1732 {"230400", B230400
, 230400},
1735 {"460800", B460800
, 460800},
1738 {"500000", B500000
, 500000},
1741 {"576000", B576000
, 576000},
1744 {"921600", B921600
, 921600},
1747 {"1000000", B1000000
, 1000000},
1750 {"1152000", B1152000
, 1152000},
1753 {"1500000", B1500000
, 1500000},
1756 {"2000000", B2000000
, 2000000},
1759 {"2500000", B2500000
, 2500000},
1762 {"3000000", B3000000
, 3000000},
1765 {"3500000", B3500000
, 3500000},
1768 {"4000000", B4000000
, 4000000},
1774 string_to_baud (const char *arg
)
1778 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1779 if (STREQ (arg
, speeds
[i
].string
))
1780 return speeds
[i
].speed
;
1781 return (speed_t
) -1;
1784 static unsigned long int
1785 baud_to_value (speed_t speed
)
1789 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1790 if (speed
== speeds
[i
].speed
)
1791 return speeds
[i
].value
;
1796 sane_mode (struct termios
*mode
)
1801 for (i
= 0; control_info
[i
].name
; ++i
)
1804 if (STREQ (control_info
[i
].name
, "min"))
1807 mode
->c_cc
[control_info
[i
].offset
] = control_info
[i
].saneval
;
1810 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1812 if (mode_info
[i
].flags
& SANE_SET
)
1814 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1815 *bitsp
= (*bitsp
& ~mode_info
[i
].mask
) | mode_info
[i
].bits
;
1817 else if (mode_info
[i
].flags
& SANE_UNSET
)
1819 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1820 *bitsp
= *bitsp
& ~mode_info
[i
].mask
& ~mode_info
[i
].bits
;
1825 /* Return a string that is the printable representation of character CH. */
1826 /* Adapted from `cat' by Torbjorn Granlund. */
1831 static char buf
[10];
1834 if (ch
== _POSIX_VDISABLE
)
1853 *bpout
++ = ch
- 128;
1863 *bpout
++ = ch
- 128 + 64;
1873 return (const char *) buf
;
1876 /* Parse string S as an integer, using decimal radix by default,
1877 but allowing octal and hex numbers as in C. Reject values
1878 larger than MAXVAL. */
1880 static unsigned long int
1881 integer_arg (const char *s
, unsigned long int maxval
)
1883 unsigned long int value
;
1884 if (xstrtoul (s
, NULL
, 0, &value
, "bB") != LONGINT_OK
1887 error (0, 0, _("invalid integer argument %s"), quote (s
));
1888 usage (EXIT_FAILURE
);