1 /* stty -- change and print terminal line settings
2 Copyright (C) 1990, 1991 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
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Usage: stty [-ag] [--all] [--save] [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.
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
28 David MacKenzie <djm@gnu.ai.mit.edu> */
31 #if defined (CONFIG_BROKETS)
32 /* We use <config.h> instead of "config.h" so that a compilation
33 using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
34 (which it would do because it found this file in $srcdir). */
42 #include <sys/types.h>
44 #ifdef GWINSZ_IN_SYS_IOCTL
45 #include <sys/ioctl.h>
47 #ifdef WINSIZE_IN_PTEM
48 #include <sys/stream.h>
54 #define VA_START(args, lastarg) va_start(args, lastarg)
57 #define VA_START(args, lastarg) va_start(args)
63 #if defined(GWINSZ_BROKEN) /* Such as for SCO UNIX 3.2.2. */
67 #ifndef _POSIX_VDISABLE
68 #define _POSIX_VDISABLE ((unsigned char) 0)
71 #define Control(c) ((c) & 0x1f)
72 /* Canonical values for control characters. */
74 #define CINTR Control ('c')
83 #define CKILL Control ('u')
86 #define CEOF Control ('d')
89 #define CEOL _POSIX_VDISABLE
92 #define CSTART Control ('q')
95 #define CSTOP Control ('s')
98 #define CSUSP Control ('z')
100 #if defined(VEOL2) && !defined(CEOL2)
101 #define CEOL2 _POSIX_VDISABLE
103 #if defined(VSWTCH) && !defined(CSWTCH)
104 #define CSWTCH _POSIX_VDISABLE
106 #if defined(VDSUSP) && !defined (CDSUSP)
107 #define CDSUSP Control ('y')
109 #if !defined(VREPRINT) && defined(VRPRNT) /* Irix 4.0.5 */
110 #define VREPRINT VRPRNT
112 #if defined(VREPRINT) && !defined(CRPRNT)
113 #define CRPRNT Control ('r')
115 #if defined(VWERASE) && !defined(CWERASE)
116 #define CWERASE Control ('w')
118 #if defined(VLNEXT) && !defined(CLNEXT)
119 #define CLNEXT Control ('v')
121 #if defined(VFLUSHO) && !defined(CFLUSHO)
122 #define CFLUSHO Control ('o')
126 unsigned long baud_to_value ();
128 int screen_columns ();
131 speed_t
string_to_baud ();
132 tcflag_t
*mode_type_flag ();
134 void display_changed ();
135 void display_recoverable ();
136 void display_settings ();
137 void display_speed ();
138 void display_window_size ();
141 void set_control_char ();
143 void set_window_size ();
145 /* Which speeds to set. */
148 input_speed
, output_speed
, both_speeds
151 /* What to output and how. */
154 changed
, all
, recoverable
/* Default, -a, -g. */
157 /* Which member(s) of `struct termios' a mode uses. */
160 control
, input
, output
, local
, combination
163 /* Flags for `struct mode_info'. */
164 #define SANE_SET 1 /* Set in `sane' mode. */
165 #define SANE_UNSET 2 /* Unset in `sane' mode. */
166 #define REV 4 /* Can be turned off by prepending `-'. */
167 #define OMIT 8 /* Don't display value. */
172 char *name
; /* Name given on command line. */
173 enum mode_type type
; /* Which structure element to change. */
174 char flags
; /* Setting and display options. */
175 unsigned long bits
; /* Bits to set for this mode. */
176 unsigned long mask
; /* Other bits to turn off for this mode. */
179 static struct mode_info mode_info
[] =
181 {"parenb", control
, REV
, PARENB
, 0},
182 {"parodd", control
, REV
, PARODD
, 0},
183 {"cs5", control
, 0, CS5
, CSIZE
},
184 {"cs6", control
, 0, CS6
, CSIZE
},
185 {"cs7", control
, 0, CS7
, CSIZE
},
186 {"cs8", control
, 0, CS8
, CSIZE
},
187 {"hupcl", control
, REV
, HUPCL
, 0},
188 {"hup", control
, REV
| OMIT
, HUPCL
, 0},
189 {"cstopb", control
, REV
, CSTOPB
, 0},
190 {"cread", control
, SANE_SET
| REV
, CREAD
, 0},
191 {"clocal", control
, REV
, CLOCAL
, 0},
193 {"crtscts", control
, REV
, CRTSCTS
, 0},
196 {"ignbrk", input
, SANE_UNSET
| REV
, IGNBRK
, 0},
197 {"brkint", input
, SANE_SET
| REV
, BRKINT
, 0},
198 {"ignpar", input
, REV
, IGNPAR
, 0},
199 {"parmrk", input
, REV
, PARMRK
, 0},
200 {"inpck", input
, REV
, INPCK
, 0},
201 {"istrip", input
, REV
, ISTRIP
, 0},
202 {"inlcr", input
, SANE_UNSET
| REV
, INLCR
, 0},
203 {"igncr", input
, SANE_UNSET
| REV
, IGNCR
, 0},
204 {"icrnl", input
, SANE_SET
| REV
, ICRNL
, 0},
205 {"ixon", input
, REV
, IXON
, 0},
206 {"ixoff", input
, SANE_UNSET
| REV
, IXOFF
, 0},
207 {"tandem", input
, REV
| OMIT
, IXOFF
, 0},
209 {"iuclc", input
, SANE_UNSET
| REV
, IUCLC
, 0},
212 {"ixany", input
, SANE_UNSET
| REV
, IXANY
, 0},
215 {"imaxbel", input
, SANE_SET
| REV
, IMAXBEL
, 0},
218 {"opost", output
, SANE_SET
| REV
, OPOST
, 0},
220 {"olcuc", output
, SANE_UNSET
| REV
, OLCUC
, 0},
223 {"ocrnl", output
, SANE_UNSET
| REV
, OCRNL
, 0},
226 {"onlcr", output
, SANE_SET
| REV
, ONLCR
, 0},
229 {"onocr", output
, SANE_UNSET
| REV
, ONOCR
, 0},
232 {"onlret", output
, SANE_UNSET
| REV
, ONLRET
, 0},
235 {"ofill", output
, SANE_UNSET
| REV
, OFILL
, 0},
238 {"ofdel", output
, SANE_UNSET
| REV
, OFDEL
, 0},
241 {"nl1", output
, SANE_UNSET
, NL1
, NLDLY
},
242 {"nl0", output
, SANE_SET
, NL0
, NLDLY
},
245 {"cr3", output
, SANE_UNSET
, CR3
, CRDLY
},
246 {"cr2", output
, SANE_UNSET
, CR2
, CRDLY
},
247 {"cr1", output
, SANE_UNSET
, CR1
, CRDLY
},
248 {"cr0", output
, SANE_SET
, CR0
, CRDLY
},
251 {"tab3", output
, SANE_UNSET
, TAB3
, TABDLY
},
252 {"tab2", output
, SANE_UNSET
, TAB2
, TABDLY
},
253 {"tab1", output
, SANE_UNSET
, TAB1
, TABDLY
},
254 {"tab0", output
, SANE_SET
, TAB0
, TABDLY
},
257 {"bs1", output
, SANE_UNSET
, BS1
, BSDLY
},
258 {"bs0", output
, SANE_SET
, BS0
, BSDLY
},
261 {"vt1", output
, SANE_UNSET
, VT1
, VTDLY
},
262 {"vt0", output
, SANE_SET
, VT0
, VTDLY
},
265 {"ff1", output
, SANE_UNSET
, FF1
, FFDLY
},
266 {"ff0", output
, SANE_SET
, FF0
, FFDLY
},
269 {"isig", local
, SANE_SET
| REV
, ISIG
, 0},
270 {"icanon", local
, SANE_SET
| REV
, ICANON
, 0},
272 {"iexten", local
, SANE_SET
| REV
, IEXTEN
, 0},
274 {"echo", local
, SANE_SET
| REV
, ECHO
, 0},
275 {"echoe", local
, SANE_SET
| REV
, ECHOE
, 0},
276 {"crterase", local
, REV
| OMIT
, ECHOE
, 0},
277 {"echok", local
, SANE_SET
| REV
, ECHOK
, 0},
278 {"echonl", local
, SANE_UNSET
| REV
, ECHONL
, 0},
279 {"noflsh", local
, SANE_UNSET
| REV
, NOFLSH
, 0},
281 {"xcase", local
, SANE_UNSET
| REV
, XCASE
, 0},
284 {"tostop", local
, SANE_UNSET
| REV
, TOSTOP
, 0},
287 {"echoprt", local
, SANE_UNSET
| REV
, ECHOPRT
, 0},
288 {"prterase", local
, REV
| OMIT
, ECHOPRT
, 0},
291 {"echoctl", local
, SANE_SET
| REV
, ECHOCTL
, 0},
292 {"ctlecho", local
, REV
| OMIT
, ECHOCTL
, 0},
295 {"echoke", local
, SANE_SET
| REV
, ECHOKE
, 0},
296 {"crtkill", local
, REV
| OMIT
, ECHOKE
, 0},
299 {"evenp", combination
, REV
| OMIT
, 0, 0},
300 {"parity", combination
, REV
| OMIT
, 0, 0},
301 {"oddp", combination
, REV
| OMIT
, 0, 0},
302 {"nl", combination
, REV
| OMIT
, 0, 0},
303 {"ek", combination
, OMIT
, 0, 0},
304 {"sane", combination
, OMIT
, 0, 0},
305 {"cooked", combination
, REV
| OMIT
, 0, 0},
306 {"raw", combination
, REV
| OMIT
, 0, 0},
307 {"pass8", combination
, REV
| OMIT
, 0, 0},
308 {"litout", combination
, REV
| OMIT
, 0, 0},
309 {"cbreak", combination
, REV
| OMIT
, 0, 0},
311 {"decctlq", combination
, REV
| OMIT
, 0, 0},
314 {"tabs", combination
, REV
| OMIT
, 0, 0},
316 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
317 {"lcase", combination
, REV
| OMIT
, 0, 0},
318 {"LCASE", combination
, REV
| OMIT
, 0, 0},
320 {"crt", combination
, OMIT
, 0, 0},
321 {"dec", combination
, OMIT
, 0, 0},
323 {NULL
, control
, 0, 0, 0}
326 /* Control character settings. */
329 char *name
; /* Name given on command line. */
330 unsigned char saneval
; /* Value to set for `stty sane'. */
331 int offset
; /* Offset in c_cc. */
334 /* Control characters. */
336 static struct control_info control_info
[] =
338 {"intr", CINTR
, VINTR
},
339 {"quit", CQUIT
, VQUIT
},
340 {"erase", CERASE
, VERASE
},
341 {"kill", CKILL
, VKILL
},
345 {"eol2", CEOL2
, VEOL2
},
348 {"swtch", CSWTCH
, VSWTCH
},
350 {"start", CSTART
, VSTART
},
351 {"stop", CSTOP
, VSTOP
},
352 {"susp", CSUSP
, VSUSP
},
354 {"dsusp", CDSUSP
, VDSUSP
},
357 {"rprnt", CRPRNT
, VREPRINT
},
360 {"werase", CWERASE
, VWERASE
},
363 {"lnext", CLNEXT
, VLNEXT
},
366 {"flush", CFLUSHO
, VFLUSHO
},
369 /* These must be last because of the display routines. */
375 /* The width of the screen, for output wrapping. */
378 /* Current position, to know when to wrap. */
379 static int current_col
;
381 /* If non-zero, display usage information and exit. */
382 static int show_help
;
384 /* If non-zero, print the version on standard output and exit. */
385 static int show_version
;
387 static struct option longopts
[] =
389 {"all", no_argument
, NULL
, 'a'},
390 {"help", no_argument
, &show_help
, 1},
391 {"save", no_argument
, NULL
, 'g'},
392 {"version", no_argument
, &show_version
, 1},
396 /* The name this program was run with. */
399 /* Print format string MESSAGE and optional args.
400 Wrap to next line first if it won't fit.
401 Print a space first unless MESSAGE will start a new line. */
406 wrapf (char *message
, ...)
408 wrapf (message
, va_alist
)
414 char buf
[1024]; /* Plenty long for our needs. */
417 VA_START (args
, message
);
418 vsprintf (buf
, message
, args
);
420 buflen
= strlen (buf
);
421 if (current_col
+ buflen
>= max_col
)
432 current_col
+= buflen
;
439 "Usage: %s [{--help,--version}] [-ag] [--all] [--save] [setting...]\n",
450 enum output_type output_type
= changed
;
453 program_name
= argv
[0];
456 while ((optc
= getopt_long (argc
, argv
, "ag", longopts
, (int *) 0)) != EOF
)
468 output_type
= recoverable
;
480 printf ("%s\n", version_string
);
487 if (tcgetattr (0, &mode
))
488 error (1, errno
, "standard input");
490 max_col
= screen_columns ();
496 error (1, 0, "invalid argument `%s'", argv
[--optind
]);
497 display_settings (output_type
, &mode
);
501 while (optind
< argc
)
507 if (argv
[optind
][0] == '-')
512 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
514 if (!strcmp (argv
[optind
], mode_info
[i
].name
))
516 match_found
= set_mode (&mode_info
[i
], reversed
, &mode
);
520 if (match_found
== 0 && reversed
)
521 error (1, 0, "invalid argument `%s'", --argv
[optind
]);
522 if (match_found
== 0)
524 for (i
= 0; control_info
[i
].name
!= NULL
; ++i
)
526 if (!strcmp (argv
[optind
], control_info
[i
].name
))
528 if (optind
== argc
- 1)
529 error (1, 0, "missing argument to `%s'", argv
[optind
]);
532 set_control_char (&control_info
[i
], argv
[optind
], &mode
);
537 if (match_found
== 0)
539 if (!strcmp (argv
[optind
], "ispeed"))
541 if (optind
== argc
- 1)
542 error (1, 0, "missing argument to `%s'", argv
[optind
]);
544 set_speed (input_speed
, argv
[optind
], &mode
);
546 else if (!strcmp (argv
[optind
], "ospeed"))
548 if (optind
== argc
- 1)
549 error (1, 0, "missing argument to `%s'", argv
[optind
]);
551 set_speed (output_speed
, argv
[optind
], &mode
);
554 else if (!strcmp (argv
[optind
], "rows"))
556 if (optind
== argc
- 1)
557 error (1, 0, "missing argument to `%s'", argv
[optind
]);
559 set_window_size ((int) integer_arg (argv
[optind
]), -1);
561 else if (!strcmp (argv
[optind
], "cols")
562 || !strcmp (argv
[optind
], "columns"))
564 if (optind
== argc
- 1)
565 error (1, 0, "missing argument to `%s'", argv
[optind
]);
567 set_window_size (-1, (int) integer_arg (argv
[optind
]));
569 else if (!strcmp (argv
[optind
], "size"))
570 display_window_size (0);
573 else if (!strcmp (argv
[optind
], "line"))
575 if (optind
== argc
- 1)
576 error (1, 0, "missing argument to `%s'", argv
[optind
]);
578 mode
.c_line
= integer_arg (argv
[optind
]);
581 else if (!strcmp (argv
[optind
], "speed"))
582 display_speed (&mode
, 0);
583 else if (string_to_baud (argv
[optind
]) != (speed_t
) -1)
584 set_speed (both_speeds
, argv
[optind
], &mode
);
585 else if (recover_mode (argv
[optind
], &mode
) == 0)
586 error (1, 0, "invalid argument `%s'", argv
[optind
]);
591 if (tcsetattr (0, TCSADRAIN
, &mode
))
592 error (1, errno
, "standard input");
597 /* Return 0 if not applied because not reversible; otherwise return 1. */
600 set_mode (info
, reversed
, mode
)
601 struct mode_info
*info
;
603 struct termios
*mode
;
607 if (reversed
&& (info
->flags
& REV
) == 0)
610 bitsp
= mode_type_flag (info
->type
, mode
);
614 /* Combination mode. */
615 if (!strcmp (info
->name
, "evenp") || !strcmp (info
->name
, "parity"))
618 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
620 mode
->c_cflag
= (mode
->c_cflag
& ~PARODD
& ~CSIZE
) | PARENB
| CS7
;
622 else if (!strcmp (info
->name
, "oddp"))
625 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
627 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARODD
| PARENB
;
629 else if (!strcmp (info
->name
, "nl"))
633 mode
->c_iflag
= (mode
->c_iflag
| ICRNL
) & ~INLCR
& ~IGNCR
;
634 mode
->c_oflag
= (mode
->c_oflag
649 mode
->c_iflag
= mode
->c_iflag
& ~ICRNL
;
651 mode
->c_oflag
= mode
->c_oflag
& ~ONLCR
;
655 else if (!strcmp (info
->name
, "ek"))
657 mode
->c_cc
[VERASE
] = CERASE
;
658 mode
->c_cc
[VKILL
] = CKILL
;
660 else if (!strcmp (info
->name
, "sane"))
662 else if (!strcmp (info
->name
, "cbreak"))
665 mode
->c_lflag
|= ICANON
;
667 mode
->c_lflag
&= ~ICANON
;
669 else if (!strcmp (info
->name
, "pass8"))
673 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
674 mode
->c_iflag
|= ISTRIP
;
678 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
679 mode
->c_iflag
&= ~ISTRIP
;
682 else if (!strcmp (info
->name
, "litout"))
686 mode
->c_cflag
= (mode
->c_cflag
& ~CSIZE
) | CS7
| PARENB
;
687 mode
->c_iflag
|= ISTRIP
;
688 mode
->c_oflag
|= OPOST
;
692 mode
->c_cflag
= (mode
->c_cflag
& ~PARENB
& ~CSIZE
) | CS8
;
693 mode
->c_iflag
&= ~ISTRIP
;
694 mode
->c_oflag
&= ~OPOST
;
697 else if (!strcmp (info
->name
, "raw") || !strcmp (info
->name
, "cooked"))
699 if ((info
->name
[0] == 'r' && reversed
)
700 || (info
->name
[0] == 'c' && !reversed
))
703 mode
->c_iflag
|= BRKINT
| IGNPAR
| ISTRIP
| ICRNL
| IXON
;
704 mode
->c_oflag
|= OPOST
;
705 mode
->c_lflag
|= ISIG
| ICANON
;
707 mode
->c_cc
[VEOF
] = CEOF
;
710 mode
->c_cc
[VEOL
] = CEOL
;
717 mode
->c_oflag
&= ~OPOST
;
718 mode
->c_lflag
&= ~(ISIG
| ICANON
723 mode
->c_cc
[VMIN
] = 1;
724 mode
->c_cc
[VTIME
] = 0;
728 else if (!strcmp (info
->name
, "decctlq"))
731 mode
->c_iflag
|= IXANY
;
733 mode
->c_iflag
&= ~IXANY
;
737 else if (!strcmp (info
->name
, "tabs"))
740 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB3
;
742 mode
->c_oflag
= (mode
->c_oflag
& ~TABDLY
) | TAB0
;
745 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC)
746 else if (!strcmp (info
->name
, "lcase")
747 || !strcmp (info
->name
, "LCASE"))
751 mode
->c_lflag
&= ~XCASE
;
752 mode
->c_iflag
&= ~IUCLC
;
753 mode
->c_oflag
&= ~OLCUC
;
757 mode
->c_lflag
|= XCASE
;
758 mode
->c_iflag
|= IUCLC
;
759 mode
->c_oflag
|= OLCUC
;
763 else if (!strcmp (info
->name
, "crt"))
764 mode
->c_lflag
|= ECHOE
772 else if (!strcmp (info
->name
, "dec"))
774 mode
->c_cc
[VINTR
] = 3; /* ^C */
775 mode
->c_cc
[VERASE
] = 127; /* DEL */
776 mode
->c_cc
[VKILL
] = 21; /* ^U */
777 mode
->c_lflag
|= ECHOE
786 mode
->c_iflag
&= ~IXANY
;
791 *bitsp
= *bitsp
& ~info
->mask
& ~info
->bits
;
793 *bitsp
= (*bitsp
& ~info
->mask
) | info
->bits
;
799 set_control_char (info
, arg
, mode
)
800 struct control_info
*info
;
802 struct termios
*mode
;
806 if (!strcmp (info
->name
, "min") || !strcmp (info
->name
, "time"))
807 value
= integer_arg (arg
);
808 else if (arg
[0] == '\0' || arg
[1] == '\0')
810 else if (!strcmp (arg
, "^-") || !strcmp (arg
, "undef"))
811 value
= _POSIX_VDISABLE
;
812 else if (arg
[0] == '^' && arg
[1] != '\0') /* Ignore any trailing junk. */
817 value
= arg
[1] & ~0140; /* Non-letters get weird results. */
820 value
= integer_arg (arg
);
821 mode
->c_cc
[info
->offset
] = value
;
825 set_speed (type
, arg
, mode
)
826 enum speed_setting type
;
828 struct termios
*mode
;
832 baud
= string_to_baud (arg
);
833 if (type
== input_speed
|| type
== both_speeds
)
834 cfsetispeed (mode
, baud
);
835 if (type
== output_speed
|| type
== both_speeds
)
836 cfsetospeed (mode
, baud
);
841 set_window_size (rows
, cols
)
846 if (ioctl (0, TIOCGWINSZ
, (char *) &win
))
847 error (1, errno
, "standard input");
852 if (ioctl (0, TIOCSWINSZ
, (char *) &win
))
853 error (1, errno
, "standard input");
857 display_window_size (fancy
)
862 if (ioctl (0, TIOCGWINSZ
, (char *) &win
))
863 error (1, errno
, "standard input");
864 wrapf (fancy
? "rows %d; columns %d;" : "%d %d\n", win
.ws_row
, win
.ws_col
);
876 if (ioctl (0, TIOCGWINSZ
, (char *) &win
))
877 error (1, errno
, "standard input");
881 if (getenv ("COLUMNS"))
882 return atoi (getenv ("COLUMNS"));
887 mode_type_flag (type
, mode
)
889 struct termios
*mode
;
894 return &mode
->c_cflag
;
897 return &mode
->c_iflag
;
900 return &mode
->c_oflag
;
903 return &mode
->c_lflag
;
914 display_settings (output_type
, mode
)
915 enum output_type output_type
;
916 struct termios
*mode
;
921 display_changed (mode
);
929 display_recoverable (mode
);
935 display_changed (mode
)
936 struct termios
*mode
;
942 enum mode_type prev_type
= control
;
944 display_speed (mode
, 1);
946 wrapf ("line = %d;", mode
->c_line
);
952 for (i
= 0; strcmp (control_info
[i
].name
, "min"); ++i
)
954 if (mode
->c_cc
[control_info
[i
].offset
] == control_info
[i
].saneval
)
957 wrapf ("%s = %s;", control_info
[i
].name
,
958 visible (mode
->c_cc
[control_info
[i
].offset
]));
960 if ((mode
->c_lflag
& ICANON
) == 0)
962 wrapf ("min = %d; time = %d;\n", (int) mode
->c_cc
[VMIN
],
963 (int) mode
->c_cc
[VTIME
]);
965 else if (empty_line
== 0)
970 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
972 if (mode_info
[i
].flags
& OMIT
)
974 if (mode_info
[i
].type
!= prev_type
)
982 prev_type
= mode_info
[i
].type
;
985 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
986 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
987 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
989 if (mode_info
[i
].flags
& SANE_UNSET
)
991 wrapf ("%s", mode_info
[i
].name
);
995 else if ((mode_info
[i
].flags
& (SANE_SET
| REV
)) == (SANE_SET
| REV
))
997 wrapf ("-%s", mode_info
[i
].name
);
1001 if (empty_line
== 0)
1008 struct termios
*mode
;
1013 enum mode_type prev_type
= control
;
1015 display_speed (mode
, 1);
1017 display_window_size (1);
1020 wrapf ("line = %d;", mode
->c_line
);
1025 for (i
= 0; strcmp (control_info
[i
].name
, "min"); ++i
)
1027 wrapf ("%s = %s;", control_info
[i
].name
,
1028 visible (mode
->c_cc
[control_info
[i
].offset
]));
1030 wrapf ("min = %d; time = %d;\n", mode
->c_cc
[VMIN
], mode
->c_cc
[VTIME
]);
1033 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1035 if (mode_info
[i
].flags
& OMIT
)
1037 if (mode_info
[i
].type
!= prev_type
)
1041 prev_type
= mode_info
[i
].type
;
1044 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1045 mask
= mode_info
[i
].mask
? mode_info
[i
].mask
: mode_info
[i
].bits
;
1046 if ((*bitsp
& mask
) == mode_info
[i
].bits
)
1047 wrapf ("%s", mode_info
[i
].name
);
1048 else if (mode_info
[i
].flags
& REV
)
1049 wrapf ("-%s", mode_info
[i
].name
);
1056 display_speed (mode
, fancy
)
1057 struct termios
*mode
;
1060 if (cfgetispeed (mode
) == 0 || cfgetispeed (mode
) == cfgetospeed (mode
))
1061 wrapf (fancy
? "speed %lu baud;" : "%lu\n",
1062 baud_to_value (cfgetospeed (mode
)));
1064 wrapf (fancy
? "ispeed %lu baud; ospeed %lu baud;" : "%lu %lu\n",
1065 baud_to_value (cfgetispeed (mode
)),
1066 baud_to_value (cfgetospeed (mode
)));
1072 display_recoverable (mode
)
1073 struct termios
*mode
;
1077 printf ("%lx:%lx:%lx:%lx",
1078 (unsigned long) mode
->c_iflag
, (unsigned long) mode
->c_oflag
,
1079 (unsigned long) mode
->c_cflag
, (unsigned long) mode
->c_lflag
);
1080 for (i
= 0; i
< NCCS
; ++i
)
1081 printf (":%x", (unsigned int) mode
->c_cc
[i
]);
1086 recover_mode (arg
, mode
)
1088 struct termios
*mode
;
1092 unsigned long iflag
, oflag
, cflag
, lflag
;
1094 /* Scan into temporaries since it is too much trouble to figure out
1095 the right format for `tcflag_t'. */
1096 if (sscanf (arg
, "%lx:%lx:%lx:%lx%n",
1097 &iflag
, &oflag
, &cflag
, &lflag
, &n
) != 4)
1099 mode
->c_iflag
= iflag
;
1100 mode
->c_oflag
= oflag
;
1101 mode
->c_cflag
= cflag
;
1102 mode
->c_lflag
= lflag
;
1104 for (i
= 0; i
< NCCS
; ++i
)
1106 if (sscanf (arg
, ":%x%n", &chr
, &n
) != 1)
1108 mode
->c_cc
[i
] = chr
;
1116 char *string
; /* ASCII representation. */
1117 speed_t speed
; /* Internal form. */
1118 unsigned long value
; /* Numeric value. */
1121 struct speed_map speeds
[] =
1128 {"134.5", B134
, 134},
1133 {"1200", B1200
, 1200},
1134 {"1800", B1800
, 1800},
1135 {"2400", B2400
, 2400},
1136 {"4800", B4800
, 4800},
1137 {"9600", B9600
, 9600},
1138 {"19200", B19200
, 19200},
1139 {"38400", B38400
, 38400},
1140 {"exta", B19200
, 19200},
1141 {"extb", B38400
, 38400},
1143 {"57600", B57600
, 57600},
1146 {"115200", B115200
, 115200},
1152 string_to_baud (arg
)
1157 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1158 if (!strcmp (arg
, speeds
[i
].string
))
1159 return speeds
[i
].speed
;
1160 return (speed_t
) -1;
1164 baud_to_value (speed
)
1169 for (i
= 0; speeds
[i
].string
!= NULL
; ++i
)
1170 if (speed
== speeds
[i
].speed
)
1171 return speeds
[i
].value
;
1177 struct termios
*mode
;
1182 for (i
= 0; control_info
[i
].name
; ++i
)
1185 if (!strcmp (control_info
[i
].name
, "min"))
1188 mode
->c_cc
[control_info
[i
].offset
] = control_info
[i
].saneval
;
1191 for (i
= 0; mode_info
[i
].name
!= NULL
; ++i
)
1193 if (mode_info
[i
].flags
& SANE_SET
)
1195 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1196 *bitsp
= (*bitsp
& ~mode_info
[i
].mask
) | mode_info
[i
].bits
;
1198 else if (mode_info
[i
].flags
& SANE_UNSET
)
1200 bitsp
= mode_type_flag (mode_info
[i
].type
, mode
);
1201 *bitsp
= *bitsp
& ~mode_info
[i
].mask
& ~mode_info
[i
].bits
;
1206 /* Return a string that is the printable representation of character CH. */
1207 /* Adapted from `cat' by Torbjorn Granlund. */
1213 static char buf
[10];
1216 if (ch
== _POSIX_VDISABLE
)
1235 *bpout
++ = ch
- 128;
1245 *bpout
++ = ch
- 128 + 64;
1258 /* Parse string S as an integer, using decimal radix by default,
1259 but allowing octal and hex numbers as in C. */
1260 /* From `od' by Richard Stallman. */
1273 else if (*++p
== 'x')
1282 while (((c
= *p
++) >= '0' && c
<= '9')
1283 || (radix
== 16 && (c
& ~40) >= 'A' && (c
& ~40) <= 'Z'))
1286 if (c
>= '0' && c
<= '9')
1289 value
+= (c
& ~40) - 'A';
1300 error (1, 0, "invalid integer argument `%s'", s
);