1 /* stty -- change and print terminal line settings
2 Copyright (C) 1990-2001 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Usage: stty [-ag] [--all] [--save] [-F device] [--file=device] [setting...]
21 -a, --all Write all current settings to stdout in human-readable form.
22 -g, --save Write all current settings to stdout in stty-readable form.
23 -F, --file Open and use the specified device instead of stdin
25 If no args are given, write to stdout the baud rate and settings that
26 have been changed from their defaults. Mode reading and changes
27 are done on the specified device, or stdin if none was specified.
29 David MacKenzie <djm@gnu.ai.mit.edu> */
33 #ifdef TERMIOS_NEEDS_XOPEN_SOURCE
34 # define _XOPEN_SOURCE
38 #include <sys/types.h>
42 #ifdef GWINSZ_IN_SYS_IOCTL
43 # include <sys/ioctl.h>
45 #ifdef WINSIZE_IN_PTEM
46 # include <sys/stream.h>
47 # include <sys/ptem.h>
49 #ifdef GWINSZ_IN_SYS_PTY
50 # include <sys/ioctl.h>
57 # define VA_START(args, lastarg) va_start(args, lastarg)
60 # define VA_START(args, lastarg) va_start(args)
64 #include "long-options.h"
69 /* The official name of this program (e.g., no `g' prefix). */
70 #define PROGRAM_NAME "stty"
72 #define AUTHORS "David MacKenzie"
74 #ifndef _POSIX_VDISABLE
75 # define _POSIX_VDISABLE ((unsigned char) 0)
78 #define Control(c) ((c) & 0x1f)
79 /* Canonical values for control characters. */
81 # define CINTR Control ('c')
90 # define CKILL Control ('u')
93 # define CEOF Control ('d')
96 # define CEOL _POSIX_VDISABLE
99 # define CSTART Control ('q')
102 # define CSTOP Control ('s')
105 # define CSUSP Control ('z')
107 #if defined(VEOL2) && !defined(CEOL2)
108 # define CEOL2 _POSIX_VDISABLE
110 /* ISC renamed swtch to susp for termios, but we'll accept either name. */
111 #if defined(VSUSP) && !defined(VSWTCH)
112 # define VSWTCH VSUSP
113 # define CSWTCH CSUSP
115 #if defined(VSWTCH) && !defined(CSWTCH)
116 # define CSWTCH _POSIX_VDISABLE
119 /* SunOS 5.3 loses (^Z doesn't work) if `swtch' is the same as `susp'.
120 So the default is to disable `swtch.' */
121 #if defined (__sparc__) && defined (__svr4__)
123 # define CSWTCH _POSIX_VDISABLE
126 #if defined(VWERSE) && !defined (VWERASE) /* AIX-3.2.5 */
127 # define VWERASE VWERSE
129 #if defined(VDSUSP) && !defined (CDSUSP)
130 # define CDSUSP Control ('y')
132 #if !defined(VREPRINT) && defined(VRPRNT) /* Irix 4.0.5 */
133 # define VREPRINT VRPRNT
135 #if defined(VREPRINT) && !defined(CRPRNT)
136 # define CRPRNT Control ('r')
138 #if defined(CREPRINT) && !defined(CRPRNT)
139 # define CRPRNT Control ('r')
141 #if defined(VWERASE) && !defined(CWERASE)
142 # define CWERASE Control ('w')
144 #if defined(VLNEXT) && !defined(CLNEXT)
145 # define CLNEXT Control ('v')
147 #if defined(VDISCARD) && !defined(VFLUSHO)
148 # define VFLUSHO VDISCARD
150 #if defined(VFLUSH) && !defined(VFLUSHO) /* Ultrix 4.2 */
151 # define VFLUSHO VFLUSH
153 #if defined(CTLECH) && !defined(ECHOCTL) /* Ultrix 4.3 */
154 # define ECHOCTL CTLECH
156 #if defined(TCTLECH) && !defined(ECHOCTL) /* Ultrix 4.2 */
157 # define ECHOCTL TCTLECH
159 #if defined(CRTKIL) && !defined(ECHOKE) /* Ultrix 4.2 and 4.3 */
160 # define ECHOKE CRTKIL
162 #if defined(VFLUSHO) && !defined(CFLUSHO)
163 # define CFLUSHO Control ('o')
165 #if defined(VSTATUS) && !defined(CSTATUS)
166 # define CSTATUS Control ('t')
169 /* Which speeds to set. */
172 input_speed
, output_speed
, both_speeds
175 /* What to output and how. */
178 changed
, all
, recoverable
/* Default, -a, -g. */
181 /* Which member(s) of `struct termios' a mode uses. */
184 control
, input
, output
, local
, combination
187 /* Flags for `struct mode_info'. */
188 #define SANE_SET 1 /* Set in `sane' mode. */
189 #define SANE_UNSET 2 /* Unset in `sane' mode. */
190 #define REV 4 /* Can be turned off by prepending `-'. */
191 #define OMIT 8 /* Don't display value. */
196 const char *name
; /* Name given on command line. */
197 enum mode_type type
; /* Which structure element to change. */
198 char flags
; /* Setting and display options. */
199 unsigned long bits
; /* Bits to set for this mode. */
200 unsigned long mask
; /* Other bits to turn off for this mode. */
203 static struct mode_info mode_info
[] =
205 {"parenb", control
, REV
, PARENB
, 0},
206 {"parodd", control
, REV
, PARODD
, 0},
207 {"cs5", control
, 0, CS5
, CSIZE
},
208 {"cs6", control
, 0, CS6
, CSIZE
},
209 {"cs7", control
, 0, CS7
, CSIZE
},
210 {"cs8", control
, 0, CS8
, CSIZE
},
211 {"hupcl", control
, REV
, HUPCL
, 0},
212 {"hup", control
, REV
| OMIT
, HUPCL
, 0},
213 {"cstopb", control
, REV
, CSTOPB
, 0},
214 {"cread", control
, SANE_SET
| REV
, CREAD
, 0},
215 {"clocal", control
, REV
, CLOCAL
, 0},
217 {"crtscts", control
, REV
, CRTSCTS
, 0},
220 {"ignbrk", input
, SANE_UNSET
| REV
, IGNBRK
, 0},
221 {"brkint", input
, SANE_SET
| REV
, BRKINT
, 0},
222 {"ignpar", input
, REV
, IGNPAR
, 0},
223 {"parmrk", input
, REV
, PARMRK
, 0},
224 {"inpck", input
, REV
, INPCK
, 0},
225 {"istrip", input
, REV
, ISTRIP
, 0},
226 {"inlcr", input
, SANE_UNSET
| REV
, INLCR
, 0},
227 {"igncr", input
, SANE_UNSET
| REV
, IGNCR
, 0},
228 {"icrnl", input
, SANE_SET
| REV
, ICRNL
, 0},
229 {"ixon", input
, REV
, IXON
, 0},
230 {"ixoff", input
, SANE_UNSET
| REV
, IXOFF
, 0},
231 {"tandem", input
, REV
| OMIT
, IXOFF
, 0},
233 {"iuclc", input
, SANE_UNSET
| REV
, IUCLC
, 0},
236 {"ixany", input
, SANE_UNSET
| REV
, IXANY
, 0},
239 {"imaxbel", input
, SANE_SET
| REV
, IMAXBEL
, 0},
242 {"opost", output
, SANE_SET
| REV
, OPOST
, 0},
244 {"olcuc", output
, SANE_UNSET
| REV
, OLCUC
, 0},
247 {"ocrnl", output
, SANE_UNSET
| REV
, OCRNL
, 0},
250 {"onlcr", output
, SANE_SET
| REV
, ONLCR
, 0},
253 {"onocr", output
, SANE_UNSET
| REV
, ONOCR
, 0},
256 {"onlret", output
, SANE_UNSET
| REV
, ONLRET
, 0},
259 {"ofill", output
, SANE_UNSET
| REV
, OFILL
, 0},
262 {"ofdel", output
, SANE_UNSET
| REV
, OFDEL
, 0},
265 {"nl1", output
, SANE_UNSET
, NL1
, NLDLY
},
266 {"nl0", output
, SANE_SET
, NL0
, NLDLY
},
269 {"cr3", output
, SANE_UNSET
, CR3
, CRDLY
},
270 {"cr2", output
, SANE_UNSET
, CR2
, CRDLY
},
271 {"cr1", output
, SANE_UNSET
, CR1
, CRDLY
},
272 {"cr0", output
, SANE_SET
, CR0
, CRDLY
},
275 {"tab3", output
, SANE_UNSET
, TAB3
, TABDLY
},
276 {"tab2", output
, SANE_UNSET
, TAB2
, TABDLY
},
277 {"tab1", output
, SANE_UNSET
, TAB1
, TABDLY
},
278 {"tab0", output
, SANE_SET
, TAB0
, TABDLY
},
281 {"tab3", output
, SANE_UNSET
, OXTABS
, 0},
285 {"bs1", output
, SANE_UNSET
, BS1
, BSDLY
},
286 {"bs0", output
, SANE_SET
, BS0
, BSDLY
},
289 {"vt1", output
, SANE_UNSET
, VT1
, VTDLY
},
290 {"vt0", output
, SANE_SET
, VT0
, VTDLY
},
293 {"ff1", output
, SANE_UNSET
, FF1
, FFDLY
},
294 {"ff0", output
, SANE_SET
, FF0
, FFDLY
},
297 {"isig", local
, SANE_SET
| REV
, ISIG
, 0},
298 {"icanon", local
, SANE_SET
| REV
, ICANON
, 0},
300 {"iexten", local
, SANE_SET
| REV
, IEXTEN
, 0},
302 {"echo", local
, SANE_SET
| REV
, ECHO
, 0},
303 {"echoe", local
, SANE_SET
| REV
, ECHOE
, 0},
304 {"crterase", local
, REV
| OMIT
, ECHOE
, 0},
305 {"echok", local
, SANE_SET
| REV
, ECHOK
, 0},
306 {"echonl", local
, SANE_UNSET
| REV
, ECHONL
, 0},
307 {"noflsh", local
, SANE_UNSET
| REV
, NOFLSH
, 0},
309 {"xcase", local
, SANE_UNSET
| REV
, XCASE
, 0},
312 {"tostop", local
, SANE_UNSET
| REV
, TOSTOP
, 0},
315 {"echoprt", local
, SANE_UNSET
| REV
, ECHOPRT
, 0},
316 {"prterase", local
, REV
| OMIT
, ECHOPRT
, 0},
319 {"echoctl", local
, SANE_SET
| REV
, ECHOCTL
, 0},
320 {"ctlecho", local
, REV
| OMIT
, ECHOCTL
, 0},
323 {"echoke", local
, SANE_SET
| REV
, ECHOKE
, 0},
324 {"crtkill", local
, REV
| OMIT
, ECHOKE
, 0},
327 {"evenp", combination
, REV
| OMIT
, 0, 0},
328 {"parity", combination
, REV
| OMIT
, 0, 0},
329 {"oddp", combination
, REV
| OMIT
, 0, 0},
330 {"nl", combination
, REV
| OMIT
, 0, 0},
331 {"ek", combination
, OMIT
, 0, 0},
332 {"sane", combination
, OMIT
, 0, 0},
333 {"cooked", combination
, REV
| OMIT
, 0, 0},
334 {"raw", combination
, REV
| OMIT
, 0, 0},
335 {"pass8", combination
, REV
| OMIT
, 0, 0},
336 {"litout", combination
, REV
| OMIT
, 0, 0},
337 {"cbreak", combination
, REV
| OMIT
, 0, 0},
339 {"decctlq", combination
, REV
| OMIT
, 0, 0},
341 #if defined (TABDLY) || defined (OXTABS)
342 {"tabs", combination
, REV
| OMIT
, 0, 0},
344 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
345 {"lcase", combination
, REV
| OMIT
, 0, 0},
346 {"LCASE", combination
, REV
| OMIT
, 0, 0},
348 {"crt", combination
, OMIT
, 0, 0},
349 {"dec", combination
, OMIT
, 0, 0},
351 {NULL
, control
, 0, 0, 0}
354 /* Control character settings. */
357 const char *name
; /* Name given on command line. */
358 unsigned char saneval
; /* Value to set for `stty sane'. */
359 int offset
; /* Offset in c_cc. */
362 /* Control characters. */
364 static struct control_info control_info
[] =
366 {"intr", CINTR
, VINTR
},
367 {"quit", CQUIT
, VQUIT
},
368 {"erase", CERASE
, VERASE
},
369 {"kill", CKILL
, VKILL
},
373 {"eol2", CEOL2
, VEOL2
},
376 {"swtch", CSWTCH
, VSWTCH
},
378 {"start", CSTART
, VSTART
},
379 {"stop", CSTOP
, VSTOP
},
380 {"susp", CSUSP
, VSUSP
},
382 {"dsusp", CDSUSP
, VDSUSP
},
385 {"rprnt", CRPRNT
, VREPRINT
},
387 # ifdef CREPRINT /* HPUX 10.20 needs this */
388 {"rprnt", CRPRNT
, CREPRINT
},
392 {"werase", CWERASE
, VWERASE
},
395 {"lnext", CLNEXT
, VLNEXT
},
398 {"flush", CFLUSHO
, VFLUSHO
},
401 {"status", CSTATUS
, VSTATUS
},
404 /* These must be last because of the display routines. */
410 static const char *visible
PARAMS ((unsigned int ch
));
411 static unsigned long baud_to_value
PARAMS ((speed_t speed
));
412 static int recover_mode
PARAMS ((char *arg
, struct termios
*mode
));
413 static int screen_columns
PARAMS ((void));
414 static int set_mode
PARAMS ((struct mode_info
*info
, int reversed
,
415 struct termios
*mode
));
416 static long integer_arg
PARAMS ((const char *s
));
417 static speed_t string_to_baud
PARAMS ((const char *arg
));
418 static tcflag_t
*mode_type_flag
PARAMS ((enum mode_type type
,
419 struct termios
*mode
));
420 static void display_all
PARAMS ((struct termios
*mode
, int fd
,
421 const char *device_name
));
422 static void display_changed
PARAMS ((struct termios
*mode
));
423 static void display_recoverable
PARAMS ((struct termios
*mode
));
424 static void display_settings
PARAMS ((enum output_type output_type
,
425 struct termios
*mode
, int fd
,
426 const char *device_name
));
427 static void display_speed
PARAMS ((struct termios
*mode
, int fancy
));
428 static void display_window_size
PARAMS ((int fancy
, int fd
,
429 const char *device_name
));
430 static void sane_mode
PARAMS ((struct termios
*mode
));
431 static void set_control_char
PARAMS ((struct control_info
*info
,
433 struct termios
*mode
));
434 static void set_speed
PARAMS ((enum speed_setting type
, const char *arg
,
435 struct termios
*mode
));
436 static void set_window_size
PARAMS ((int rows
, int cols
, int fd
,
437 const char *device_name
));
439 /* The width of the screen, for output wrapping. */
442 /* Current position, to know when to wrap. */
443 static int current_col
;
445 static struct option longopts
[] =
447 {"all", no_argument
, NULL
, 'a'},
448 {"save", no_argument
, NULL
, 'g'},
449 {"file", required_argument
, NULL
, 'F'},
453 /* The name this program was run with. */
456 /* Print format string MESSAGE and optional args.
457 Wrap to next line first if it won't fit.
458 Print a space first unless MESSAGE will start a new line. */
463 wrapf (const char *message
,...)
465 wrapf (message
, va_alist
)
471 char buf
[1024]; /* Plenty long for our needs. */
474 VA_START (args
, message
);
475 vsprintf (buf
, message
, args
);
477 buflen
= strlen (buf
);
479 && max_col
<= current_col
+ (0 < current_col
) + buflen
)
490 current_col
+= buflen
;
497 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
502 Usage: %s [-F DEVICE] [--file=DEVICE] [SETTING]...\n\
503 or: %s [-F DEVICE] [--file=DEVICE] [-a|--all]\n\
504 or: %s [-F DEVICE] [--file=DEVICE] [-g|--save]\n\
506 program_name
, program_name
, program_name
);
508 Print or change terminal characteristics.\n\
510 -a, --all print all current settings in human-readable form\n\
511 -g, --save print all current settings in a stty-readable form\n\
512 -F, --file=DEVICE open and use the specified DEVICE instead of stdin\n\
514 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
515 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
518 Optional - before SETTING indicates negation. An * marks non-POSIX\n\
519 settings. The underlying system defines which settings are available.\n\
523 Special characters:\n\
524 * dsusp CHAR CHAR will send a terminal stop signal once input flushed\n\
525 eof CHAR CHAR will send an end of file (terminate the input)\n\
526 eol CHAR CHAR will end the line\n\
529 * eol2 CHAR alternate CHAR for ending the line\n\
530 erase CHAR CHAR will erase the last character typed\n\
531 intr CHAR CHAR will send an interrupt signal\n\
532 kill CHAR CHAR will erase the current line\n\
535 * lnext CHAR CHAR will enter the next character quoted\n\
536 quit CHAR CHAR will send a quit signal\n\
537 * rprnt CHAR CHAR will redraw the current line\n\
538 start CHAR CHAR will restart the output after stopping it\n\
541 stop CHAR CHAR will stop the output\n\
542 susp CHAR CHAR will send a terminal stop signal\n\
543 * swtch CHAR CHAR will switch to a different shell layer\n\
544 * werase CHAR CHAR will erase the last word typed\n\
549 N set the input and output speeds to N bauds\n\
550 * cols N tell the kernel that the terminal has N columns\n\
551 * columns N same as cols N\n\
554 ispeed N set the input speed to N\n\
555 * line N use line discipline N\n\
556 min N with -icanon, set N characters minimum for a completed read\n\
557 ospeed N set the output speed to N\n\
560 * rows N tell the kernel that the terminal has N rows\n\
561 * size print the number of rows and columns according to the kernel\n\
562 speed print the terminal speed\n\
563 time N with -icanon, set read timeout of N tenths of a second\n\
568 [-]clocal disable modem control signals\n\
569 [-]cread allow input to be received\n\
570 * [-]crtscts enable RTS/CTS handshaking\n\
571 csN set character size to N bits, N in [5..8]\n\
574 [-]cstopb use two stop bits per character (one with `-')\n\
575 [-]hup send a hangup signal when the last process closes the tty\n\
576 [-]hupcl same as [-]hup\n\
577 [-]parenb generate parity bit in output and expect parity bit in input\n\
578 [-]parodd set odd parity (even with `-')\n\
583 [-]brkint breaks cause an interrupt signal\n\
584 [-]icrnl translate carriage return to newline\n\
585 [-]ignbrk ignore break characters\n\
586 [-]igncr ignore carriage return\n\
589 [-]ignpar ignore characters with parity errors\n\
590 * [-]imaxbel beep and do not flush a full input buffer on a character\n\
591 [-]inlcr translate newline to carriage return\n\
592 [-]inpck enable input parity checking\n\
593 [-]istrip clear high (8th) bit of input characters\n\
596 * [-]iuclc translate uppercase characters to lowercase\n\
597 * [-]ixany let any character restart output, not only start character\n\
598 [-]ixoff enable sending of start/stop characters\n\
599 [-]ixon enable XON/XOFF flow control\n\
600 [-]parmrk mark parity errors (with a 255-0-character sequence)\n\
601 [-]tandem same as [-]ixoff\n\
606 * bsN backspace delay style, N in [0..1]\n\
607 * crN carriage return delay style, N in [0..3]\n\
608 * ffN form feed delay style, N in [0..1]\n\
609 * nlN newline delay style, N in [0..1]\n\
612 * [-]ocrnl translate carriage return to newline\n\
613 * [-]ofdel use delete characters for fill instead of null characters\n\
614 * [-]ofill use fill (padding) characters instead of timing for delays\n\
615 * [-]olcuc translate lowercase characters to uppercase\n\
616 * [-]onlcr translate newline to carriage return-newline\n\
617 * [-]onlret newline performs a carriage return\n\
620 * [-]onocr do not print carriage returns in the first column\n\
621 [-]opost postprocess output\n\
622 * tabN horizontal tab delay style, N in [0..3]\n\
623 * tabs same as tab0\n\
624 * -tabs same as tab3\n\
625 * vtN vertical tab delay style, N in [0..1]\n\
630 [-]crterase echo erase characters as backspace-space-backspace\n\
631 * crtkill kill all line by obeying the echoprt and echoe settings\n\
632 * -crtkill kill all line by obeying the echoctl and echok settings\n\
635 * [-]ctlecho echo control characters in hat notation (`^c')\n\
636 [-]echo echo input characters\n\
637 * [-]echoctl same as [-]ctlecho\n\
638 [-]echoe same as [-]crterase\n\
639 [-]echok echo a newline after a kill character\n\
642 * [-]echoke same as [-]crtkill\n\
643 [-]echonl echo newline even if not echoing other characters\n\
644 * [-]echoprt echo erased characters backward, between `\\' and '/'\n\
645 [-]icanon enable erase, kill, werase, and rprnt special characters\n\
646 [-]iexten enable non-POSIX special characters\n\
649 [-]isig enable interrupt, quit, and suspend special characters\n\
650 [-]noflsh disable flushing after interrupt and quit special characters\n\
651 * [-]prterase same as [-]echoprt\n\
652 * [-]tostop stop background jobs that try to write to the terminal\n\
653 * [-]xcase with icanon, escape with `\\' for uppercase characters\n\
657 Combination settings:\n\
658 * [-]LCASE same as [-]lcase\n\
659 cbreak same as -icanon\n\
660 -cbreak same as icanon\n\
663 cooked same as brkint ignpar istrip icrnl ixon opost isig\n\
664 icanon, eof and eol characters to their default values\n\
665 -cooked same as raw\n\
666 crt same as echoe echoctl echoke\n\
669 dec same as echoe echoctl echoke -ixany intr ^c erase 0177\n\
671 * [-]decctlq same as [-]ixany\n\
672 ek erase and kill characters to their default values\n\
673 evenp same as parenb -parodd cs7\n\
676 -evenp same as -parenb cs8\n\
677 * [-]lcase same as xcase iuclc olcuc\n\
678 litout same as -parenb -istrip -opost cs8\n\
679 -litout same as parenb istrip opost cs7\n\
680 nl same as -icrnl -onlcr\n\
681 -nl same as icrnl -inlcr -igncr onlcr -ocrnl -onlret\n\
684 oddp same as parenb parodd cs7\n\
685 -oddp same as -parenb cs8\n\
686 [-]parity same as [-]evenp\n\
687 pass8 same as -parenb -istrip cs8\n\
688 -pass8 same as parenb istrip cs7\n\
691 raw same as -ignbrk -brkint -ignpar -parmrk -inpck -istrip\n\
692 -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany\n\
693 -imaxbel -opost -isig -icanon -xcase min 1 time 0\n\
694 -raw same as cooked\n\
697 sane same as cread -ignbrk brkint -inlcr -igncr icrnl\n\
698 -ixoff -iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr\n\
699 -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0\n\
700 isig icanon iexten echo echoe echok -echonl -noflsh\n\
701 -xcase -tostop -echoprt echoctl echoke, all special\n\
702 characters to their default values.\n\
706 Handle the tty line connected to standard input. Without arguments,\n\
707 prints baud rate, line discipline, and deviations from stty sane. In\n\
708 settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
709 127; special values ^- or undef used to disable special characters.\n\
711 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
716 /* Return 1 if the string contains only valid options. */
718 valid_options (char *opt
, const char *valid_opts
,
719 const char *valid_arg_opts
)
723 if (*opt
++ != '-' || *opt
== 0)
729 if (strchr (valid_opts
, ch
))
731 if (strchr (valid_arg_opts
, ch
))
739 main (int argc
, char **argv
)
742 enum output_type output_type
;
744 int require_set_attr
;
747 int recoverable_output
;
750 char *file_name
= NULL
;
752 const char *device_name
;
753 const char *posixly_correct
= getenv ("POSIXLY_CORRECT");
754 int invalid_long_option
= 0;
756 program_name
= argv
[0];
757 setlocale (LC_ALL
, "");
758 bindtextdomain (PACKAGE
, LOCALEDIR
);
759 textdomain (PACKAGE
);
761 atexit (close_stdout
);
763 parse_long_options (argc
, argv
, PROGRAM_NAME
, GNU_PACKAGE
, VERSION
,
766 output_type
= changed
;
768 recoverable_output
= 0;
770 /* Don't print error messages for unrecognized options. */
773 while ((optc
= getopt_long (argc
, argv
, "agF:", longopts
, NULL
)) != -1)
775 int unrecognized_option
= 0;
784 recoverable_output
= 1;
785 output_type
= recoverable
;
790 error (2, 0, _("only one device may be specified"));
795 unrecognized_option
= 1;
799 if (unrecognized_option
)
803 /* FIXME: what is this?!? */
804 if (invalid_long_option
)
807 /* Clear out the options that have been parsed. This is really
808 gross, but it's needed because stty SETTINGS look like options to
809 getopt(), so we need to work around things in a really horrible
810 way. If any new options are ever added to stty, the short option
811 MUST NOT be a letter which is the first letter of one of the
812 possible stty settings. If you change anything about how stty
813 parses options, be sure it still works with combinations of
814 short and long options, --, POSIXLY_CORRECT, etc. */
815 for (k
= 1; k
< argc
; k
++)
823 /* Handle --, and reset noargs if there are arguments following it. */
824 if (STREQ (argv
[k
], "--"))
832 /* Handle "--file device" */
833 len
= strlen (argv
[k
]);
834 if (len
>= 3 && strstr ("--file", argv
[k
]))
841 /* Handle "--all" and "--save". */
843 && (strstr ("--all", argv
[k
])
844 || strstr ("--save", argv
[k
])))
850 /* Handle "--file=device". */
851 eq
= strchr (argv
[k
], '=');
852 if (eq
&& eq
- argv
[k
] >= 3)
855 if (strstr ("--file", argv
[k
]))
860 /* Put the equals sign back for the error message. */
864 /* Handle "-a", "-ag", "-aF/dev/foo", "-aF /dev/foo", etc. */
865 if (valid_options (argv
[k
], "ag", "F"))
867 /* FIXME: this loses when the device name ends in `F'.
868 e.g. `stty -F/dev/BARF nl' would clobber the `nl' argument. */
869 if (argv
[k
][strlen (argv
[k
]) - 1] == 'F')
873 /* Everything else must be a normal, non-option argument. */
882 /* Specifying both -a and -g gets an error. */
883 if (verbose_output
&& recoverable_output
)
885 _("the options for verbose and stty-readable output styles are\n\
886 mutually exclusive"));
888 /* Specifying any other arguments with -a or -g gets an error. */
889 if (!noargs
&& (verbose_output
|| recoverable_output
))
890 error (2, 0, _("when specifying an output style, modes may not be set"));
892 /* FIXME: it'd be better not to open the file until we've verified
893 that all arguments are valid. Otherwise, we could end up doing
894 only some of the requested operations and then failing, probably
895 leaving things in an undesirable state. */
900 device_name
= file_name
;
901 fd
= open (device_name
, O_RDONLY
| O_NONBLOCK
);
903 error (1, errno
, "%s", device_name
);
904 if ((fdflags
= fcntl (fd
, F_GETFL
)) == -1
905 || fcntl (fd
, F_SETFL
, fdflags
& ~O_NONBLOCK
) < 0)
906 error (1, errno
, _("%s: couldn't reset non-blocking mode"),
912 device_name
= _("standard input");
915 /* Initialize to all zeroes so there is no risk memcmp will report a
916 spurious difference in an uninitialized portion of the structure. */
917 memset (&mode
, 0, sizeof (mode
));
918 if (tcgetattr (fd
, &mode
))
919 error (1, errno
, "%s", device_name
);
921 if (verbose_output
|| recoverable_output
|| noargs
)
923 max_col
= screen_columns ();
925 display_settings (output_type
, &mode
, fd
, device_name
);
930 require_set_attr
= 0;
944 if (argv
[k
][0] == '-')
949 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
951 if (STREQ (argv
[k
], mode_info
[i
].name
))
953 match_found
= set_mode (&mode_info
[i
], reversed
, &mode
);
954 require_set_attr
= 1;
958 if (match_found
== 0 && reversed
)
960 error (0, 0, _("invalid argument `%s'"), --argv
[k
]);
963 if (match_found
== 0)
965 for (i
= 0; control_info
[i
].name
!= NULL
; ++i
)
967 if (STREQ (argv
[k
], control_info
[i
].name
))
971 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
976 set_control_char (&control_info
[i
], argv
[k
], &mode
);
977 require_set_attr
= 1;
982 if (match_found
== 0)
984 if (STREQ (argv
[k
], "ispeed"))
988 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
992 set_speed (input_speed
, argv
[k
], &mode
);
994 require_set_attr
= 1;
996 else if (STREQ (argv
[k
], "ospeed"))
1000 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1004 set_speed (output_speed
, argv
[k
], &mode
);
1006 require_set_attr
= 1;
1009 else if (STREQ (argv
[k
], "rows"))
1013 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1017 set_window_size ((int) integer_arg (argv
[k
]), -1,
1020 else if (STREQ (argv
[k
], "cols")
1021 || STREQ (argv
[k
], "columns"))
1025 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1029 set_window_size (-1, (int) integer_arg (argv
[k
]),
1032 else if (STREQ (argv
[k
], "size"))
1034 max_col
= screen_columns ();
1036 display_window_size (0, fd
, device_name
);
1040 else if (STREQ (argv
[k
], "line"))
1044 error (0, 0, _("missing argument to `%s'"), argv
[k
]);
1048 mode
.c_line
= integer_arg (argv
[k
]);
1049 require_set_attr
= 1;
1052 else if (STREQ (argv
[k
], "speed"))
1054 max_col
= screen_columns ();
1055 display_speed (&mode
, 0);
1057 else if (string_to_baud (argv
[k
]) != (speed_t
) -1)
1059 set_speed (both_speeds
, argv
[k
], &mode
);
1061 require_set_attr
= 1;
1065 if (recover_mode (argv
[k
], &mode
) == 0)
1067 error (0, 0, _("invalid argument `%s'"), argv
[k
]);
1070 require_set_attr
= 1;
1076 if (require_set_attr
)
1078 struct termios new_mode
;
1080 if (tcsetattr (fd
, TCSADRAIN
, &mode
))
1081 error (1, errno
, "%s", device_name
);
1083 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if
1084 it performs *any* of the requested operations. This means it
1085 can report `success' when it has actually failed to perform
1086 some proper subset of the requested operations. To detect
1087 this partial failure, get the current terminal attributes and
1088 compare them to the requested ones. */
1090 /* Initialize to all zeroes so there is no risk memcmp will report a
1091 spurious difference in an uninitialized portion of the structure. */
1092 memset (&new_mode
, 0, sizeof (new_mode
));
1093 if (tcgetattr (fd
, &new_mode
))
1094 error (1, errno
, "%s", device_name
);
1096 /* Normally, one shouldn't use memcmp to compare structures that
1097 may have `holes' containing uninitialized data, but we have been
1098 careful to initialize the storage of these two variables to all
1099 zeroes. One might think it more efficient simply to compare the
1100 modified fields, but that would require enumerating those fields --
1101 and not all systems have the same fields in this structure. */
1103 if (memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1106 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1107 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1108 sometimes (m1 != m2). The only difference is in the four bits
1109 of the c_cflag field corresponding to the baud rate. To save
1110 Sun users a little confusion, don't report an error if this
1111 happens. But suppress the error only if we haven't tried to
1112 set the baud rate explicitly -- otherwise we'd never give an
1113 error for a true failure to set the baud rate. */
1115 new_mode
.c_cflag
&= (~CIBAUD
);
1116 if (speed_was_set
|| memcmp (&mode
, &new_mode
, sizeof (mode
)) != 0)
1120 _("%s: unable to perform all requested operations"),
1125 printf (_("new_mode: mode\n"));
1126 for (i
= 0; i
< sizeof (new_mode
); i
++)
1127 printf ("0x%02x: 0x%02x\n",
1128 *(((unsigned char *) &new_mode
) + i
),
1129 *(((unsigned char *) &mode
) + i
));
1139 /* Return 0 if not applied because not reversible; otherwise return 1. */
1142 set_mode (struct mode_info
*info
, int reversed
, struct termios
*mode
)
1146 if (reversed
&& (info
->flags
& REV
) == 0)
1149 bitsp
= mode_type_flag (info
->type
, mode
);
1153 /* Combination mode. */
1154 if (STREQ (info
->name
, "evenp") || STREQ (info
->name
, "parity"))
1157 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1159 mode
->c_cflag
= (mode
->c_cflag
& ~PARODD
& ~CSIZE
) | PARENB
| CS7
;
1161 else if (STREQ (info
->name
, "oddp"))
1164 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1166 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARODD
| PARENB
;
1168 else if (STREQ (info
->name
, "nl"))
1172 mode
->c_iflag
= (mode
->c_iflag
| ICRNL
) & ~INLCR
& ~IGNCR
;
1173 mode
->c_oflag
= (mode
->c_oflag
1188 mode
->c_iflag
= mode
->c_iflag
& ~ICRNL
;
1190 mode
->c_oflag
= mode
->c_oflag
& ~ONLCR
;
1194 else if (STREQ (info
->name
, "ek"))
1196 mode
->c_cc
[VERASE
] = CERASE
;
1197 mode
->c_cc
[VKILL
] = CKILL
;
1199 else if (STREQ (info
->name
, "sane"))
1201 else if (STREQ (info
->name
, "cbreak"))
1204 mode
->c_lflag
|= ICANON
;
1206 mode
->c_lflag
&= ~ICANON
;
1208 else if (STREQ (info
->name
, "pass8"))
1212 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1213 mode
->c_iflag
|= ISTRIP
;
1217 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1218 mode
->c_iflag
&= ~ISTRIP
;
1221 else if (STREQ (info
->name
, "litout"))
1225 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
1226 mode
->c_iflag
|= ISTRIP
;
1227 mode
->c_oflag
|= OPOST
;
1231 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
1232 mode
->c_iflag
&= ~ISTRIP
;
1233 mode
->c_oflag
&= ~OPOST
;
1236 else if (STREQ (info
->name
, "raw") || STREQ (info
->name
, "cooked"))
1238 if ((info
->name
[0] == 'r' && reversed
)
1239 || (info
->name
[0] == 'c' && !reversed
))
1242 mode
->c_iflag
|= BRKINT
| IGNPAR
| ISTRIP
| ICRNL
| IXON
;
1243 mode
->c_oflag
|= OPOST
;
1244 mode
->c_lflag
|= ISIG
| ICANON
;
1246 mode
->c_cc
[VEOF
] = CEOF
;
1249 mode
->c_cc
[VEOL
] = CEOL
;
1256 mode
->c_oflag
&= ~OPOST
;
1257 mode
->c_lflag
&= ~(ISIG
| ICANON
1262 mode
->c_cc
[VMIN
] = 1;
1263 mode
->c_cc
[VTIME
] = 0;
1267 else if (STREQ (info
->name
, "decctlq"))
1270 mode
->c_iflag
|= IXANY
;
1272 mode
->c_iflag
&= ~IXANY
;
1276 else if (STREQ (info
->name
, "tabs"))
1279 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB3
;
1281 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB0
;
1285 else if (STREQ (info
->name
, "tabs"))
1288 mode
->c_oflag
= mode
->c_oflag
| OXTABS
;
1290 mode
->c_oflag
= mode
->c_oflag
& ~OXTABS
;
1294 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
1295 else if (STREQ (info
->name
, "lcase")
1296 || STREQ (info
->name
, "LCASE"))
1300 mode
->c_lflag
&= ~XCASE
;
1301 mode
->c_iflag
&= ~IUCLC
;
1302 mode
->c_oflag
&= ~OLCUC
;
1306 mode
->c_lflag
|= XCASE
;
1307 mode
->c_iflag
|= IUCLC
;
1308 mode
->c_oflag
|= OLCUC
;
1312 else if (STREQ (info
->name
, "crt"))
1313 mode
->c_lflag
|= ECHOE
1321 else if (STREQ (info
->name
, "dec"))
1323 mode
->c_cc
[VINTR
] = 3; /* ^C */
1324 mode
->c_cc
[VERASE
] = 127; /* DEL */
1325 mode
->c_cc
[VKILL
] = 21; /* ^U */
1326 mode
->c_lflag
|= ECHOE
1335 mode
->c_iflag
&= ~IXANY
;
1340 *bitsp
= *bitsp
& ~info
->mask
& ~info
->bits
;
1342 *bitsp
= (*bitsp
& ~info
->mask
) | info
->bits
;
1348 set_control_char (struct control_info
*info
, const char *arg
,
1349 struct termios
*mode
)
1351 unsigned char value
;
1353 if (STREQ (info
->name
, "min") || STREQ (info
->name
, "time"))
1354 value
= integer_arg (arg
);
1355 else if (arg
[0] == '\0' || arg
[1] == '\0')
1357 else if (STREQ (arg
, "^-") || STREQ (arg
, "undef"))
1358 value
= _POSIX_VDISABLE
;
1359 else if (arg
[0] == '^' && arg
[1] != '\0') /* Ignore any trailing junk. */
1364 value
= arg
[1] & ~0140; /* Non-letters get weird results. */
1367 value
= integer_arg (arg
);
1368 mode
->c_cc
[info
->offset
] = value
;
1372 set_speed (enum speed_setting type
, const char *arg
, struct termios
*mode
)
1376 baud
= string_to_baud (arg
);
1377 if (type
== input_speed
|| type
== both_speeds
)
1378 cfsetispeed (mode
, baud
);
1379 if (type
== output_speed
|| type
== both_speeds
)
1380 cfsetospeed (mode
, baud
);
1386 get_win_size (int fd
, struct winsize
*win
)
1388 int err
= ioctl (fd
, TIOCGWINSZ
, (char *) win
);
1393 set_window_size (int rows
, int cols
, int fd
, const char *device_name
)
1397 if (get_win_size (fd
, &win
))
1399 if (errno
!= EINVAL
)
1400 error (1, errno
, "%s", device_name
);
1401 memset (&win
, 0, sizeof (win
));
1410 /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote:
1411 The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.
1412 This comment from sys/ttold.h describes Sun's twisted logic - a better
1413 test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).
1414 At any rate, the problem is gone in Solaris 2.x.
1416 Unfortunately, the old TIOCSSIZE code does collide with TIOCSWINSZ,
1417 but they can be disambiguated by checking whether a "struct ttysize"
1418 structure's "ts_lines" field is greater than 64K or not. If so,
1419 it's almost certainly a "struct winsize" instead.
1421 At any rate, the bug manifests itself when ws_row == 0; the symptom is
1422 that ws_row is set to ws_col, and ws_col is set to (ws_xpixel<<16) +
1423 ws_ypixel. Since GNU stty sets rows and columns separately, this bug
1424 caused "stty rows 0 cols 0" to set rows to cols and cols to 0, while
1425 "stty cols 0 rows 0" would do the right thing. On a little-endian
1426 machine like the sun386i, the problem is the same, but for ws_col == 0.
1428 The workaround is to do the ioctl once with row and col = 1 to set the
1429 pixel info, and then do it again using a TIOCSSIZE to set rows/cols. */
1431 if (win
.ws_row
== 0 || win
.ws_col
== 0)
1433 struct ttysize ttysz
;
1435 ttysz
.ts_lines
= win
.ws_row
;
1436 ttysz
.ts_cols
= win
.ws_col
;
1441 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1442 error (1, errno
, "%s", device_name
);
1444 if (ioctl (fd
, TIOCSSIZE
, (char *) &ttysz
))
1445 error (1, errno
, "%s", device_name
);
1450 if (ioctl (fd
, TIOCSWINSZ
, (char *) &win
))
1451 error (1, errno
, "%s", device_name
);
1455 display_window_size (int fancy
, int fd
, const char *device_name
)
1459 if (get_win_size (fd
, &win
))
1461 if (errno
!= EINVAL
)
1462 error (1, errno
, "%s", device_name
);
1464 error (1, 0, _("%s: no size information for this device"), device_name
);
1468 wrapf (fancy
? "rows %d; columns %d;" : "%d %d\n",
1469 win
.ws_row
, win
.ws_col
);
1477 screen_columns (void)
1482 /* With Solaris 2.[123], this ioctl fails and errno is set to
1483 EINVAL for telnet (but not rlogin) sessions.
1484 On ISC 3.0, it fails for the console and the serial port
1485 (but it works for ptys).
1486 It can also fail on any system when stdout isn't a tty.
1487 In case of any failure, just use the default. */
1488 if (get_win_size (STDOUT_FILENO
, &win
) == 0 && 0 < win
.ws_col
)
1492 /* Use $COLUMNS if it's in [1..INT_MAX-1]. */
1493 char *col_string
= getenv ("COLUMNS");
1495 if (!(col_string
!= NULL
1496 && xstrtol (col_string
, NULL
, 0, &n_columns
, "") == LONGINT_OK
1498 && n_columns
< INT_MAX
))
1505 mode_type_flag (enum mode_type type
, struct termios
*mode
)
1510 return &mode
->c_cflag
;
1513 return &mode
->c_iflag
;
1516 return &mode
->c_oflag
;
1519 return &mode
->c_lflag
;
1530 display_settings (enum output_type output_type
, struct termios
*mode
,
1531 int fd
, const char *device_name
)
1533 switch (output_type
)
1536 display_changed (mode
);
1540 display_all (mode
, fd
, device_name
);
1544 display_recoverable (mode
);
1550 display_changed (struct termios
*mode
)
1556 enum mode_type prev_type
= control
;
1558 display_speed (mode
, 1);
1560 wrapf ("line = %d;", mode
->c_line
);
1566 for (i
= 0; !STREQ (control_info
[i
].name
, "min"); ++i
)
1568 if (mode
->c_cc
[control_info
[i
].offset
] == control_info
[i
].saneval
)
1570 /* If swtch is the same as susp, don't print both. */
1572 if (STREQ (control_info
[i
].name
, "swtch"))
1575 /* If eof uses the same slot as min, only print whichever applies. */
1577 if ((mode
->c_lflag
& ICANON
) == 0
1578 && (STREQ (control_info
[i
].name
, "eof")
1579 || STREQ (control_info
[i
].name
, "eol")))
1584 wrapf ("%s = %s;", control_info
[i
].name
,
1585 visible (mode
->c_cc
[control_info
[i
].offset
]));
1587 if ((mode
->c_lflag
& ICANON
) == 0)
1589 wrapf ("min = %d; time = %d;\n", (int) mode
->c_cc
[VMIN
],
1590 (int) mode
->c_cc
[VTIME
]);
1592 else if (empty_line
== 0)
1597 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1599 if (mode_info
[i
].flags
& OMIT
)
1601 if (mode_info
[i
].type
!= prev_type
)
1603 if (empty_line
== 0)
1609 prev_type
= mode_info
[i
].type
;
1612 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1613 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1614 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1616 if (mode_info
[i
].flags
& SANE_UNSET
)
1618 wrapf ("%s", mode_info
[i
].name
);
1622 else if ((mode_info
[i
].flags
& (SANE_SET
| REV
)) == (SANE_SET
| REV
))
1624 wrapf ("-%s", mode_info
[i
].name
);
1628 if (empty_line
== 0)
1634 display_all (struct termios
*mode
, int fd
, const char *device_name
)
1639 enum mode_type prev_type
= control
;
1641 display_speed (mode
, 1);
1643 display_window_size (1, fd
, device_name
);
1646 wrapf ("line = %d;", mode
->c_line
);
1651 for (i
= 0; ! STREQ (control_info
[i
].name
, "min"); ++i
)
1653 /* If swtch is the same as susp, don't print both. */
1655 if (STREQ (control_info
[i
].name
, "swtch"))
1658 /* If eof uses the same slot as min, only print whichever applies. */
1660 if ((mode
->c_lflag
& ICANON
) == 0
1661 && (STREQ (control_info
[i
].name
, "eof")
1662 || STREQ (control_info
[i
].name
, "eol")))
1665 wrapf ("%s = %s;", control_info
[i
].name
,
1666 visible (mode
->c_cc
[control_info
[i
].offset
]));
1669 if ((mode
->c_lflag
& ICANON
) == 0)
1671 wrapf ("min = %d; time = %d;", mode
->c_cc
[VMIN
], mode
->c_cc
[VTIME
]);
1672 if (current_col
!= 0)
1676 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1678 if (mode_info
[i
].flags
& OMIT
)
1680 if (mode_info
[i
].type
!= prev_type
)
1684 prev_type
= mode_info
[i
].type
;
1687 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1688 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1689 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1690 wrapf ("%s", mode_info
[i
].name
);
1691 else if (mode_info
[i
].flags
& REV
)
1692 wrapf ("-%s", mode_info
[i
].name
);
1699 display_speed (struct termios
*mode
, int fancy
)
1701 if (cfgetispeed (mode
) == 0 || cfgetispeed (mode
) == cfgetospeed (mode
))
1702 wrapf (fancy
? "speed %lu baud;" : "%lu\n",
1703 baud_to_value (cfgetospeed (mode
)));
1705 wrapf (fancy
? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n",
1706 baud_to_value (cfgetispeed (mode
)),
1707 baud_to_value (cfgetospeed (mode
)));
1713 display_recoverable (struct termios
*mode
)
1717 printf ("%lx:%lx:%lx:%lx",
1718 (unsigned long) mode
->c_iflag
, (unsigned long) mode
->c_oflag
,
1719 (unsigned long) mode
->c_cflag
, (unsigned long) mode
->c_lflag
);
1720 for (i
= 0; i
< NCCS
; ++i
)
1721 printf (":%x", (unsigned int) mode
->c_cc
[i
]);
1726 recover_mode (char *arg
, struct termios
*mode
)
1730 unsigned long iflag
, oflag
, cflag
, lflag
;
1732 /* Scan into temporaries since it is too much trouble to figure out
1733 the right format for `tcflag_t'. */
1734 if (sscanf (arg
, "%lx:%lx:%lx:%lx%n",
1735 &iflag
, &oflag
, &cflag
, &lflag
, &n
) != 4)
1737 mode
->c_iflag
= iflag
;
1738 mode
->c_oflag
= oflag
;
1739 mode
->c_cflag
= cflag
;
1740 mode
->c_lflag
= lflag
;
1742 for (i
= 0; i
< NCCS
; ++i
)
1744 if (sscanf (arg
, ":%x%n", &chr
, &n
) != 1)
1746 mode
->c_cc
[i
] = chr
;
1750 /* Fail if there are too many fields. */
1759 const char *string
; /* ASCII representation. */
1760 speed_t speed
; /* Internal form. */
1761 unsigned long value
; /* Numeric value. */
1764 struct speed_map speeds
[] =
1771 {"134.5", B134
, 134},
1776 {"1200", B1200
, 1200},
1777 {"1800", B1800
, 1800},
1778 {"2400", B2400
, 2400},
1779 {"4800", B4800
, 4800},
1780 {"9600", B9600
, 9600},
1781 {"19200", B19200
, 19200},
1782 {"38400", B38400
, 38400},
1783 {"exta", B19200
, 19200},
1784 {"extb", B38400
, 38400},
1786 {"57600", B57600
, 57600},
1789 {"115200", B115200
, 115200},
1792 {"230400", B230400
, 230400},
1795 {"460800", B460800
, 460800},
1801 string_to_baud (const char *arg
)
1805 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1806 if (STREQ (arg
, speeds
[i
].string
))
1807 return speeds
[i
].speed
;
1808 return (speed_t
) -1;
1811 static unsigned long
1812 baud_to_value (speed_t speed
)
1816 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1817 if (speed
== speeds
[i
].speed
)
1818 return speeds
[i
].value
;
1823 sane_mode (struct termios
*mode
)
1828 for (i
= 0; control_info
[i
].name
; ++i
)
1831 if (STREQ (control_info
[i
].name
, "min"))
1834 mode
->c_cc
[control_info
[i
].offset
] = control_info
[i
].saneval
;
1837 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1839 if (mode_info
[i
].flags
& SANE_SET
)
1841 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1842 *bitsp
= (*bitsp
& ~mode_info
[i
].mask
) | mode_info
[i
].bits
;
1844 else if (mode_info
[i
].flags
& SANE_UNSET
)
1846 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1847 *bitsp
= *bitsp
& ~mode_info
[i
].mask
& ~mode_info
[i
].bits
;
1852 /* Return a string that is the printable representation of character CH. */
1853 /* Adapted from `cat' by Torbjorn Granlund. */
1856 visible (unsigned int ch
)
1858 static char buf
[10];
1861 if (ch
== _POSIX_VDISABLE
)
1880 *bpout
++ = ch
- 128;
1890 *bpout
++ = ch
- 128 + 64;
1900 return (const char *) buf
;
1903 /* Parse string S as an integer, using decimal radix by default,
1904 but allowing octal and hex numbers as in C. */
1905 /* From `od' by Richard Stallman. */
1908 integer_arg (const char *s
)
1911 if (xstrtol (s
, NULL
, 0, &value
, "bB") != LONGINT_OK
)
1913 error (0, 0, _("invalid integer argument `%s'"), s
);