Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/bin/stty/key.c
39475 views
1
/*-
2
* Copyright (c) 1991, 1993, 1994
3
* The Regents of the University of California. All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
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.
16
*
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
27
* SUCH DAMAGE.
28
*/
29
30
#include <sys/types.h>
31
32
#include <err.h>
33
#include <stdlib.h>
34
#include <stdio.h>
35
#include <string.h>
36
37
#include "stty.h"
38
#include "extern.h"
39
40
__BEGIN_DECLS
41
static int c_key(const void *, const void *);
42
void f_all(struct info *);
43
void f_cbreak(struct info *);
44
void f_columns(struct info *);
45
void f_dec(struct info *);
46
void f_ek(struct info *);
47
void f_everything(struct info *);
48
void f_extproc(struct info *);
49
void f_ispeed(struct info *);
50
void f_nl(struct info *);
51
void f_ospeed(struct info *);
52
void f_raw(struct info *);
53
void f_rows(struct info *);
54
void f_sane(struct info *);
55
void f_size(struct info *);
56
void f_speed(struct info *);
57
void f_tty(struct info *);
58
__END_DECLS
59
60
static struct key {
61
const char *name; /* name */
62
void (*f)(struct info *); /* function */
63
#define F_NEEDARG 0x01 /* needs an argument */
64
#define F_OFFOK 0x02 /* can turn off */
65
int flags;
66
} keys[] = {
67
{ "all", f_all, 0 },
68
{ "cbreak", f_cbreak, F_OFFOK },
69
{ "cols", f_columns, F_NEEDARG },
70
{ "columns", f_columns, F_NEEDARG },
71
{ "cooked", f_sane, 0 },
72
{ "dec", f_dec, 0 },
73
{ "ek", f_ek, 0 },
74
{ "everything", f_everything, 0 },
75
{ "extproc", f_extproc, F_OFFOK },
76
{ "ispeed", f_ispeed, F_NEEDARG },
77
{ "new", f_tty, 0 },
78
{ "nl", f_nl, F_OFFOK },
79
{ "old", f_tty, 0 },
80
{ "ospeed", f_ospeed, F_NEEDARG },
81
{ "raw", f_raw, F_OFFOK },
82
{ "rows", f_rows, F_NEEDARG },
83
{ "sane", f_sane, 0 },
84
{ "size", f_size, 0 },
85
{ "speed", f_speed, 0 },
86
{ "tty", f_tty, 0 },
87
};
88
89
static int
90
c_key(const void *a, const void *b)
91
{
92
93
return (strcmp(((const struct key *)a)->name, ((const struct key *)b)->name));
94
}
95
96
int
97
ksearch(char ***argvp, struct info *ip)
98
{
99
char *name;
100
struct key *kp, tmp;
101
102
name = **argvp;
103
if (*name == '-') {
104
ip->off = 1;
105
++name;
106
} else
107
ip->off = 0;
108
109
tmp.name = name;
110
if (!(kp = (struct key *)bsearch(&tmp, keys,
111
sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key)))
112
return (0);
113
if (!(kp->flags & F_OFFOK) && ip->off) {
114
warnx("illegal option -- -%s", name);
115
usage();
116
}
117
if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) {
118
warnx("option requires an argument -- %s", name);
119
usage();
120
}
121
kp->f(ip);
122
return (1);
123
}
124
125
void
126
f_all(struct info *ip)
127
{
128
print(&ip->t, &ip->win, ip->ldisc, BSD);
129
}
130
131
void
132
f_cbreak(struct info *ip)
133
{
134
135
if (ip->off)
136
f_sane(ip);
137
else {
138
ip->t.c_iflag |= BRKINT|IXON|IMAXBEL;
139
ip->t.c_oflag |= OPOST;
140
ip->t.c_lflag |= ISIG|IEXTEN;
141
ip->t.c_lflag &= ~ICANON;
142
ip->set = 1;
143
}
144
}
145
146
void
147
f_columns(struct info *ip)
148
{
149
150
ip->win.ws_col = atoi(ip->arg);
151
ip->wset = 1;
152
}
153
154
void
155
f_dec(struct info *ip)
156
{
157
158
ip->t.c_cc[VERASE] = (u_char)0177;
159
ip->t.c_cc[VKILL] = CTRL('u');
160
ip->t.c_cc[VINTR] = CTRL('c');
161
ip->t.c_lflag &= ~ECHOPRT;
162
ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL;
163
ip->t.c_iflag &= ~IXANY;
164
ip->set = 1;
165
}
166
167
void
168
f_ek(struct info *ip)
169
{
170
171
ip->t.c_cc[VERASE] = CERASE;
172
ip->t.c_cc[VKILL] = CKILL;
173
ip->set = 1;
174
}
175
176
void
177
f_everything(struct info *ip)
178
{
179
180
print(&ip->t, &ip->win, ip->ldisc, BSD);
181
}
182
183
void
184
f_extproc(struct info *ip)
185
{
186
187
if (ip->off) {
188
int tmp = 0;
189
(void)ioctl(ip->fd, TIOCEXT, &tmp);
190
} else {
191
int tmp = 1;
192
(void)ioctl(ip->fd, TIOCEXT, &tmp);
193
}
194
}
195
196
void
197
f_ispeed(struct info *ip)
198
{
199
200
cfsetispeed(&ip->t, (speed_t)atoi(ip->arg));
201
ip->set = 1;
202
}
203
204
void
205
f_nl(struct info *ip)
206
{
207
208
if (ip->off) {
209
ip->t.c_iflag |= ICRNL;
210
ip->t.c_oflag |= ONLCR;
211
} else {
212
ip->t.c_iflag &= ~ICRNL;
213
ip->t.c_oflag &= ~ONLCR;
214
}
215
ip->set = 1;
216
}
217
218
void
219
f_ospeed(struct info *ip)
220
{
221
222
cfsetospeed(&ip->t, (speed_t)atoi(ip->arg));
223
ip->set = 1;
224
}
225
226
void
227
f_raw(struct info *ip)
228
{
229
230
if (ip->off)
231
f_sane(ip);
232
else {
233
cfmakeraw(&ip->t);
234
ip->t.c_cflag &= ~(CSIZE|PARENB);
235
ip->t.c_cflag |= CS8;
236
ip->set = 1;
237
}
238
}
239
240
void
241
f_rows(struct info *ip)
242
{
243
244
ip->win.ws_row = atoi(ip->arg);
245
ip->wset = 1;
246
}
247
248
void
249
f_sane(struct info *ip)
250
{
251
struct termios def;
252
253
cfmakesane(&def);
254
ip->t.c_cflag = def.c_cflag | (ip->t.c_cflag & CLOCAL);
255
ip->t.c_iflag = def.c_iflag;
256
/* preserve user-preference flags in lflag */
257
#define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH)
258
ip->t.c_lflag = def.c_lflag | (ip->t.c_lflag & LKEEP);
259
ip->t.c_oflag = def.c_oflag;
260
ip->set = 1;
261
}
262
263
void
264
f_size(struct info *ip)
265
{
266
267
(void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col);
268
}
269
270
void
271
f_speed(struct info *ip)
272
{
273
274
(void)printf("%lu\n", (u_long)cfgetospeed(&ip->t));
275
}
276
277
void
278
f_tty(struct info *ip)
279
{
280
int tmp;
281
282
tmp = TTYDISC;
283
if (ioctl(ip->fd, TIOCSETD, &tmp) < 0)
284
err(1, "TIOCSETD");
285
}
286
287