1 /* stty -- change and print terminal line settings
2 Copyright (C) 1990-2015 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 3 of the License, or
7 (at your option) any later version.
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, see <http://www.gnu.org/licenses/>. */
17 /* Usage: stty [-ag] [--all] [--save] [-F device] [--file=device] [setting...]
20 -a, --all Write all current settings to stdout in human-readable form.
21 -g, --save Write all current settings to stdout in stty-readable form.
22 -F, --file Open and use the specified device instead of stdin
24 If no args are given, write to stdout the baud rate and settings that
25 have been changed from their defaults. Mode reading and changes
26 are done on the specified device, or stdin if none was specified.
28 David MacKenzie <djm@gnu.ai.mit.edu> */
32 #ifdef TERMIOS_NEEDS_XOPEN_SOURCE
33 # define _XOPEN_SOURCE
37 #include <sys/types.h>
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
59 #include "fd-reopen.h"
61 #include "xdectoint.h"
64 /* The official name of this program (e.g., no 'g' prefix). */
65 #define PROGRAM_NAME "stty"
67 #define AUTHORS proper_name ("David MacKenzie")
69 #ifndef _POSIX_VDISABLE
70 # define _POSIX_VDISABLE 0
73 #define Control(c) ((c) & 0x1f)
74 /* Canonical values for control characters. */
76 # define CINTR Control ('c')
85 # define CKILL Control ('u')
88 # define CEOF Control ('d')
91 # define CEOL _POSIX_VDISABLE
94 # define CSTART Control ('q')
97 # define CSTOP Control ('s')
100 # define CSUSP Control ('z')
102 #if defined VEOL2 && !defined CEOL2
103 # define CEOL2 _POSIX_VDISABLE
105 /* Some platforms have VSWTC, others VSWTCH. In both cases, this control
106 character is initialized by CSWTCH, if present. */
107 #if defined VSWTC && !defined VSWTCH
108 # define VSWTCH VSWTC
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 # if defined CSUSP && !defined CSWTCH
114 # define CSWTCH CSUSP
117 #if defined VSWTCH && !defined CSWTCH
118 # define CSWTCH _POSIX_VDISABLE
121 /* SunOS 5.3 loses (^Z doesn't work) if 'swtch' is the same as 'susp'.
122 So the default is to disable 'swtch.' */
123 #if defined __sparc__ && defined __svr4__
125 # define CSWTCH _POSIX_VDISABLE
128 #if defined VWERSE && !defined VWERASE /* AIX-3.2.5 */
129 # define VWERASE VWERSE
131 #if defined VDSUSP && !defined CDSUSP
132 # define CDSUSP Control ('y')
134 #if !defined VREPRINT && defined VRPRNT /* Irix 4.0.5 */
135 # define VREPRINT VRPRNT
137 #if defined VREPRINT && !defined CRPRNT
138 # define CRPRNT Control ('r')
140 #if defined CREPRINT && !defined CRPRNT
141 # define CRPRNT Control ('r')
143 #if defined VWERASE && !defined CWERASE
144 # define CWERASE Control ('w')
146 #if defined VLNEXT && !defined CLNEXT
147 # define CLNEXT Control ('v')
149 #if defined VDISCARD && !defined VFLUSHO
150 # define VFLUSHO VDISCARD
152 #if defined VFLUSH && !defined VFLUSHO /* Ultrix 4.2 */
153 # define VFLUSHO VFLUSH
155 #if defined CTLECH && !defined ECHOCTL /* Ultrix 4.3 */
156 # define ECHOCTL CTLECH
158 #if defined TCTLECH && !defined ECHOCTL /* Ultrix 4.2 */
159 # define ECHOCTL TCTLECH
161 #if defined CRTKIL && !defined ECHOKE /* Ultrix 4.2 and 4.3 */
162 # define ECHOKE CRTKIL
164 #if defined VFLUSHO && !defined CFLUSHO
165 # define CFLUSHO Control ('o')
167 #if defined VSTATUS && !defined CSTATUS
168 # define CSTATUS Control ('t')
171 /* Which speeds to set. */
174 input_speed
, output_speed
, both_speeds
177 /* What to output and how. */
180 changed
, all
, recoverable
/* Default, -a, -g. */
183 /* Which member(s) of 'struct termios' a mode uses. */
186 control
, input
, output
, local
, combination
189 /* Flags for 'struct mode_info'. */
190 #define SANE_SET 1 /* Set in 'sane' mode. */
191 #define SANE_UNSET 2 /* Unset in 'sane' mode. */
192 #define REV 4 /* Can be turned off by prepending '-'. */
193 #define OMIT 8 /* Don't display value. */
194 #define NO_SETATTR 16 /* tcsetattr not used to set mode bits. */
199 const char *name
; /* Name given on command line. */
200 enum mode_type type
; /* Which structure element to change. */
201 char flags
; /* Setting and display options. */
202 unsigned long bits
; /* Bits to set for this mode. */
203 unsigned long mask
; /* Other bits to turn off for this mode. */
206 static struct mode_info
const mode_info
[] =
208 {"parenb", control
, REV
, PARENB
, 0},
209 {"parodd", control
, REV
, PARODD
, 0},
211 {"cmspar", control
, REV
, CMSPAR
, 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 {"cdtrdsr", control
, REV
, CDTRDSR
, 0},
229 {"ignbrk", input
, SANE_UNSET
| REV
, IGNBRK
, 0},
230 {"brkint", input
, SANE_SET
| REV
, BRKINT
, 0},
231 {"ignpar", input
, REV
, IGNPAR
, 0},
232 {"parmrk", input
, REV
, PARMRK
, 0},
233 {"inpck", input
, REV
, INPCK
, 0},
234 {"istrip", input
, REV
, ISTRIP
, 0},
235 {"inlcr", input
, SANE_UNSET
| REV
, INLCR
, 0},
236 {"igncr", input
, SANE_UNSET
| REV
, IGNCR
, 0},
237 {"icrnl", input
, SANE_SET
| REV
, ICRNL
, 0},
238 {"ixon", input
, REV
, IXON
, 0},
239 {"ixoff", input
, SANE_UNSET
| REV
, IXOFF
, 0},
240 {"tandem", input
, REV
| OMIT
, IXOFF
, 0},
242 {"iuclc", input
, SANE_UNSET
| REV
, IUCLC
, 0},
245 {"ixany", input
, SANE_UNSET
| REV
, IXANY
, 0},
248 {"imaxbel", input
, SANE_SET
| REV
, IMAXBEL
, 0},
251 {"iutf8", input
, SANE_UNSET
| REV
, IUTF8
, 0},
254 {"opost", output
, SANE_SET
| REV
, OPOST
, 0},
256 {"olcuc", output
, SANE_UNSET
| REV
, OLCUC
, 0},
259 {"ocrnl", output
, SANE_UNSET
| REV
, OCRNL
, 0},
262 {"onlcr", output
, SANE_SET
| REV
, ONLCR
, 0},
265 {"onocr", output
, SANE_UNSET
| REV
, ONOCR
, 0},
268 {"onlret", output
, SANE_UNSET
| REV
, ONLRET
, 0},
271 {"ofill", output
, SANE_UNSET
| REV
, OFILL
, 0},
274 {"ofdel", output
, SANE_UNSET
| REV
, OFDEL
, 0},
277 {"nl1", output
, SANE_UNSET
, NL1
, NLDLY
},
278 {"nl0", output
, SANE_SET
, NL0
, NLDLY
},
281 {"cr3", output
, SANE_UNSET
, CR3
, CRDLY
},
282 {"cr2", output
, SANE_UNSET
, CR2
, CRDLY
},
283 {"cr1", output
, SANE_UNSET
, CR1
, CRDLY
},
284 {"cr0", output
, SANE_SET
, CR0
, CRDLY
},
288 {"tab3", output
, SANE_UNSET
, TAB3
, TABDLY
},
291 {"tab2", output
, SANE_UNSET
, TAB2
, TABDLY
},
294 {"tab1", output
, SANE_UNSET
, TAB1
, TABDLY
},
297 {"tab0", output
, SANE_SET
, TAB0
, TABDLY
},
301 {"tab3", output
, SANE_UNSET
, OXTABS
, 0},
305 {"bs1", output
, SANE_UNSET
, BS1
, BSDLY
},
306 {"bs0", output
, SANE_SET
, BS0
, BSDLY
},
309 {"vt1", output
, SANE_UNSET
, VT1
, VTDLY
},
310 {"vt0", output
, SANE_SET
, VT0
, VTDLY
},
313 {"ff1", output
, SANE_UNSET
, FF1
, FFDLY
},
314 {"ff0", output
, SANE_SET
, FF0
, FFDLY
},
317 {"isig", local
, SANE_SET
| REV
, ISIG
, 0},
318 {"icanon", local
, SANE_SET
| REV
, ICANON
, 0},
320 {"iexten", local
, SANE_SET
| REV
, IEXTEN
, 0},
322 {"echo", local
, SANE_SET
| REV
, ECHO
, 0},
323 {"echoe", local
, SANE_SET
| REV
, ECHOE
, 0},
324 {"crterase", local
, REV
| OMIT
, ECHOE
, 0},
325 {"echok", local
, SANE_SET
| REV
, ECHOK
, 0},
326 {"echonl", local
, SANE_UNSET
| REV
, ECHONL
, 0},
327 {"noflsh", local
, SANE_UNSET
| REV
, NOFLSH
, 0},
329 {"xcase", local
, SANE_UNSET
| REV
, XCASE
, 0},
332 {"tostop", local
, SANE_UNSET
| REV
, TOSTOP
, 0},
335 {"echoprt", local
, SANE_UNSET
| REV
, ECHOPRT
, 0},
336 {"prterase", local
, REV
| OMIT
, ECHOPRT
, 0},
339 {"echoctl", local
, SANE_SET
| REV
, ECHOCTL
, 0},
340 {"ctlecho", local
, REV
| OMIT
, ECHOCTL
, 0},
343 {"echoke", local
, SANE_SET
| REV
, ECHOKE
, 0},
344 {"crtkill", local
, REV
| OMIT
, ECHOKE
, 0},
347 {"extproc", local
, SANE_UNSET
| REV
| NO_SETATTR
, EXTPROC
, 0},
348 #elif defined EXTPROC
349 {"extproc", local
, SANE_UNSET
| REV
, EXTPROC
, 0},
352 {"evenp", combination
, REV
| OMIT
, 0, 0},
353 {"parity", combination
, REV
| OMIT
, 0, 0},
354 {"oddp", combination
, REV
| OMIT
, 0, 0},
355 {"nl", combination
, REV
| OMIT
, 0, 0},
356 {"ek", combination
, OMIT
, 0, 0},
357 {"sane", combination
, OMIT
, 0, 0},
358 {"cooked", combination
, REV
| OMIT
, 0, 0},
359 {"raw", combination
, REV
| OMIT
, 0, 0},
360 {"pass8", combination
, REV
| OMIT
, 0, 0},
361 {"litout", combination
, REV
| OMIT
, 0, 0},
362 {"cbreak", combination
, REV
| OMIT
, 0, 0},
364 {"decctlq", combination
, REV
| OMIT
, 0, 0},
366 #if defined TABDLY || defined OXTABS
367 {"tabs", combination
, REV
| OMIT
, 0, 0},
369 #if defined XCASE && defined IUCLC && defined OLCUC
370 {"lcase", combination
, REV
| OMIT
, 0, 0},
371 {"LCASE", combination
, REV
| OMIT
, 0, 0},
373 {"crt", combination
, OMIT
, 0, 0},
374 {"dec", combination
, OMIT
, 0, 0},
376 {NULL
, control
, 0, 0, 0}
379 /* Control character settings. */
382 const char *name
; /* Name given on command line. */
383 cc_t saneval
; /* Value to set for 'stty sane'. */
384 size_t offset
; /* Offset in c_cc. */
387 /* Control characters. */
389 static struct control_info
const control_info
[] =
391 {"intr", CINTR
, VINTR
},
392 {"quit", CQUIT
, VQUIT
},
393 {"erase", CERASE
, VERASE
},
394 {"kill", CKILL
, VKILL
},
398 {"eol2", CEOL2
, VEOL2
},
401 {"swtch", CSWTCH
, VSWTCH
},
403 {"start", CSTART
, VSTART
},
404 {"stop", CSTOP
, VSTOP
},
405 {"susp", CSUSP
, VSUSP
},
407 {"dsusp", CDSUSP
, VDSUSP
},
410 {"rprnt", CRPRNT
, VREPRINT
},
412 # ifdef CREPRINT /* HPUX 10.20 needs this */
413 {"rprnt", CRPRNT
, CREPRINT
},
417 {"werase", CWERASE
, VWERASE
},
420 {"lnext", CLNEXT
, VLNEXT
},
423 {"flush", CFLUSHO
, VFLUSHO
}, /* deprecated compat option. */
424 {"discard", CFLUSHO
, VFLUSHO
},
427 {"status", CSTATUS
, VSTATUS
},
430 /* These must be last because of the display routines. */
436 static char const *visible (cc_t ch
);
437 static unsigned long int baud_to_value (speed_t speed
);
438 static bool recover_mode (char const *arg
, struct termios
*mode
);
439 static int screen_columns (void);
440 static bool set_mode (struct mode_info
const *info
, bool reversed
,
441 struct termios
*mode
);
442 static unsigned long int integer_arg (const char *s
, unsigned long int max
);
443 static speed_t
string_to_baud (const char *arg
);
444 static tcflag_t
*mode_type_flag (enum mode_type type
, struct termios
*mode
);
445 static void display_all (struct termios
*mode
, char const *device_name
);
446 static void display_changed (struct termios
*mode
);
447 static void display_recoverable (struct termios
*mode
);
448 static void display_settings (enum output_type output_type
,
449 struct termios
*mode
,
450 const char *device_name
);
451 static void display_speed (struct termios
*mode
, bool fancy
);
452 static void display_window_size (bool fancy
, char const *device_name
);
453 static void sane_mode (struct termios
*mode
);
454 static void set_control_char (struct control_info
const *info
,
456 struct termios
*mode
);
457 static void set_speed (enum speed_setting type
, const char *arg
,
458 struct termios
*mode
);
459 static void set_window_size (int rows
, int cols
, char const *device_name
);
461 /* The width of the screen, for output wrapping. */
464 /* Current position, to know when to wrap. */
465 static int current_col
;
467 static struct option
const longopts
[] =
469 {"all", no_argument
, NULL
, 'a'},
470 {"save", no_argument
, NULL
, 'g'},
471 {"file", required_argument
, NULL
, 'F'},
472 {GETOPT_HELP_OPTION_DECL
},
473 {GETOPT_VERSION_OPTION_DECL
},
477 static void wrapf (const char *message
, ...)
478 __attribute__ ((__format__ (__printf__
, 1, 2)));
480 /* Print format string MESSAGE and optional args.
481 Wrap to next line first if it won't fit.
482 Print a space first unless MESSAGE will start a new line. */
485 wrapf (const char *message
,...)
491 va_start (args
, message
);
492 buflen
= vasprintf (&buf
, message
, args
);
500 if (max_col
- current_col
< buflen
)
514 current_col
+= buflen
;
520 if (status
!= EXIT_SUCCESS
)
525 Usage: %s [-F DEVICE | --file=DEVICE] [SETTING]...\n\
526 or: %s [-F DEVICE | --file=DEVICE] [-a|--all]\n\
527 or: %s [-F DEVICE | --file=DEVICE] [-g|--save]\n\
529 program_name
, program_name
, program_name
);
531 Print or change terminal characteristics.\n\
534 emit_mandatory_arg_note ();
537 -a, --all print all current settings in human-readable form\n\
538 -g, --save print all current settings in a stty-readable form\n\
539 -F, --file=DEVICE open and use the specified DEVICE instead of stdin\n\
541 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
542 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
545 Optional - before SETTING indicates negation. An * marks non-POSIX\n\
546 settings. The underlying system defines which settings are available.\n\
550 Special characters:\n"), stdout
);
553 * discard CHAR CHAR will toggle discarding of output\n\
558 * dsusp CHAR CHAR will send a terminal stop signal once input flushed\n\
562 eof CHAR CHAR will send an end of file (terminate the input)\n\
563 eol CHAR CHAR will end the line\n\
567 * eol2 CHAR alternate CHAR for ending the line\n\
571 erase CHAR CHAR will erase the last character typed\n\
572 intr CHAR CHAR will send an interrupt signal\n\
573 kill CHAR CHAR will erase the current line\n\
577 * lnext CHAR CHAR will enter the next character quoted\n\
582 * status CHAR CHAR will send an info signal\n\
586 quit CHAR CHAR will send a quit signal\n\
588 #if defined CREPRINT || defined VREPRINT
590 * rprnt CHAR CHAR will redraw the current line\n\
594 start CHAR CHAR will restart the output after stopping it\n\
595 stop CHAR CHAR will stop the output\n\
596 susp CHAR CHAR will send a terminal stop signal\n\
600 * swtch CHAR CHAR will switch to a different shell layer\n\
605 * werase CHAR CHAR will erase the last word typed\n\
611 N set the input and output speeds to N bauds\n\
615 * cols N tell the kernel that the terminal has N columns\n\
616 * columns N same as cols N\n\
620 ispeed N set the input speed to N\n\
624 * line N use line discipline N\n\
628 min N with -icanon, set N characters minimum for a completed read\n\
629 ospeed N set the output speed to N\n\
633 * rows N tell the kernel that the terminal has N rows\n\
634 * size print the number of rows and columns according to the kernel\n\
638 speed print the terminal speed\n\
639 time N with -icanon, set read timeout of N tenths of a second\n\
644 [-]clocal disable modem control signals\n\
645 [-]cread allow input to be received\n\
649 * [-]crtscts enable RTS/CTS handshaking\n\
654 * [-]cdtrdsr enable DTR/DSR handshaking\n\
658 csN set character size to N bits, N in [5..8]\n\
661 [-]cstopb use two stop bits per character (one with '-')\n\
662 [-]hup send a hangup signal when the last process closes the tty\n\
663 [-]hupcl same as [-]hup\n\
664 [-]parenb generate parity bit in output and expect parity bit in input\n\
665 [-]parodd set odd parity (or even parity with '-')\n\
669 * [-]cmspar use \"stick\" (mark/space) parity\n\
675 [-]brkint breaks cause an interrupt signal\n\
676 [-]icrnl translate carriage return to newline\n\
677 [-]ignbrk ignore break characters\n\
678 [-]igncr ignore carriage return\n\
679 [-]ignpar ignore characters with parity errors\n\
683 * [-]imaxbel beep and do not flush a full input buffer on a character\n\
687 [-]inlcr translate newline to carriage return\n\
688 [-]inpck enable input parity checking\n\
689 [-]istrip clear high (8th) bit of input characters\n\
693 * [-]iutf8 assume input characters are UTF-8 encoded\n\
698 * [-]iuclc translate uppercase characters to lowercase\n\
703 * [-]ixany let any character restart output, not only start character\n\
707 [-]ixoff enable sending of start/stop characters\n\
708 [-]ixon enable XON/XOFF flow control\n\
709 [-]parmrk mark parity errors (with a 255-0-character sequence)\n\
710 [-]tandem same as [-]ixoff\n\
718 * bsN backspace delay style, N in [0..1]\n\
723 * crN carriage return delay style, N in [0..3]\n\
728 * ffN form feed delay style, N in [0..1]\n\
733 * nlN newline delay style, N in [0..1]\n\
738 * [-]ocrnl translate carriage return to newline\n\
743 * [-]ofdel use delete characters for fill instead of NUL characters\n\
748 * [-]ofill use fill (padding) characters instead of timing for delays\n\
753 * [-]olcuc translate lowercase characters to uppercase\n\
758 * [-]onlcr translate newline to carriage return-newline\n\
763 * [-]onlret newline performs a carriage return\n\
768 * [-]onocr do not print carriage returns in the first column\n\
772 [-]opost postprocess output\n\
774 #if defined TABDLY || defined OXTABS
776 * tabN horizontal tab delay style, N in [0..3]\n\
777 * tabs same as tab0\n\
778 * -tabs same as tab3\n\
783 * vtN vertical tab delay style, N in [0..1]\n\
789 [-]crterase echo erase characters as backspace-space-backspace\n\
793 * crtkill kill all line by obeying the echoprt and echoe settings\n\
794 * -crtkill kill all line by obeying the echoctl and echok settings\n\
799 * [-]ctlecho echo control characters in hat notation ('^c')\n\
803 [-]echo echo input characters\n\
807 * [-]echoctl same as [-]ctlecho\n\
811 [-]echoe same as [-]crterase\n\
812 [-]echok echo a newline after a kill character\n\
816 * [-]echoke same as [-]crtkill\n\
820 [-]echonl echo newline even if not echoing other characters\n\
824 * [-]echoprt echo erased characters backward, between '\\' and '/'\n\
827 #if defined EXTPROC || defined TIOCEXT
829 * [-]extproc enable \"LINEMODE\"; useful with high latency links\n\
833 [-]icanon enable special characters: %s\n\
834 [-]iexten enable non-POSIX special characters\n\
839 #if defined CREPRINT || defined VREPRINT
844 [-]isig enable interrupt, quit, and suspend special characters\n\
845 [-]noflsh disable flushing after interrupt and quit special characters\n\
849 * [-]prterase same as [-]echoprt\n\
854 * [-]tostop stop background jobs that try to write to the terminal\n\
859 * [-]xcase with icanon, escape with '\\' for uppercase characters\n\
864 Combination settings:\n\
866 #if defined XCASE && defined IUCLC && defined OLCUC
868 * [-]LCASE same as [-]lcase\n\
872 cbreak same as -icanon\n\
873 -cbreak same as icanon\n\
876 cooked same as brkint ignpar istrip icrnl ixon opost isig\n\
877 icanon, eof and eol characters to their default values\n\
878 -cooked same as raw\n\
891 dec same as %s intr ^c erase 0177\n\
906 * [-]decctlq same as [-]ixany\n\
910 ek erase and kill characters to their default values\n\
911 evenp same as parenb -parodd cs7\n\
912 -evenp same as -parenb cs8\n\
914 #if defined XCASE && defined IUCLC && defined OLCUC
916 * [-]lcase same as xcase iuclc olcuc\n\
920 litout same as -parenb -istrip -opost cs8\n\
921 -litout same as parenb istrip opost cs7\n\
930 , "icrnl -inlcr -igncr"
944 oddp same as parenb parodd cs7\n\
945 -oddp same as -parenb cs8\n\
946 [-]parity same as [-]evenp\n\
947 pass8 same as -parenb -istrip cs8\n\
948 -pass8 same as parenb istrip cs7\n\
951 raw same as -ignbrk -brkint -ignpar -parmrk -inpck -istrip\n\
952 -inlcr -igncr -icrnl -ixon -ixoff -icanon -opost\n\
953 -isig%s min 1 time 0\n\
954 -raw same as cooked\n\
970 sane same as cread -ignbrk brkint -inlcr -igncr icrnl\n\
971 icanon iexten echo echoe echok -echonl -noflsh\n\
975 all special characters to their default values\n\
1054 Handle the tty line connected to standard input. Without arguments,\n\
1055 prints baud rate, line discipline, and deviations from stty sane. In\n\
1056 settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
1057 127; special values ^- or undef used to disable special characters.\n\
1059 emit_ancillary_info (PROGRAM_NAME
);
1065 main (int argc
, char **argv
)
1067 /* Initialize to all zeroes so there is no risk memcmp will report a
1068 spurious difference in an uninitialized portion of the structure. */
1069 static struct termios mode
;
1071 enum output_type output_type
;
1075 bool require_set_attr
;
1076 bool speed_was_set _GL_UNUSED
;
1077 bool verbose_output
;
1078 bool recoverable_output
;
1081 char *file_name
= NULL
;
1082 const char *device_name
;
1084 initialize_main (&argc
, &argv
);
1085 set_program_name (argv
[0]);
1086 setlocale (LC_ALL
, "");
1087 bindtextdomain (PACKAGE
, LOCALEDIR
);
1088 textdomain (PACKAGE
);
1090 atexit (close_stdout
);
1092 output_type
= changed
;
1093 verbose_output
= false;
1094 recoverable_output
= false;
1096 /* Don't print error messages for unrecognized options. */
1099 /* If any new options are ever added to stty, the short options MUST
1100 NOT allow any ambiguity with the stty settings. For example, the
1101 stty setting "-gagFork" would not be feasible, since it will be
1102 parsed as "-g -a -g -F ork". If you change anything about how
1103 stty parses options, be sure it still works with combinations of
1104 short and long options, --, POSIXLY_CORRECT, etc. */
1106 while ((optc
= getopt_long (argc
- argi
, argv
+ argi
, "-agF:",
1113 verbose_output
= true;
1118 recoverable_output
= true;
1119 output_type
= recoverable
;
1124 error (EXIT_FAILURE
, 0, _("only one device may be specified"));
1128 case_GETOPT_HELP_CHAR
;
1130 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1135 /* Skip the argument containing this unrecognized option;
1136 the 2nd pass will analyze it. */
1139 /* Restart getopt_long from the first unskipped argument. */
1146 /* Clear fully-parsed arguments, so they don't confuse the 2nd pass. */
1147 while (opti
< optind
)
1148 argv
[argi
+ opti
++] = NULL
;
1151 /* Specifying both -a and -g gets an error. */
1152 if (verbose_output
&& recoverable_output
)
1153 error (EXIT_FAILURE
, 0,
1154 _("the options for verbose and stty-readable output styles are\n"
1155 "mutually exclusive"));
1157 /* Specifying any other arguments with -a or -g gets an error. */
1158 if (!noargs
&& (verbose_output
|| recoverable_output
))
1159 error (EXIT_FAILURE
, 0,
1160 _("when specifying an output style, modes may not be set"));
1162 /* FIXME: it'd be better not to open the file until we've verified
1163 that all arguments are valid. Otherwise, we could end up doing
1164 only some of the requested operations and then failing, probably
1165 leaving things in an undesirable state. */
1170 device_name
= file_name
;
1171 if (fd_reopen (STDIN_FILENO
, device_name
, O_RDONLY
| O_NONBLOCK
, 0) < 0)
1172 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1173 if ((fdflags
= fcntl (STDIN_FILENO
, F_GETFL
)) == -1
1174 || fcntl (STDIN_FILENO
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
1175 error (EXIT_FAILURE
, errno
, _("%s: couldn't reset non-blocking mode"),
1179 device_name
= _("standard input");
1181 if (tcgetattr (STDIN_FILENO
, &mode
))
1182 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1184 if (verbose_output
|| recoverable_output
|| noargs
)
1186 max_col
= screen_columns ();
1188 display_settings (output_type
, &mode
, device_name
);
1189 return EXIT_SUCCESS
;
1192 speed_was_set
= false;
1193 require_set_attr
= false;
1194 for (k
= 1; k
< argc
; k
++)
1196 char const *arg
= argv
[k
];
1197 bool match_found
= false;
1198 bool not_set_attr
= false;
1199 bool reversed
= false;
1210 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1212 if (STREQ (arg
, mode_info
[i
].name
))
1214 if ((mode_info
[i
].flags
& NO_SETATTR
) == 0)
1216 match_found
= set_mode (&mode_info
[i
], reversed
, &mode
);
1217 require_set_attr
= true;
1220 match_found
= not_set_attr
= true;
1224 if (!match_found
&& reversed
)
1226 error (0, 0, _("invalid argument %s"), quote (arg
- 1));
1227 usage (EXIT_FAILURE
);
1231 for (i
= 0; control_info
[i
].name
!= NULL
; ++i
)
1233 if (STREQ (arg
, control_info
[i
].name
))
1237 error (0, 0, _("missing argument to %s"), quote (arg
));
1238 usage (EXIT_FAILURE
);
1242 set_control_char (&control_info
[i
], argv
[k
], &mode
);
1243 require_set_attr
= true;
1248 if (!match_found
|| not_set_attr
)
1250 if (STREQ (arg
, "ispeed"))
1254 error (0, 0, _("missing argument to %s"), quote (arg
));
1255 usage (EXIT_FAILURE
);
1258 set_speed (input_speed
, argv
[k
], &mode
);
1259 speed_was_set
= true;
1260 require_set_attr
= true;
1262 else if (STREQ (arg
, "ospeed"))
1266 error (0, 0, _("missing argument to %s"), quote (arg
));
1267 usage (EXIT_FAILURE
);
1270 set_speed (output_speed
, argv
[k
], &mode
);
1271 speed_was_set
= true;
1272 require_set_attr
= true;
1275 /* This is the BSD interface to "extproc".
1276 Even though it's an lflag, an ioctl is used to set it. */
1277 else if (STREQ (arg
, "extproc"))
1279 int val
= ! reversed
;
1281 if (ioctl (STDIN_FILENO
, TIOCEXT
, &val
) != 0)
1283 error (EXIT_FAILURE
, errno
, _("%s: error setting %s"),
1284 device_name
, quote (arg
));
1289 else if (STREQ (arg
, "rows"))
1293 error (0, 0, _("missing argument to %s"), quote (arg
));
1294 usage (EXIT_FAILURE
);
1297 set_window_size (integer_arg (argv
[k
], INT_MAX
), -1,
1300 else if (STREQ (arg
, "cols")
1301 || STREQ (arg
, "columns"))
1305 error (0, 0, _("missing argument to %s"), quote (arg
));
1306 usage (EXIT_FAILURE
);
1309 set_window_size (-1, integer_arg (argv
[k
], INT_MAX
),
1312 else if (STREQ (arg
, "size"))
1314 max_col
= screen_columns ();
1316 display_window_size (false, device_name
);
1320 else if (STREQ (arg
, "line"))
1322 unsigned long int value
;
1325 error (0, 0, _("missing argument to %s"), quote (arg
));
1326 usage (EXIT_FAILURE
);
1329 mode
.c_line
= value
= integer_arg (argv
[k
], ULONG_MAX
);
1330 if (mode
.c_line
!= value
)
1331 error (0, 0, _("invalid line discipline %s"), quote (argv
[k
]));
1332 require_set_attr
= true;
1335 else if (STREQ (arg
, "speed"))
1337 max_col
= screen_columns ();
1338 display_speed (&mode
, false);
1340 else if (string_to_baud (arg
) != (speed_t
) -1)
1342 set_speed (both_speeds
, arg
, &mode
);
1343 speed_was_set
= true;
1344 require_set_attr
= true;
1348 if (! recover_mode (arg
, &mode
))
1350 error (0, 0, _("invalid argument %s"), quote (arg
));
1351 usage (EXIT_FAILURE
);
1353 require_set_attr
= true;
1358 if (require_set_attr
)
1360 /* Initialize to all zeroes so there is no risk memcmp will report a
1361 spurious difference in an uninitialized portion of the structure. */
1362 static struct termios new_mode
;
1364 if (tcsetattr (STDIN_FILENO
, TCSADRAIN
, &mode
))
1365 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1367 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
1368 it performs *any* of the requested operations. This means it
1369 can report 'success' when it has actually failed to perform
1370 some proper subset of the requested operations. To detect
1371 this partial failure, get the current terminal attributes and
1372 compare them to the requested ones. */
1374 if (tcgetattr (STDIN_FILENO
, &new_mode
))
1375 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1377 /* Normally, one shouldn't use memcmp to compare structures that
1378 may have 'holes' containing uninitialized data, but we have been
1379 careful to initialize the storage of these two variables to all
1380 zeroes. One might think it more efficient simply to compare the
1381 modified fields, but that would require enumerating those fields --
1382 and not all systems have the same fields in this structure. */
1384 if (memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1387 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1388 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1389 sometimes (m1 != m2). The only difference is in the four bits
1390 of the c_cflag field corresponding to the baud rate. To save
1391 Sun users a little confusion, don't report an error if this
1392 happens. But suppress the error only if we haven't tried to
1393 set the baud rate explicitly -- otherwise we'd never give an
1394 error for a true failure to set the baud rate. */
1396 new_mode
.c_cflag
&= (~CIBAUD
);
1397 if (speed_was_set
|| memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1400 error (EXIT_FAILURE
, 0,
1401 _("%s: unable to perform all requested operations"),
1406 printf ("new_mode: mode\n");
1407 for (i
= 0; i
< sizeof (new_mode
); i
++)
1408 printf ("0x%02x: 0x%02x\n",
1409 *(((unsigned char *) &new_mode
) + i
),
1410 *(((unsigned char *) &mode
) + i
));
1417 return EXIT_SUCCESS
;
1420 /* Return false if not applied because not reversible; otherwise
1424 set_mode (struct mode_info
const *info
, bool reversed
, struct termios
*mode
)
1428 if (reversed
&& (info
->flags
& REV
) == 0)
1431 bitsp
= mode_type_flag (info
->type
, mode
);
1435 /* Combination mode. */
1436 if (STREQ (info
->name
, "evenp") || STREQ (info
->name
, "parity"))
1439 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1441 mode
->c_cflag
= (mode
->c_cflag
& ~PARODD
& ~CSIZE
) | PARENB
| CS7
;
1443 else if (STREQ (info
->name
, "oddp"))
1446 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1448 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARODD
| PARENB
;
1450 else if (STREQ (info
->name
, "nl"))
1454 mode
->c_iflag
= (mode
->c_iflag
| ICRNL
) & ~INLCR
& ~IGNCR
;
1455 mode
->c_oflag
= (mode
->c_oflag
1470 mode
->c_iflag
= mode
->c_iflag
& ~ICRNL
;
1472 mode
->c_oflag
= mode
->c_oflag
& ~ONLCR
;
1476 else if (STREQ (info
->name
, "ek"))
1478 mode
->c_cc
[VERASE
] = CERASE
;
1479 mode
->c_cc
[VKILL
] = CKILL
;
1481 else if (STREQ (info
->name
, "sane"))
1483 else if (STREQ (info
->name
, "cbreak"))
1486 mode
->c_lflag
|= ICANON
;
1488 mode
->c_lflag
&= ~ICANON
;
1490 else if (STREQ (info
->name
, "pass8"))
1494 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1495 mode
->c_iflag
|= ISTRIP
;
1499 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1500 mode
->c_iflag
&= ~ISTRIP
;
1503 else if (STREQ (info
->name
, "litout"))
1507 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1508 mode
->c_iflag
|= ISTRIP
;
1509 mode
->c_oflag
|= OPOST
;
1513 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1514 mode
->c_iflag
&= ~ISTRIP
;
1515 mode
->c_oflag
&= ~OPOST
;
1518 else if (STREQ (info
->name
, "raw") || STREQ (info
->name
, "cooked"))
1520 if ((info
->name
[0] == 'r' && reversed
)
1521 || (info
->name
[0] == 'c' && !reversed
))
1524 mode
->c_iflag
|= BRKINT
| IGNPAR
| ISTRIP
| ICRNL
| IXON
;
1525 mode
->c_oflag
|= OPOST
;
1526 mode
->c_lflag
|= ISIG
| ICANON
;
1528 mode
->c_cc
[VEOF
] = CEOF
;
1531 mode
->c_cc
[VEOL
] = CEOL
;
1538 mode
->c_oflag
&= ~OPOST
;
1539 mode
->c_lflag
&= ~(ISIG
| ICANON
1544 mode
->c_cc
[VMIN
] = 1;
1545 mode
->c_cc
[VTIME
] = 0;
1549 else if (STREQ (info
->name
, "decctlq"))
1552 mode
->c_iflag
|= IXANY
;
1554 mode
->c_iflag
&= ~IXANY
;
1558 else if (STREQ (info
->name
, "tabs"))
1561 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB3
;
1563 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB0
;
1567 else if (STREQ (info
->name
, "tabs"))
1570 mode
->c_oflag
= mode
->c_oflag
| OXTABS
;
1572 mode
->c_oflag
= mode
->c_oflag
& ~OXTABS
;
1576 #if defined XCASE && defined IUCLC && defined OLCUC
1577 else if (STREQ (info
->name
, "lcase")
1578 || STREQ (info
->name
, "LCASE"))
1582 mode
->c_lflag
&= ~XCASE
;
1583 mode
->c_iflag
&= ~IUCLC
;
1584 mode
->c_oflag
&= ~OLCUC
;
1588 mode
->c_lflag
|= XCASE
;
1589 mode
->c_iflag
|= IUCLC
;
1590 mode
->c_oflag
|= OLCUC
;
1594 else if (STREQ (info
->name
, "crt"))
1595 mode
->c_lflag
|= ECHOE
1603 else if (STREQ (info
->name
, "dec"))
1605 mode
->c_cc
[VINTR
] = 3; /* ^C */
1606 mode
->c_cc
[VERASE
] = 127; /* DEL */
1607 mode
->c_cc
[VKILL
] = 21; /* ^U */
1608 mode
->c_lflag
|= ECHOE
1617 mode
->c_iflag
&= ~IXANY
;
1622 *bitsp
= *bitsp
& ~info
->mask
& ~info
->bits
;
1624 *bitsp
= (*bitsp
& ~info
->mask
) | info
->bits
;
1630 set_control_char (struct control_info
const *info
, const char *arg
,
1631 struct termios
*mode
)
1633 unsigned long int value
;
1635 if (STREQ (info
->name
, "min") || STREQ (info
->name
, "time"))
1636 value
= integer_arg (arg
, TYPE_MAXIMUM (cc_t
));
1637 else if (arg
[0] == '\0' || arg
[1] == '\0')
1638 value
= to_uchar (arg
[0]);
1639 else if (STREQ (arg
, "^-") || STREQ (arg
, "undef"))
1640 value
= _POSIX_VDISABLE
;
1641 else if (arg
[0] == '^' && arg
[1] != '\0') /* Ignore any trailing junk. */
1646 value
= to_uchar (arg
[1]) & ~0140; /* Non-letters get weird results. */
1649 value
= integer_arg (arg
, TYPE_MAXIMUM (cc_t
));
1650 mode
->c_cc
[info
->offset
] = value
;
1654 set_speed (enum speed_setting type
, const char *arg
, struct termios
*mode
)
1658 baud
= string_to_baud (arg
);
1659 if (type
== input_speed
|| type
== both_speeds
)
1660 cfsetispeed (mode
, baud
);
1661 if (type
== output_speed
|| type
== both_speeds
)
1662 cfsetospeed (mode
, baud
);
1668 get_win_size (int fd
, struct winsize
*win
)
1670 int err
= ioctl (fd
, TIOCGWINSZ
, (char *) win
);
1675 set_window_size (int rows
, int cols
, char const *device_name
)
1679 if (get_win_size (STDIN_FILENO
, &win
))
1681 if (errno
!= EINVAL
)
1682 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1683 memset (&win
, 0, sizeof (win
));
1692 /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote:
1693 The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.
1694 This comment from sys/ttold.h describes Sun's twisted logic - a better
1695 test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).
1696 At any rate, the problem is gone in Solaris 2.x.
1698 Unfortunately, the old TIOCSSIZE code does collide with TIOCSWINSZ,
1699 but they can be disambiguated by checking whether a "struct ttysize"
1700 structure's "ts_lines" field is greater than 64K or not. If so,
1701 it's almost certainly a "struct winsize" instead.
1703 At any rate, the bug manifests itself when ws_row == 0; the symptom is
1704 that ws_row is set to ws_col, and ws_col is set to (ws_xpixel<<16)
1705 + ws_ypixel. Since GNU stty sets rows and columns separately, this bug
1706 caused "stty rows 0 cols 0" to set rows to cols and cols to 0, while
1707 "stty cols 0 rows 0" would do the right thing. On a little-endian
1708 machine like the sun386i, the problem is the same, but for ws_col == 0.
1710 The workaround is to do the ioctl once with row and col = 1 to set the
1711 pixel info, and then do it again using a TIOCSSIZE to set rows/cols. */
1713 if (win
.ws_row
== 0 || win
.ws_col
== 0)
1715 struct ttysize ttysz
;
1717 ttysz
.ts_lines
= win
.ws_row
;
1718 ttysz
.ts_cols
= win
.ws_col
;
1723 if (ioctl (STDIN_FILENO
, TIOCSWINSZ
, (char *) &win
))
1724 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1726 if (ioctl (STDIN_FILENO
, TIOCSSIZE
, (char *) &ttysz
))
1727 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1732 if (ioctl (STDIN_FILENO
, TIOCSWINSZ
, (char *) &win
))
1733 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1737 display_window_size (bool fancy
, char const *device_name
)
1741 if (get_win_size (STDIN_FILENO
, &win
))
1743 if (errno
!= EINVAL
)
1744 error (EXIT_FAILURE
, errno
, "%s", device_name
);
1746 error (EXIT_FAILURE
, 0,
1747 _("%s: no size information for this device"), device_name
);
1751 wrapf (fancy
? "rows %d; columns %d;" : "%d %d\n",
1752 win
.ws_row
, win
.ws_col
);
1760 screen_columns (void)
1765 /* With Solaris 2.[123], this ioctl fails and errno is set to
1766 EINVAL for telnet (but not rlogin) sessions.
1767 On ISC 3.0, it fails for the console and the serial port
1768 (but it works for ptys).
1769 It can also fail on any system when stdout isn't a tty.
1770 In case of any failure, just use the default. */
1771 if (get_win_size (STDOUT_FILENO
, &win
) == 0 && 0 < win
.ws_col
)
1775 /* Use $COLUMNS if it's in [1..INT_MAX]. */
1776 char *col_string
= getenv ("COLUMNS");
1778 if (!(col_string
!= NULL
1779 && xstrtol (col_string
, NULL
, 0, &n_columns
, "") == LONGINT_OK
1781 && n_columns
<= INT_MAX
))
1787 static tcflag_t
* _GL_ATTRIBUTE_PURE
1788 mode_type_flag (enum mode_type type
, struct termios
*mode
)
1793 return &mode
->c_cflag
;
1796 return &mode
->c_iflag
;
1799 return &mode
->c_oflag
;
1802 return &mode
->c_lflag
;
1813 display_settings (enum output_type output_type
, struct termios
*mode
,
1814 char const *device_name
)
1816 switch (output_type
)
1819 display_changed (mode
);
1823 display_all (mode
, device_name
);
1827 display_recoverable (mode
);
1833 display_changed (struct termios
*mode
)
1839 enum mode_type prev_type
= control
;
1841 display_speed (mode
, true);
1843 wrapf ("line = %d;", mode
->c_line
);
1849 for (i
= 0; !STREQ (control_info
[i
].name
, "min"); ++i
)
1851 if (mode
->c_cc
[control_info
[i
].offset
] == control_info
[i
].saneval
)
1855 /* 'flush' is the deprecated equivalent of 'discard'. */
1856 if (STREQ (control_info
[i
].name
, "flush"))
1859 /* If swtch is the same as susp, don't print both. */
1861 if (STREQ (control_info
[i
].name
, "swtch"))
1864 /* If eof uses the same slot as min, only print whichever applies. */
1866 if ((mode
->c_lflag
& ICANON
) == 0
1867 && (STREQ (control_info
[i
].name
, "eof")
1868 || STREQ (control_info
[i
].name
, "eol")))
1873 wrapf ("%s = %s;", control_info
[i
].name
,
1874 visible (mode
->c_cc
[control_info
[i
].offset
]));
1876 if ((mode
->c_lflag
& ICANON
) == 0)
1878 wrapf ("min = %lu; time = %lu;\n",
1879 (unsigned long int) mode
->c_cc
[VMIN
],
1880 (unsigned long int) mode
->c_cc
[VTIME
]);
1882 else if (!empty_line
)
1887 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1889 if (mode_info
[i
].flags
& OMIT
)
1891 if (mode_info
[i
].type
!= prev_type
)
1899 prev_type
= mode_info
[i
].type
;
1902 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1903 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1905 /* bitsp would be NULL only for "combination" modes, yet those
1906 are filtered out above via the OMIT flag. Tell static analysis
1907 tools that it's ok to dereference bitsp here. */
1910 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1912 if (mode_info
[i
].flags
& SANE_UNSET
)
1914 wrapf ("%s", mode_info
[i
].name
);
1918 else if ((mode_info
[i
].flags
& (SANE_SET
| REV
)) == (SANE_SET
| REV
))
1920 wrapf ("-%s", mode_info
[i
].name
);
1930 display_all (struct termios
*mode
, char const *device_name
)
1935 enum mode_type prev_type
= control
;
1937 display_speed (mode
, true);
1939 display_window_size (true, device_name
);
1942 wrapf ("line = %d;", mode
->c_line
);
1947 for (i
= 0; ! STREQ (control_info
[i
].name
, "min"); ++i
)
1950 /* 'flush' is the deprecated equivalent of 'discard'. */
1951 if (STREQ (control_info
[i
].name
, "flush"))
1954 /* If swtch is the same as susp, don't print both. */
1956 if (STREQ (control_info
[i
].name
, "swtch"))
1959 /* If eof uses the same slot as min, only print whichever applies. */
1961 if ((mode
->c_lflag
& ICANON
) == 0
1962 && (STREQ (control_info
[i
].name
, "eof")
1963 || STREQ (control_info
[i
].name
, "eol")))
1966 wrapf ("%s = %s;", control_info
[i
].name
,
1967 visible (mode
->c_cc
[control_info
[i
].offset
]));
1970 if ((mode
->c_lflag
& ICANON
) == 0)
1972 wrapf ("min = %lu; time = %lu;",
1973 (unsigned long int) mode
->c_cc
[VMIN
],
1974 (unsigned long int) mode
->c_cc
[VTIME
]);
1975 if (current_col
!= 0)
1979 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1981 if (mode_info
[i
].flags
& OMIT
)
1983 if (mode_info
[i
].type
!= prev_type
)
1987 prev_type
= mode_info
[i
].type
;
1990 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1991 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1992 assert (bitsp
); /* See the identical assertion and comment above. */
1993 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1994 wrapf ("%s", mode_info
[i
].name
);
1995 else if (mode_info
[i
].flags
& REV
)
1996 wrapf ("-%s", mode_info
[i
].name
);
2003 display_speed (struct termios
*mode
, bool fancy
)
2005 if (cfgetispeed (mode
) == 0 || cfgetispeed (mode
) == cfgetospeed (mode
))
2006 wrapf (fancy
? "speed %lu baud;" : "%lu\n",
2007 baud_to_value (cfgetospeed (mode
)));
2009 wrapf (fancy
? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n",
2010 baud_to_value (cfgetispeed (mode
)),
2011 baud_to_value (cfgetospeed (mode
)));
2017 display_recoverable (struct termios
*mode
)
2021 printf ("%lx:%lx:%lx:%lx",
2022 (unsigned long int) mode
->c_iflag
,
2023 (unsigned long int) mode
->c_oflag
,
2024 (unsigned long int) mode
->c_cflag
,
2025 (unsigned long int) mode
->c_lflag
);
2026 for (i
= 0; i
< NCCS
; ++i
)
2027 printf (":%lx", (unsigned long int) mode
->c_cc
[i
]);
2031 /* NOTE: identical to below, modulo use of tcflag_t */
2033 strtoul_tcflag_t (char const *s
, int base
, char **p
, tcflag_t
*result
,
2038 ul
= strtoul (s
, p
, base
);
2039 if (errno
|| **p
!= delim
|| *p
== s
|| (tcflag_t
) ul
!= ul
)
2045 /* NOTE: identical to above, modulo use of cc_t */
2047 strtoul_cc_t (char const *s
, int base
, char **p
, cc_t
*result
, char delim
)
2051 ul
= strtoul (s
, p
, base
);
2052 if (errno
|| **p
!= delim
|| *p
== s
|| (cc_t
) ul
!= ul
)
2058 /* Parse the output of display_recoverable.
2059 Return false if any part of it is invalid. */
2061 recover_mode (char const *arg
, struct termios
*mode
)
2064 char const *s
= arg
;
2066 for (i
= 0; i
< 4; i
++)
2069 if (strtoul_tcflag_t (s
, 16, &p
, flag
+ i
, ':') != 0)
2073 mode
->c_iflag
= flag
[0];
2074 mode
->c_oflag
= flag
[1];
2075 mode
->c_cflag
= flag
[2];
2076 mode
->c_lflag
= flag
[3];
2078 for (i
= 0; i
< NCCS
; ++i
)
2081 char delim
= i
< NCCS
- 1 ? ':' : '\0';
2082 if (strtoul_cc_t (s
, 16, &p
, mode
->c_cc
+ i
, delim
) != 0)
2092 const char *string
; /* ASCII representation. */
2093 speed_t speed
; /* Internal form. */
2094 unsigned long int value
; /* Numeric value. */
2097 static struct speed_map
const speeds
[] =
2104 {"134.5", B134
, 134},
2109 {"1200", B1200
, 1200},
2110 {"1800", B1800
, 1800},
2111 {"2400", B2400
, 2400},
2112 {"4800", B4800
, 4800},
2113 {"9600", B9600
, 9600},
2114 {"19200", B19200
, 19200},
2115 {"38400", B38400
, 38400},
2116 {"exta", B19200
, 19200},
2117 {"extb", B38400
, 38400},
2119 {"57600", B57600
, 57600},
2122 {"115200", B115200
, 115200},
2125 {"230400", B230400
, 230400},
2128 {"460800", B460800
, 460800},
2131 {"500000", B500000
, 500000},
2134 {"576000", B576000
, 576000},
2137 {"921600", B921600
, 921600},
2140 {"1000000", B1000000
, 1000000},
2143 {"1152000", B1152000
, 1152000},
2146 {"1500000", B1500000
, 1500000},
2149 {"2000000", B2000000
, 2000000},
2152 {"2500000", B2500000
, 2500000},
2155 {"3000000", B3000000
, 3000000},
2158 {"3500000", B3500000
, 3500000},
2161 {"4000000", B4000000
, 4000000},
2166 static speed_t _GL_ATTRIBUTE_PURE
2167 string_to_baud (const char *arg
)
2171 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
2172 if (STREQ (arg
, speeds
[i
].string
))
2173 return speeds
[i
].speed
;
2174 return (speed_t
) -1;
2177 static unsigned long int _GL_ATTRIBUTE_PURE
2178 baud_to_value (speed_t speed
)
2182 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
2183 if (speed
== speeds
[i
].speed
)
2184 return speeds
[i
].value
;
2189 sane_mode (struct termios
*mode
)
2194 for (i
= 0; control_info
[i
].name
; ++i
)
2197 if (STREQ (control_info
[i
].name
, "min"))
2200 mode
->c_cc
[control_info
[i
].offset
] = control_info
[i
].saneval
;
2203 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
2205 if (mode_info
[i
].flags
& NO_SETATTR
)
2208 if (mode_info
[i
].flags
& SANE_SET
)
2210 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
2211 *bitsp
= (*bitsp
& ~mode_info
[i
].mask
) | mode_info
[i
].bits
;
2213 else if (mode_info
[i
].flags
& SANE_UNSET
)
2215 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
2216 *bitsp
= *bitsp
& ~mode_info
[i
].mask
& ~mode_info
[i
].bits
;
2221 /* Return a string that is the printable representation of character CH. */
2222 /* Adapted from 'cat' by Torbjorn Granlund. */
2227 static char buf
[10];
2230 if (ch
== _POSIX_VDISABLE
)
2249 *bpout
++ = ch
- 128;
2259 *bpout
++ = ch
- 128 + 64;
2269 return (const char *) buf
;
2272 /* Parse string S as an integer, using decimal radix by default,
2273 but allowing octal and hex numbers as in C. Reject values
2274 larger than MAXVAL. */
2276 static unsigned long int
2277 integer_arg (const char *s
, unsigned long int maxval
)
2279 return xnumtoumax (s
, 0, 0, maxval
, "bB", _("invalid integer argument"), 0);