1 /* $NetBSD: set.c,v 1.11 2006/05/01 23:18:37 christos Exp $ */
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)set.c 8.2 (Berkeley) 2/28/94";
37 __RCSID("$NetBSD: set.c,v 1.11 2006/05/01 23:18:37 christos Exp $");
46 #define CHK(val, dft) (val <= 0 ? dft : val)
48 int set_tabs
__P((void));
51 * Reset the terminal mode bits to a sensible state. Very useful after
52 * a child program dies in raw mode.
57 tcgetattr(STDERR_FILENO
, &mode
);
59 #if defined(VDISCARD) && defined(CDISCARD)
60 mode
.c_cc
[VDISCARD
] = CHK(mode
.c_cc
[VDISCARD
], CDISCARD
);
62 mode
.c_cc
[VEOF
] = CHK(mode
.c_cc
[VEOF
], CEOF
);
63 mode
.c_cc
[VERASE
] = CHK(mode
.c_cc
[VERASE
], CERASE
);
64 #if defined(VFLUSH) && defined(CFLUSH)
65 mode
.c_cc
[VFLUSH
] = CHK(mode
.c_cc
[VFLUSH
], CFLUSH
);
67 mode
.c_cc
[VINTR
] = CHK(mode
.c_cc
[VINTR
], CINTR
);
68 mode
.c_cc
[VKILL
] = CHK(mode
.c_cc
[VKILL
], CKILL
);
69 #if defined(VLNEXT) && defined(CLNEXT)
70 mode
.c_cc
[VLNEXT
] = CHK(mode
.c_cc
[VLNEXT
], CLNEXT
);
72 mode
.c_cc
[VQUIT
] = CHK(mode
.c_cc
[VQUIT
], CQUIT
);
73 #if defined(VREPRINT) && defined(CRPRNT)
74 mode
.c_cc
[VREPRINT
] = CHK(mode
.c_cc
[VREPRINT
], CRPRNT
);
76 mode
.c_cc
[VSTART
] = CHK(mode
.c_cc
[VSTART
], CSTART
);
77 mode
.c_cc
[VSTOP
] = CHK(mode
.c_cc
[VSTOP
], CSTOP
);
78 mode
.c_cc
[VSUSP
] = CHK(mode
.c_cc
[VSUSP
], CSUSP
);
79 #if defined(VWERASE) && defined(CWERASE)
80 mode
.c_cc
[VWERASE
] = CHK(mode
.c_cc
[VWERASE
], CWERASE
);
83 mode
.c_iflag
&= ~(IGNBRK
| PARMRK
| INPCK
| ISTRIP
| INLCR
| IGNCR
92 mode
.c_iflag
|= (BRKINT
| IGNPAR
| ICRNL
| IXON
118 | NLDLY
| CRDLY
| TABDLY
| BSDLY
| VTDLY
| FFDLY
122 mode
.c_oflag
|= (OPOST
128 mode
.c_cflag
&= ~(CSIZE
| CSTOPB
| PARENB
| PARODD
);
129 mode
.c_cflag
|= (CS8
| CREAD
);
130 mode
.c_lflag
&= ~(ECHONL
| NOFLSH
| TOSTOP
139 mode
.c_lflag
|= (ISIG
| ICANON
| ECHO
| ECHOE
| ECHOK
148 tcsetattr(STDERR_FILENO
, TCSADRAIN
, &mode
);
152 * Determine the erase, interrupt, and kill characters from the termcap
153 * entry and command line and update their values in 'mode'.
156 set_control_chars(int erasechar
, int intrchar
, int killchar
)
158 char *bp
, *p
, bs_char
, buf
[1024];
161 p
= tgetstr("kb", &bp
);
162 if (p
== NULL
|| p
[1] != '\0')
163 p
= tgetstr("bc", &bp
);
164 if (p
!= NULL
&& p
[1] == '\0')
166 else if (tgetflag("bs"))
171 if (erasechar
== 0 && !tgetflag("os") && mode
.c_cc
[VERASE
] != CERASE
) {
172 if (tgetflag("bs") || bs_char
!= 0)
176 erasechar
= (bs_char
!= 0) ? bs_char
: CTRL('h');
178 if (mode
.c_cc
[VERASE
] == 0 || erasechar
!= 0)
179 mode
.c_cc
[VERASE
] = erasechar
? erasechar
: CERASE
;
181 if (mode
.c_cc
[VINTR
] == 0 || intrchar
!= 0)
182 mode
.c_cc
[VINTR
] = intrchar
? intrchar
: CINTR
;
184 if (mode
.c_cc
[VKILL
] == 0 || killchar
!= 0)
185 mode
.c_cc
[VKILL
] = killchar
? killchar
: CKILL
;
189 * Set up various conversions in 'mode', including parity, tabs, returns,
190 * echo, and case, according to the termcap entry. If the program we're
191 * running was named with a leading upper-case character, map external
192 * uppercase to internal lowercase.
195 set_conversions(int usingupper
)
197 if (tgetflag("UC") || usingupper
) {
199 mode
.c_iflag
|= IUCLC
;
200 mode
.c_oflag
|= OLCUC
;
202 } else if (tgetflag("LC")) {
204 mode
.c_iflag
&= ~IUCLC
;
205 mode
.c_oflag
&= ~OLCUC
;
208 mode
.c_iflag
&= ~(PARMRK
| INPCK
);
209 mode
.c_lflag
|= ICANON
;
210 if (tgetflag("EP")) {
211 mode
.c_cflag
|= PARENB
;
212 mode
.c_cflag
&= ~PARODD
;
214 if (tgetflag("OP")) {
215 mode
.c_cflag
|= PARENB
;
216 mode
.c_cflag
|= PARODD
;
220 mode
.c_oflag
|= ONLCR
;
222 mode
.c_iflag
|= ICRNL
;
223 mode
.c_lflag
|= ECHO
;
224 mode
.c_oflag
|= OXTABS
;
225 if (tgetflag("NL")) { /* Newline, not linefeed. */
227 mode
.c_oflag
&= ~ONLCR
;
229 mode
.c_iflag
&= ~ICRNL
;
231 if (tgetflag("HD")) /* Half duplex. */
232 mode
.c_lflag
&= ~ECHO
;
233 if (tgetflag("pt")) /* Print tabs. */
234 mode
.c_oflag
&= ~OXTABS
;
235 mode
.c_lflag
|= (ECHOE
| ECHOK
);
238 /* Output startup string. */
246 if (tgetstr("pc", &bp
) != 0) /* Get/set pad character. */
250 if (oldmode
.c_oflag
& (TAB3
| ONLCR
| OCRNL
| ONLRET
)) {
251 oldmode
.c_oflag
&= (TAB3
| ONLCR
| OCRNL
| ONLRET
);
252 tcsetattr(STDERR_FILENO
, TCSADRAIN
, &oldmode
);
259 if (tgetstr("rs", &bp
) != 0 || tgetstr("is", &bp
) != 0) {
264 if (tgetstr("rf", &bp
) != 0 || tgetstr("if", &bp
) != 0) {
271 (void)putc('\r', stderr
);
272 (void)fflush(stderr
);
273 (void)sleep(1); /* Settle the terminal. */
278 * Set the hardware tabs on the terminal, using the ct (clear all tabs),
279 * st (set one tab) and ch (horizontal cursor addressing) capabilities.
280 * This is done before if and is, so they can patch in case we blow this.
281 * Return nonzero if we set any tab stops, zero if not.
287 char *capsp
, *clear_tabs
;
288 char *set_column
, *set_tab
;
293 set_tab
= tgetstr("st", &capsp
);
295 if (set_tab
&& (clear_tabs
= tgetstr("ct", &capsp
))) {
296 (void)putc('\r', stderr
); /* Force to left margin. */
297 tputs(clear_tabs
, 0, outc
);
300 set_column
= tgetstr("ch", &capsp
);
303 for (c
= 8; c
< columns
; c
+= 8) {
305 * Get to the right column. "OOPS" is returned by
306 * tgoto() if it can't do the job. (*snarl*)
310 tg_out
= tgoto(set_column
, 0, c
);
312 tputs(tg_out
, 1, outc
);
314 (void)fprintf(stderr
, "%s", " ");
316 tputs(set_tab
, 0, outc
);