2 * Copyright (c) 1988, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * @(#)hack.tty.c 8.1 (Berkeley) 5/31/93
30 * $FreeBSD: src/games/hack/hack.tty.c,v 1.6.2.1 2000/07/20 10:35:07 kris Exp $
31 * $DragonFly: src/games/hack/hack.tty.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $
34 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
35 /* hack.tty.c - version 1.0.3 */
37 * With thanks to the people who sent code for SYSV - hpscdi!jon,
38 * arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others.
45 * Some systems may have getchar() return EOF for various reasons, and
46 * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
47 * FIXME: is this still valid nowadays?
51 static char erase_char
, kill_char
;
52 static boolean settty_needed
= FALSE
;
53 struct termios inittyb
, curttyb
;
55 static void setctty(void);
58 * Get initial state of terminal, set ospeed (for termcap routines)
59 * and switch off tab expansion if necessary.
60 * Called by startup() in termcap.c and after returning from ! or ^Z
65 if (tcgetattr(fileno(stdin
), &inittyb
) < 0)
66 perror("Hack (gettty)");
68 erase_char
= inittyb
.c_cc
[VERASE
];
69 kill_char
= inittyb
.c_cc
[VKILL
];
72 /* do not expand tabs - they might be needed inside a cm sequence */
73 if (curttyb
.c_oflag
& OXTABS
) {
74 curttyb
.c_oflag
&= ~OXTABS
;
80 /* reset terminal to original state */
89 if (tcsetattr(fileno(stdin
), TCSANOW
, &inittyb
) < 0)
90 perror("Hack (settty)");
91 flags
.echo
= (inittyb
.c_lflag
& ECHO
) ? ON
: OFF
;
92 flags
.cbreak
= (inittyb
.c_lflag
& ICANON
) ? OFF
: ON
;
99 if (tcsetattr(fileno(stdin
), TCSANOW
, &curttyb
) < 0)
100 perror("Hack (setctty)");
106 u_long ef
= 0; /* desired value of flags & ECHO */
107 u_long cf
= !(ICANON
); /* desired value of flags & CBREAK */
112 /* Should use (ECHO|CRMOD) here instead of ECHO */
113 if ((curttyb
.c_lflag
& ECHO
) != ef
) {
114 curttyb
.c_lflag
&= ~ECHO
;
117 if ((curttyb
.c_lflag
& ICANON
) != cf
) {
118 curttyb
.c_lflag
&= ~ICANON
;
119 curttyb
.c_lflag
|= cf
;
120 /* be satisfied with one character; no timeout */
121 curttyb
.c_cc
[VMIN
] = 1; /* was VEOF */
122 curttyb
.c_cc
[VTIME
] = 0; /* was VEOL */
133 error(const char *s
, ...)
147 * Read a line closed with '\n' into the array char bufp[BUFSZ].
148 * (The '\n' is not stored. The string is closed with a '\0'.)
149 * Reading can be interrupted by an escape ('\033') - now the
150 * resulting string is "\033".
158 flags
.toplin
= 2; /* nonempty, no --More-- required */
161 if ((c
= getchar()) == EOF
) {
170 if (c
== erase_char
|| c
== '\b') {
173 putstr("\b \b"); /* putsym converts \b */
176 } else if (c
== '\n') {
179 } else if (' ' <= c
&& c
< '\177') {
181 * avoid isprint() - some people don't have it ' ' is
182 * not always a printing char
187 if (bufp
- obufp
< BUFSZ
- 1 && bufp
- obufp
< COLNO
)
189 } else if (c
== kill_char
|| c
== '\177') { /* Robert Viduya */
190 /* this test last - @ might be the kill_char */
191 while (bufp
!= obufp
) {
207 cgetret(const char *s
)
213 putstr(flags
.cbreak
? "space" : "return");
214 putstr(" to continue: ");
220 char morc
; /* tell the outside world what char he used */
223 xwaitforspace(const char *s
) /* chars allowed besides space or return */
228 while ((c
= readchar()) != '\n') {
232 if (s
&& strchr(s
, c
)) {
244 static char inputline
[COLNO
];
252 while ((foo
= readchar()) >= '0' && foo
<= '9')
253 multi
= 10 * multi
+ foo
- '0';
260 if (foo
== 'f' || foo
== 'F') {
261 inputline
[1] = getchar();
263 if (inputline
[1] == foo
)
264 inputline
[2] = getchar();
269 if (foo
== 'm' || foo
== 'M') {
270 inputline
[1] = getchar();
283 if ((sym
= getchar()) == EOF
)
286 * Some SYSV systems seem to return EOFs for various reasons
287 * (?like when one hits break or for interrupted systemcalls?),
288 * and we must see several before we quit.
290 int cnt
= NR_OF_EOFS
;
292 clearerr(stdin
); /* omit if clearerr is undefined */
293 if ((sym
= getchar()) != EOF
)
301 #endif /* NR_OF_EOFS */
302 if (flags
.toplin
== 1)
310 settty("End of input?\n");