GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: bin/stty/key.c Lines: 9 106 8.5 %
Date: 2017-11-13 Branches: 2 36 5.6 %

Line Branch Exec Source
1
/*	$OpenBSD: key.c,v 1.17 2016/03/23 14:52:42 mmcc Exp $	*/
2
/*	$NetBSD: key.c,v 1.11 1995/09/07 06:57:11 jtc Exp $	*/
3
4
/*-
5
 * Copyright (c) 1991, 1993, 1994
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 */
32
33
#include <sys/types.h>
34
#include <sys/ioctl.h>
35
36
#include <err.h>
37
#include <errno.h>
38
#include <limits.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <string.h>
42
#include <termios.h>
43
44
#include "stty.h"
45
#include "extern.h"
46
47
__BEGIN_DECLS
48
void	f_all(struct info *);
49
void	f_cbreak(struct info *);
50
void	f_columns(struct info *);
51
void	f_dec(struct info *);
52
void	f_ek(struct info *);
53
void	f_everything(struct info *);
54
void	f_extproc(struct info *);
55
void	f_ispeed(struct info *);
56
void	f_lcase(struct info *);
57
void	f_nl(struct info *);
58
void	f_ospeed(struct info *);
59
void	f_raw(struct info *);
60
void	f_rows(struct info *);
61
void	f_sane(struct info *);
62
void	f_size(struct info *);
63
void	f_speed(struct info *);
64
void	f_ostart(struct info *);
65
void	f_ostop(struct info *);
66
void	f_tty(struct info *);
67
__END_DECLS
68
69
static struct key {
70
	char *name;				/* name */
71
	void (*f)(struct info *);		/* function */
72
#define	F_NEEDARG	0x01			/* needs an argument */
73
#define	F_OFFOK		0x02			/* can turn off */
74
	int flags;
75
} keys[] = {
76
	{ "all",	f_all,		0 },
77
	{ "cbreak",	f_cbreak,	F_OFFOK },
78
	{ "cols",	f_columns,	F_NEEDARG },
79
	{ "columns",	f_columns,	F_NEEDARG },
80
	{ "cooked", 	f_sane,		0 },
81
	{ "dec",	f_dec,		0 },
82
	{ "ek",		f_ek,		0 },
83
	{ "everything",	f_everything,	0 },
84
	{ "extproc",	f_extproc,	F_OFFOK },
85
	{ "ispeed",	f_ispeed,	F_NEEDARG },
86
	{ "lcase", 	f_lcase,	0 },
87
	{ "new",	f_tty,		0 },
88
	{ "nl",		f_nl,		F_OFFOK },
89
	{ "old",	f_tty,		0 },
90
	{ "ospeed",	f_ospeed,	F_NEEDARG },
91
	{ "ostart",	f_ostart,	0 },
92
	{ "ostop",	f_ostop,	0 },
93
	{ "raw",	f_raw,		F_OFFOK },
94
	{ "rows",	f_rows,		F_NEEDARG },
95
	{ "sane",	f_sane,		0 },
96
	{ "size",	f_size,		0 },
97
	{ "speed",	f_speed,	0 },
98
	{ "tty",	f_tty,		0 },
99
};
100
101
static int
102
c_key(const void *a, const void *b)
103
{
104
105
180
	return (strcmp(((struct key *)a)->name, ((struct key *)b)->name));
106
}
107
108
int
109
ksearch(char ***argvp, struct info *ip)
110
{
111
	char *name;
112
36
	struct key *kp, tmp;
113
114
18
	name = **argvp;
115
18
	if (*name == '-') {
116
		ip->off = 1;
117
		++name;
118
	} else
119
18
		ip->off = 0;
120
121
18
	tmp.name = name;
122
18
	if (!(kp = (struct key *)bsearch(&tmp, keys,
123
	    sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key)))
124
18
		return (0);
125
	if (!(kp->flags & F_OFFOK) && ip->off) {
126
		warnx("illegal option -- -%s", name);
127
		usage();
128
	}
129
	if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) {
130
		warnx("option requires an argument -- %s", name);
131
		usage();
132
	}
133
	kp->f(ip);
134
	return (1);
135
18
}
136
137
void
138
f_all(struct info *ip)
139
{
140
	print(&ip->t, &ip->win, ip->ldisc, BSD);
141
}
142
143
void
144
f_cbreak(struct info *ip)
145
{
146
147
	if (ip->off)
148
		f_sane(ip);
149
	else {
150
		ip->t.c_iflag |= BRKINT|IXON|IMAXBEL;
151
		ip->t.c_oflag |= OPOST;
152
		ip->t.c_lflag |= ISIG|IEXTEN;
153
		ip->t.c_lflag &= ~ICANON;
154
		ip->set = 1;
155
	}
156
}
157
158
void
159
f_columns(struct info *ip)
160
{
161
	const char *error;
162
163
	ip->win.ws_col = strtonum(ip->arg, 0, USHRT_MAX, &error);
164
	if (error)
165
		err(1, "cols %s", ip->arg);
166
	ip->wset = 1;
167
}
168
169
void
170
f_dec(struct info *ip)
171
{
172
173
	ip->t.c_cc[VERASE] = (u_char)0177;
174
	ip->t.c_cc[VKILL] = CTRL('u');
175
	ip->t.c_cc[VINTR] = CTRL('c');
176
	ip->t.c_lflag &= ~ECHOPRT;
177
	ip->t.c_lflag |= ECHOE|ECHOKE|ECHOCTL;
178
	ip->t.c_iflag &= ~IXANY;
179
	ip->set = 1;
180
}
181
182
void
183
f_ek(struct info *ip)
184
{
185
186
	ip->t.c_cc[VERASE] = CERASE;
187
	ip->t.c_cc[VKILL] = CKILL;
188
	ip->set = 1;
189
}
190
191
void
192
f_everything(struct info *ip)
193
{
194
195
	print(&ip->t, &ip->win, ip->ldisc, BSD);
196
}
197
198
void
199
f_extproc(struct info *ip)
200
{
201
202
	if (ip->off) {
203
		int tmp = 0;
204
		(void)ioctl(ip->fd, TIOCEXT, &tmp);
205
	} else {
206
		int tmp = 1;
207
		(void)ioctl(ip->fd, TIOCEXT, &tmp);
208
	}
209
	ip->set = 1;
210
}
211
212
void
213
f_ispeed(struct info *ip)
214
{
215
	const char *errstr;
216
	speed_t speed;
217
218
	speed = strtonum(ip->arg, 0, UINT_MAX, &errstr);
219
	if (errstr)
220
		err(1, "ispeed %s", ip->arg);
221
	cfsetispeed(&ip->t, speed);
222
	ip->set = 1;
223
}
224
225
void
226
f_lcase(struct info *ip)
227
{
228
	if (ip->off) {
229
		ip->t.c_iflag &= ~IUCLC;
230
		ip->t.c_oflag &= ~OLCUC;
231
		ip->t.c_lflag &= ~XCASE;
232
	} else {
233
		ip->t.c_iflag |= IUCLC;
234
		ip->t.c_oflag |= OLCUC;
235
		ip->t.c_lflag |= XCASE;
236
	}
237
	ip->set = 1;
238
}
239
240
void
241
f_nl(struct info *ip)
242
{
243
244
	if (ip->off) {
245
		ip->t.c_iflag |= ICRNL;
246
		ip->t.c_oflag |= ONLCR;
247
	} else {
248
		ip->t.c_iflag &= ~ICRNL;
249
		ip->t.c_oflag &= ~ONLCR;
250
	}
251
	ip->set = 1;
252
}
253
254
void
255
f_ospeed(struct info *ip)
256
{
257
	const char *errstr;
258
	speed_t speed;
259
260
	speed = strtonum(ip->arg, 0, UINT_MAX, &errstr);
261
	if (errstr)
262
		err(1, "ospeed %s", ip->arg);
263
	cfsetospeed(&ip->t, speed);
264
	ip->set = 1;
265
}
266
267
void
268
f_raw(struct info *ip)
269
{
270
271
	if (ip->off)
272
		f_sane(ip);
273
	else {
274
		cfmakeraw(&ip->t);
275
		ip->t.c_cflag &= ~(CSIZE|PARENB);
276
		ip->t.c_cflag |= CS8;
277
		ip->set = 1;
278
	}
279
}
280
281
void
282
f_rows(struct info *ip)
283
{
284
	const char *error;
285
286
	ip->win.ws_row = strtonum(ip->arg, 0, USHRT_MAX, &error);
287
	if (error)
288
		err(1, "rows %s", ip->arg);
289
	ip->wset = 1;
290
}
291
292
void
293
f_sane(struct info *ip)
294
{
295
296
	ip->t.c_cflag = TTYDEF_CFLAG | (ip->t.c_cflag & (CLOCAL|CRTSCTS));
297
	ip->t.c_iflag = TTYDEF_IFLAG;
298
	ip->t.c_iflag |= ICRNL;
299
	/* preserve user-preference flags in lflag */
300
#define	LKEEP	(ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH)
301
	ip->t.c_lflag = TTYDEF_LFLAG | (ip->t.c_lflag & LKEEP);
302
	ip->t.c_oflag = TTYDEF_OFLAG;
303
	ip->set = 1;
304
}
305
306
void
307
f_size(struct info *ip)
308
{
309
310
	(void)printf("%d %d\n", ip->win.ws_row, ip->win.ws_col);
311
}
312
313
void
314
f_speed(struct info *ip)
315
{
316
317
	(void)printf("%d\n", cfgetospeed(&ip->t));
318
}
319
320
void
321
f_tty(struct info *ip)
322
{
323
	int tmp;
324
325
	tmp = TTYDISC;
326
	if (ioctl(ip->fd, TIOCSETD, &tmp) < 0)
327
		err(1, "TIOCSETD");
328
}
329
330
void
331
f_ostart(struct info *ip)
332
{
333
	if (ioctl(ip->fd, TIOCSTART) < 0)
334
		err(1, "TIOCSTART");
335
}
336
337
void
338
f_ostop(struct info *ip)
339
{
340
	if (ioctl(ip->fd, TIOCSTOP) < 0)
341
		err(1, "TIOCSTOP");
342
}