Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <tty.h>
4
 
5
typedef struct Mode Mode;
6
struct Mode
7
{
8
	char*	name;
9
	int	bit;
10
};
11
 
12
Mode ou[] =
13
{
14
	"opost",	OPOST,
15
	"olcuc",	OLCUC,
16
	"onlcr",	ONLCR,
17
	"ocrnl",	OCRNL,
18
	"onocr",	ONOCR,
19
	"onlret",	ONLRET,
20
	"ofill",	OFILL,
21
	"ofdel",	OFDEL,
22
 
23
};
24
 
25
Mode in[] =
26
{
27
	"brkint",	BRKINT,
28
	"icrnl",	ICRNL,
29
	"ignbrk",	IGNBRK,
30
	"igncr",	IGNCR,
31
	"ignpar",	IGNPAR,
32
	"inlcr",	INLCR,
33
	"inpck",	INPCK,
34
	"istrip",	ISTRIP,
35
	"ixoff",	IXOFF,
36
	"ixon",		IXON,
37
	"parmrk",	PARMRK,
38
 
39
};
40
 
41
Mode lo[] =
42
{
43
	"echo",		ECHO,
44
	"echoe",	ECHOE,
45
	"echok", 	ECHOK,
46
	"echonl",	ECHONL,
47
	"icanon",	ICANON,
48
	"iexten",	IEXTEN,
49
	"isig",		ISIG,
50
	"noflsh",	NOFLSH,
51
	"tostop",	TOSTOP,
52
 
53
};
54
 
55
Mode cc[] =
56
{
57
	"eof",		VEOF,
58
	"eol",		VEOL,
59
	"erase",	VERASE,
60
	"intr",		VINTR,
61
	"kill",		VKILL,
62
	"min",		VMIN,
63
	"quit",		VQUIT,
64
	"susp",		VSUSP,
65
	"time",		VTIME,
66
	"start",	VSTART,
67
	"stop",		VSTOP,
68
	0,
69
};
70
 
71
int	getmode(int, Termios*);
72
int	setmode(int, Termios*);
73
 
74
char*
75
ctlchar(char c)
76
{
77
	static char buf[10];
78
 
79
	if(c == 0x7f)
80
		return "DEL";
81
	if(c == 0)
82
		return "NUL";
83
	if(c < 32) {
84
		buf[0] = '^';
85
		buf[1] = '@'+c;
86
		buf[2] = '\0';
87
		return buf;
88
	}	
89
	buf[0] = c;
90
	buf[1] = '\0';
91
	return buf;
92
}
93
 
94
void
95
showmode(Termios *t)
96
{
97
	int i;
98
 
99
	for(i = 0; cc[i].name; i++) {
100
		switch(cc[i].bit) {
101
		case VMIN:
102
		case VTIME:
103
			if(t->cc[i] != 0)
104
				print("%s %d ", cc[i].name, t->cc[i]);
105
			break;
106
		default:
107
			print("%s %s ", cc[i].name, ctlchar(t->cc[i]));
108
			break;
109
		}
110
	}
111
	print("\n");
112
 
113
	for(i = 0; ou[i].name; i++)
114
		if(ou[i].bit & t->oflag)
115
			print("%s ", ou[i].name);
116
 
117
	for(i = 0; in[i].name; i++)
118
		if(in[i].bit & t->iflag)
119
			print("%s ", in[i].name);
120
 
121
	print("\n");
122
	for(i = 0; lo[i].name; i++)
123
		if(lo[i].bit & t->lflag)
124
			print("%s ", lo[i].name);
125
	print("\n");
126
}
127
 
128
int
129
setreset(char *mode, int *bits, Mode *t)
130
{
131
	int i, clr;
132
 
133
	clr = 0;
134
	if(mode[0] == '-') {
135
		mode++;
136
		clr = 1;
137
	}
138
	for(i = 0; t[i].name; i++) {
139
		if(strcmp(mode, t[i].name) == 0) {
140
			if(clr)
141
				*bits &= ~t[i].bit;
142
			else
143
				*bits |= t[i].bit;
144
 
145
			return 1;
146
		}
147
	}
148
	return 0;
149
}
150
 
151
int
152
ccname(char *name)
153
{
154
	int i;
155
 
156
	for(i = 0; cc[i].name; i++)
157
		if(strcmp(cc[i].name, name) == 0)
158
			return i;
159
 
160
	return -1;
161
}
162
 
163
void
164
main(int argc, char **argv)
165
{
166
	Termios t;
167
	int i, stdin, wmo, cc;
168
 
169
	/* Try and get a seek pointer */
170
	stdin = open("/fd/0", ORDWR);
171
	if(stdin < 0)
172
		stdin = 0;
173
 
174
	if(getmode(stdin, &t) < 0) {
175
		fprint(2, "stty: tiocget %r\n");
176
		exits("1");
177
	}
178
 
179
	if(argc < 2) {
180
		fprint(2, "usage: stty [-a|-g] modes...\n");
181
		exits("1");
182
	}
183
	wmo = 0;
184
	for(i = 1; i < argc; i++) {
185
		if(strcmp(argv[i], "-a") == 0) {
186
			showmode(&t);
187
			continue;
188
		}
189
		if(setreset(argv[i], &t.iflag, in)) {
190
			wmo++;
191
			continue;
192
		}
193
		if(setreset(argv[i], &t.lflag, lo)) {
194
			wmo++;
195
			continue;
196
		}
197
		if(setreset(argv[i], &t.oflag, ou)) {
198
			wmo++;
199
			continue;
200
		}
201
		cc = ccname(argv[i]);
202
		if(cc != -1 && i+1 < argc) {
203
			wmo++;
204
			t.cc[cc] = argv[++i][0];
205
			continue;
206
		}
207
		fprint(2, "stty: bad option/mode %s\n", argv[i]);
208
		exits("1");
209
	}
210
 
211
	if(wmo) {
212
		if(setmode(stdin, &t) < 0) {
213
			fprint(2, "stty: cant set mode %r\n");
214
			exits("1");
215
		}
216
	}
217
 
218
	exits(0);
219
}
220
 
221
int
222
setmode(int fd, Termios *t)
223
{
224
	int n, i;
225
	char buf[256];
226
 
227
	n = sprint(buf, "IOW %4.4ux %4.4ux %4.4ux %4.4ux ",
228
		t->iflag, t->oflag, t->cflag, t->lflag);
229
	for(i = 0; i < NCCS; i++)
230
		n += sprint(buf+n, "%2.2ux ", t->cc[i]);
231
 
232
	if(seek(fd, -2, 0) != -2)
233
		return -1;
234
 
235
	n = write(fd, buf, n);
236
	if(n < 0)
237
		return -1;
238
	return 0;
239
}
240
 
241
/*
242
 * Format is: IOR iiii oooo cccc llll xx xx xx xx ...
243
 */
244
int
245
getmode(int fd, Termios *t)
246
{
247
	int n;
248
	char buf[256];
249
 
250
	if(seek(fd, -2, 0) != -2)
251
		return -1;
252
 
253
	n = read(fd, buf, 57);
254
	if(n < 0)
255
		return -1;
256
 
257
	t->iflag = strtoul(buf+4, 0, 16);
258
	t->oflag = strtoul(buf+9, 0, 16);
259
	t->cflag = strtoul(buf+14, 0, 16);
260
	t->lflag = strtoul(buf+19, 0, 16);
261
 
262
	for(n = 0; n < NCCS; n++)
263
		t->cc[n] = strtoul(buf+24+(n*3), 0, 16);
264
 
265
	return 0;
266
}