-
Notifications
You must be signed in to change notification settings - Fork 0
/
tty.c
184 lines (170 loc) · 3.59 KB
/
tty.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
* TtySet ()
*
* - set terminal CBREAK mode.
*
* TtyReset ()
*
* - restore terminal mode.
*
* TtyFlushInput ()
* - flush input queue.
*/
#if HAVE_TERMIOS_H
# include <sys/termios.h>
# if HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
# endif
# define HAVE_TERMIO_H 1
# define termio termios
# ifdef sun
# undef TCGETA
# undef TCSETA
# undef TCSETAW
# undef TIOCSLTC
# define TCGETA TCGETS
# define TCSETA TCSETS
# define TCSETAW TCSETSW
# endif
#else
#if HAVE_TERMIO_H
# include <termio.h>
#else
# include <sgtty.h>
#endif
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "scr.h"
#ifndef TCGETA
# define TCGETA TIOCGETA
#endif
#ifndef TCSETA
# define TCSETA TIOCSETA
#endif
#ifndef TCSETAW
# define TCSETAW TIOCSETAW
#endif
#ifndef OLCUC
# define OLCUC 0
#endif
#ifndef IUCLC
# define IUCLC 0
#endif
#ifndef OCRNL
# define OCRNL 0
#endif
#ifndef XCASE
# define XCASE 0
#endif
#define CHANNEL 2 /* output file descriptor */
#if HAVE_TERMIO_H
static struct termio oldtio, newtio;
#else
static struct sgttyb tty;
static ttyflags;
#ifdef TIOCSETC
static struct tchars oldtchars, newtchars;
#endif
#endif
#ifdef TIOCSLTC
static struct ltchars oldchars, newchars;
#endif
#ifdef TAB3
# define OXTABS TAB3
#endif
int TtyUpperCase;
#define NOCHAR 0
#if HAVE_TCGETATTR
# define GET(addr) tcgetattr (CHANNEL, addr)
# define SET(addr) tcsetattr (CHANNEL, TCSADRAIN, addr)
#else
# define GET(addr) ioctl (CHANNEL, TCGETA, addr)
# define SET(addr) ioctl (CHANNEL, TCSETAW, addr)
#endif
void TtySet ()
{
#if HAVE_TERMIO_H
if (GET (&oldtio) < 0)
return;
if (oldtio.c_oflag & OLCUC)
TtyUpperCase = 1; /* uppercase on output */
newtio = oldtio;
newtio.c_iflag &= ~(INLCR | ICRNL | IGNCR | ISTRIP | IUCLC);
newtio.c_oflag &= ~(OLCUC | OCRNL | OXTABS);
newtio.c_lflag &= ~(ECHO | ICANON | XCASE);
newtio.c_cc [VMIN] = 1; /* break input after each character */
newtio.c_cc [VTIME] = 1; /* timeout is 100 msecs */
newtio.c_cc [VINTR] = NOCHAR;
newtio.c_cc [VQUIT] = NOCHAR;
#ifdef VSWTCH
newtio.c_cc [VSWTCH] = NOCHAR;
#endif
#ifdef VDSUSP
newtio.c_cc [VDSUSP] = NOCHAR;
#endif
#ifdef VLNEXT
newtio.c_cc [VLNEXT] = NOCHAR;
#endif
#ifdef VDISCARD
newtio.c_cc [VDISCARD] = NOCHAR;
#endif
SET (&newtio);
#else
if (gtty (CHANNEL, &tty) < 0)
return;
if (tty.sg_flags & LCASE)
TtyUpperCase = 1; /* uppercase on output */
ttyflags = tty.sg_flags;
tty.sg_flags &= ~(XTABS | ECHO | CRMOD | LCASE);
# ifdef CBREAK
tty.sg_flags |= CBREAK;
# endif
stty (CHANNEL, &tty);
# ifdef TIOCSETC
ioctl (CHANNEL, TIOCGETC, (char *) &oldtchars);
newtchars = oldtchars;
newtchars.t_intrc = NOCHAR;
newtchars.t_quitc = NOCHAR;
newtchars.t_eofc = NOCHAR;
newtchars.t_brkc = NOCHAR;
ioctl (CHANNEL, TIOCSETC, (char *) &newtchars);
# endif
#endif /* HAVE_TERMIO_H */
#ifdef TIOCSLTC
ioctl (CHANNEL, TIOCGLTC, (char *) &oldchars);
newchars = oldchars;
newchars.t_lnextc = NOCHAR;
newchars.t_rprntc = NOCHAR;
newchars.t_dsuspc = NOCHAR;
newchars.t_flushc = NOCHAR;
ioctl (CHANNEL, TIOCSLTC, (char *) &newchars);
#endif
}
void TtyReset ()
{
#if HAVE_TERMIO_H
SET (&oldtio);
#else
tty.sg_flags = ttyflags;
stty (CHANNEL, &tty);
# ifdef TIOCSETC
ioctl (CHANNEL, TIOCSETC, (char *) &oldtchars);
# endif
#endif
#ifdef TIOCSLTC
ioctl (CHANNEL, TIOCSLTC, (char *) &oldchars);
#endif
}
void TtyFlushInput ()
{
#ifdef TCFLSH
ioctl (CHANNEL, TCFLSH, 0);
#else
# ifdef TIOCFLUSH
int p = 1;
ioctl (CHANNEL, TIOCFLUSH, (char *) &p);
# endif
#endif
}