Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/bin/stty/cchar.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 <limits.h>
34
#include <stdlib.h>
35
#include <string.h>
36
37
#include "stty.h"
38
#include "extern.h"
39
40
static int c_cchar(const void *, const void *);
41
42
/*
43
* Special control characters.
44
*
45
* Cchars1 are the standard names, cchars2 are the old aliases.
46
* The first are displayed, but both are recognized on the
47
* command line.
48
*/
49
struct cchar cchars1[] = {
50
{ "discard", VDISCARD, CDISCARD },
51
{ "dsusp", VDSUSP, CDSUSP },
52
{ "eof", VEOF, CEOF },
53
{ "eol", VEOL, CEOL },
54
{ "eol2", VEOL2, CEOL },
55
{ "erase", VERASE, CERASE },
56
{ "erase2", VERASE2, CERASE2 },
57
{ "intr", VINTR, CINTR },
58
{ "kill", VKILL, CKILL },
59
{ "lnext", VLNEXT, CLNEXT },
60
{ "min", VMIN, CMIN },
61
{ "quit", VQUIT, CQUIT },
62
{ "reprint", VREPRINT, CREPRINT },
63
{ "start", VSTART, CSTART },
64
{ "status", VSTATUS, CSTATUS },
65
{ "stop", VSTOP, CSTOP },
66
{ "susp", VSUSP, CSUSP },
67
{ "time", VTIME, CTIME },
68
{ "werase", VWERASE, CWERASE },
69
{ NULL, 0, 0},
70
};
71
72
struct cchar cchars2[] = {
73
{ "brk", VEOL, CEOL },
74
{ "flush", VDISCARD, CDISCARD },
75
{ "rprnt", VREPRINT, CREPRINT },
76
{ NULL, 0, 0 },
77
};
78
79
static int
80
c_cchar(const void *a, const void *b)
81
{
82
83
return (strcmp(((const struct cchar *)a)->name, ((const struct cchar *)b)->name));
84
}
85
86
int
87
csearch(char ***argvp, struct info *ip)
88
{
89
struct cchar *cp, tmp;
90
long val;
91
char *arg, *ep, *name;
92
93
name = **argvp;
94
95
tmp.name = name;
96
if (!(cp = (struct cchar *)bsearch(&tmp, cchars1,
97
sizeof(cchars1)/sizeof(struct cchar) - 1, sizeof(struct cchar),
98
c_cchar)) && !(cp = (struct cchar *)bsearch(&tmp, cchars2,
99
sizeof(cchars2)/sizeof(struct cchar) - 1, sizeof(struct cchar),
100
c_cchar)))
101
return (0);
102
103
arg = *++*argvp;
104
if (!arg) {
105
warnx("option requires an argument -- %s", name);
106
usage();
107
}
108
109
#define CHK(s) (*arg == s[0] && !strcmp(arg, s))
110
if (CHK("undef") || CHK("<undef>"))
111
ip->t.c_cc[cp->sub] = _POSIX_VDISABLE;
112
else if (cp->sub == VMIN || cp->sub == VTIME) {
113
val = strtol(arg, &ep, 10);
114
if (val > UCHAR_MAX) {
115
warnx("maximum option value is %d -- %s",
116
UCHAR_MAX, name);
117
usage();
118
}
119
if (*ep != '\0') {
120
warnx("option requires a numeric argument -- %s", name);
121
usage();
122
}
123
ip->t.c_cc[cp->sub] = val;
124
} else if (arg[0] == '^')
125
ip->t.c_cc[cp->sub] = (arg[1] == '?') ? 0177 :
126
(arg[1] == '-') ? _POSIX_VDISABLE : arg[1] & 037;
127
else
128
ip->t.c_cc[cp->sub] = arg[0];
129
ip->set = 1;
130
return (1);
131
}
132
133