Deleted Added
full compact
svr4_termios.c (102003) svr4_termios.c (116174)
1/*
2 * Copyright (c) 1998 Mark Newton
3 * Copyright (c) 1994 Christos Zoulas
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1/*
2 * Copyright (c) 1998 Mark Newton
3 * Copyright (c) 1994 Christos Zoulas
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/compat/svr4/svr4_termios.c 102003 2002-08-17 02:36:16Z rwatson $
29 */
30
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_termios.c 116174 2003-06-10 21:44:29Z obrien $");
31
31#include <sys/param.h>
32#include <sys/proc.h>
33#include <sys/systm.h>
34#include <sys/file.h>
35#include <sys/filedesc.h>
36#include <sys/termios.h>
37
38#include <sys/sysproto.h>
39
40#include <compat/svr4/svr4.h>
41#include <compat/svr4/svr4_util.h>
42#include <compat/svr4/svr4_ioctl.h>
43#include <compat/svr4/svr4_termios.h>
44
45#ifndef __CONCAT3
46# if __STDC__
47# define __CONCAT3(a,b,c) a ## b ## c
48# else
49# define __CONCAT3(a,b,c) a/**/b/**/c
50# endif
51#endif
52
53static u_long bsd_to_svr4_speed(u_long, u_long);
54static u_long svr4_to_bsd_speed(u_long, u_long);
55static void svr4_to_bsd_termios(const struct svr4_termios *,
56 struct termios *, int);
57static void bsd_to_svr4_termios(const struct termios *,
58 struct svr4_termios *);
59static void svr4_termio_to_termios(const struct svr4_termio *,
60 struct svr4_termios *);
61static void svr4_termios_to_termio(const struct svr4_termios *,
62 struct svr4_termio *);
63#ifdef DEBUG_SVR4
64static void print_svr4_termios(const struct svr4_termios *);
65static void print_bsd_termios(const struct termios *);
66#endif /* DEBUG_SVR4 */
67
68#define undefined_char(a,b) /**/
69#define undefined_flag1(f,a,b) /**/
70#define undefined_flag2(f,a,b,c1,t1,c2,t2) /**/
71#define undefined_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) /**/
72
73#define svr4_to_bsd_char(a,b) \
74 if (new || __CONCAT3(SVR4_,a,b) < SVR4_NCC) { \
75 if (st->c_cc[__CONCAT3(SVR4_,a,b)] == SVR4_POSIX_VDISABLE) \
76 bt->c_cc[__CONCAT(a,b)] = _POSIX_VDISABLE; \
77 else \
78 bt->c_cc[__CONCAT(a,b)] = st->c_cc[__CONCAT3(SVR4_,a,b)]; \
79 }
80
81#define svr4_to_bsd_flag1(f,a,b) \
82 if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \
83 if (st->f & __CONCAT3(SVR4_,a,b)) \
84 bt->f |= __CONCAT(a,b); \
85 else \
86 bt->f &= ~__CONCAT(a,b); \
87 }
88
89#define svr4_to_bsd_flag2(f,a,b,c1,t1,c2,t2) \
90 if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \
91 bt->f &= ~__CONCAT(a,b); \
92 switch (st->f & __CONCAT3(SVR4_,a,b)) { \
93 case __CONCAT3(SVR4_,c1,t1): bt->f |= __CONCAT(c1,t1); break; \
94 case __CONCAT3(SVR4_,c2,t2): bt->f |= __CONCAT(c2,t2); break; \
95 } \
96 }
97
98#define svr4_to_bsd_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) \
99 if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \
100 bt->f &= ~__CONCAT(a,b); \
101 switch (st->f & __CONCAT3(SVR4_,a,b)) { \
102 case __CONCAT3(SVR4_,c1,t1): bt->f |= __CONCAT(c1,t1); break; \
103 case __CONCAT3(SVR4_,c2,t2): bt->f |= __CONCAT(c2,t2); break; \
104 case __CONCAT3(SVR4_,c3,t3): bt->f |= __CONCAT(c3,t3); break; \
105 case __CONCAT3(SVR4_,c4,t4): bt->f |= __CONCAT(c4,t4); break; \
106 } \
107 }
108
109
110#define bsd_to_svr4_char(a,b) \
111 if (bt->c_cc[__CONCAT(a,b)] == _POSIX_VDISABLE) \
112 st->c_cc[__CONCAT3(SVR4_,a,b)] = SVR4_POSIX_VDISABLE; \
113 else \
114 st->c_cc[__CONCAT3(SVR4_,a,b)] = bt->c_cc[__CONCAT(a,b)]
115
116#define bsd_to_svr4_flag1(f,a,b) \
117 if (bt->f & __CONCAT(a,b)) \
118 st->f |= __CONCAT3(SVR4_,a,b); \
119 else \
120 st->f &= ~__CONCAT3(SVR4_,a,b)
121
122#define bsd_to_svr4_flag2(f,a,b,c1,t1,c2,t2) \
123 st->f &= ~__CONCAT(a,b); \
124 switch (bt->f & __CONCAT(a,b)) { \
125 case __CONCAT(c1,t1): st->f |= __CONCAT3(SVR4_,c1,t1); break; \
126 case __CONCAT(c2,t2): st->f |= __CONCAT3(SVR4_,c2,t2); break; \
127 }
128
129#define bsd_to_svr4_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) \
130 st->f &= ~__CONCAT(a,b); \
131 switch (bt->f & __CONCAT(a,b)) { \
132 case __CONCAT(c1,t1): st->f |= __CONCAT3(SVR4_,c1,t1); break; \
133 case __CONCAT(c2,t2): st->f |= __CONCAT3(SVR4_,c2,t2); break; \
134 case __CONCAT(c3,t3): st->f |= __CONCAT3(SVR4_,c3,t3); break; \
135 case __CONCAT(c4,t4): st->f |= __CONCAT3(SVR4_,c4,t4); break; \
136 }
137
138#ifdef DEBUG_SVR4
139static void
140print_svr4_termios(st)
141 const struct svr4_termios *st;
142{
143 int i;
144 DPRINTF(("SVR4\niflag=%lo oflag=%lo cflag=%lo lflag=%lo\n",
145 st->c_iflag, st->c_oflag, st->c_cflag, st->c_lflag));
146 DPRINTF(("cc: "));
147 for (i = 0; i < SVR4_NCCS; i++)
148 DPRINTF(("%o ", st->c_cc[i]));
149 DPRINTF(("\n"));
150}
151
152
153static void
154print_bsd_termios(bt)
155 const struct termios *bt;
156{
157 int i;
158 uprintf("BSD\niflag=%o oflag=%o cflag=%o lflag=%o\n",
159 bt->c_iflag, bt->c_oflag, bt->c_cflag, bt->c_lflag);
160 uprintf("cc: ");
161 for (i = 0; i < NCCS; i++)
162 uprintf("%o ", bt->c_cc[i]);
163 uprintf("\n");
164}
165#endif /* DEBUG_SVR4 */
166
167static u_long
168bsd_to_svr4_speed(sp, mask)
169 u_long sp;
170 u_long mask;
171{
172 switch (sp) {
173#undef getval
174#define getval(a,b) case __CONCAT(a,b): sp = __CONCAT3(SVR4_,a,b)
175 getval(B,0);
176 getval(B,50);
177 getval(B,75);
178 getval(B,110);
179 getval(B,134);
180 getval(B,150);
181 getval(B,200);
182 getval(B,300);
183 getval(B,600);
184 getval(B,1200);
185 getval(B,1800);
186 getval(B,2400);
187 getval(B,4800);
188 getval(B,9600);
189 getval(B,19200);
190 getval(B,38400);
191 getval(B,57600);
192 getval(B,115200);
193 default: sp = SVR4_B9600; /* XXX */
194 }
195
196 while ((mask & 1) == 0) {
197 mask >>= 1;
198 sp <<= 1;
199 }
200
201 return sp;
202}
203
204
205static u_long
206svr4_to_bsd_speed(sp, mask)
207 u_long sp;
208 u_long mask;
209{
210 while ((mask & 1) == 0) {
211 mask >>= 1;
212 sp >>= 1;
213 }
214
215 switch (sp & mask) {
216#undef getval
217#define getval(a,b) case __CONCAT3(SVR4_,a,b): return __CONCAT(a,b)
218 getval(B,0);
219 getval(B,50);
220 getval(B,75);
221 getval(B,110);
222 getval(B,134);
223 getval(B,150);
224 getval(B,200);
225 getval(B,300);
226 getval(B,600);
227 getval(B,1200);
228 getval(B,1800);
229 getval(B,2400);
230 getval(B,4800);
231 getval(B,9600);
232 getval(B,19200);
233 getval(B,38400);
234 getval(B,57600);
235 getval(B,115200);
236 default: return B9600; /* XXX */
237 }
238}
239
240
241static void
242svr4_to_bsd_termios(st, bt, new)
243 const struct svr4_termios *st;
244 struct termios *bt;
245 int new;
246{
247 /* control characters */
248 /*
249 * We process VMIN and VTIME first,
250 * because they are shared with VEOF and VEOL
251 */
252 svr4_to_bsd_char(V,MIN);
253 svr4_to_bsd_char(V,TIME);
254
255 svr4_to_bsd_char(V,INTR);
256 svr4_to_bsd_char(V,QUIT);
257 svr4_to_bsd_char(V,ERASE);
258 svr4_to_bsd_char(V,KILL);
259 svr4_to_bsd_char(V,EOF);
260 svr4_to_bsd_char(V,EOL);
261 svr4_to_bsd_char(V,EOL2);
262 undefined_char(V,SWTCH);
263 svr4_to_bsd_char(V,START);
264 svr4_to_bsd_char(V,STOP);
265 svr4_to_bsd_char(V,SUSP);
266 svr4_to_bsd_char(V,DSUSP);
267 svr4_to_bsd_char(V,REPRINT);
268 svr4_to_bsd_char(V,DISCARD);
269 svr4_to_bsd_char(V,WERASE);
270 svr4_to_bsd_char(V,LNEXT);
271
272 /* Input modes */
273 svr4_to_bsd_flag1(c_iflag,I,GNBRK);
274 svr4_to_bsd_flag1(c_iflag,B,RKINT);
275 svr4_to_bsd_flag1(c_iflag,I,GNPAR);
276 svr4_to_bsd_flag1(c_iflag,P,ARMRK);
277 svr4_to_bsd_flag1(c_iflag,I,NPCK);
278 svr4_to_bsd_flag1(c_iflag,I,STRIP);
279 svr4_to_bsd_flag1(c_iflag,I,NLCR);
280 svr4_to_bsd_flag1(c_iflag,I,GNCR);
281 svr4_to_bsd_flag1(c_iflag,I,CRNL);
282 undefined_flag1(c_iflag,I,UCLC);
283 svr4_to_bsd_flag1(c_iflag,I,XON);
284 svr4_to_bsd_flag1(c_iflag,I,XANY);
285 svr4_to_bsd_flag1(c_iflag,I,XOFF);
286 svr4_to_bsd_flag1(c_iflag,I,MAXBEL);
287 undefined_flag1(c_iflag,D,OSMODE);
288
289 /* Output modes */
290 svr4_to_bsd_flag1(c_oflag,O,POST);
291 undefined_flag1(c_oflag,O,LCUC);
292 svr4_to_bsd_flag1(c_oflag,O,NLCR);
293 undefined_flag1(c_oflag,O,CRNL);
294 undefined_flag1(c_oflag,O,NOCR);
295 undefined_flag1(c_oflag,O,NLRET);
296 undefined_flag1(c_oflag,O,FILL);
297 undefined_flag1(c_oflag,O,FDEL);
298 undefined_flag2(c_oflag,N,LDLY,N,L0,N,L1);
299 undefined_flag4(c_oflag,C,RDLY,C,R0,C,R1,C,R2,C,R3);
300 undefined_flag4(c_oflag,T,ABDLY,T,AB0,T,AB1,T,AB2,T,AB3);
301 undefined_flag2(c_oflag,B,SDLY,B,S0,B,S1);
302 undefined_flag2(c_oflag,V,TDLY,V,T0,V,T1);
303 undefined_flag2(c_oflag,F,FDLY,F,F0,F,F1);
304 undefined_flag1(c_oflag,P,AGEOUT);
305 undefined_flag1(c_oflag,W,RAP);
306
307 /* Control modes */
308 bt->c_ospeed = svr4_to_bsd_speed(st->c_cflag, SVR4_CBAUD);
309 svr4_to_bsd_flag4(c_cflag,C,SIZE,C,S5,C,S6,C,S7,C,S8)
310 svr4_to_bsd_flag1(c_cflag,C,STOPB);
311 svr4_to_bsd_flag1(c_cflag,C,READ);
312 svr4_to_bsd_flag1(c_cflag,P,ARENB);
313 svr4_to_bsd_flag1(c_cflag,P,ARODD);
314 svr4_to_bsd_flag1(c_cflag,H,UPCL);
315 svr4_to_bsd_flag1(c_cflag,C,LOCAL);
316 undefined_flag1(c_cflag,R,CV1EN);
317 undefined_flag1(c_cflag,X,MT1EN);
318 undefined_flag1(c_cflag,L,OBLK);
319 undefined_flag1(c_cflag,X,CLUDE);
320 bt->c_ispeed = svr4_to_bsd_speed(st->c_cflag, SVR4_CIBAUD);
321 undefined_flag1(c_cflag,P,AREXT);
322
323 /* line discipline modes */
324 svr4_to_bsd_flag1(c_lflag,I,SIG);
325 svr4_to_bsd_flag1(c_lflag,I,CANON);
326 undefined_flag1(c_lflag,X,CASE);
327 svr4_to_bsd_flag1(c_lflag,E,CHO);
328 svr4_to_bsd_flag1(c_lflag,E,CHOE);
329 svr4_to_bsd_flag1(c_lflag,E,CHOK);
330 svr4_to_bsd_flag1(c_lflag,E,CHONL);
331 svr4_to_bsd_flag1(c_lflag,N,OFLSH);
332 svr4_to_bsd_flag1(c_lflag,T,OSTOP);
333 svr4_to_bsd_flag1(c_lflag,E,CHOCTL);
334 svr4_to_bsd_flag1(c_lflag,E,CHOPRT);
335 svr4_to_bsd_flag1(c_lflag,E,CHOKE);
336 undefined_flag1(c_lflag,D,EFECHO);
337 svr4_to_bsd_flag1(c_lflag,F,LUSHO);
338 svr4_to_bsd_flag1(c_lflag,P,ENDIN);
339 svr4_to_bsd_flag1(c_lflag,I,EXTEN);
340}
341
342
343static void
344bsd_to_svr4_termios(bt, st)
345 const struct termios *bt;
346 struct svr4_termios *st;
347{
348 /* control characters */
349 /*
350 * We process VMIN and VTIME first,
351 * because they are shared with VEOF and VEOL
352 */
353 bsd_to_svr4_char(V,MIN);
354 bsd_to_svr4_char(V,TIME);
355 bsd_to_svr4_char(V,INTR);
356 bsd_to_svr4_char(V,QUIT);
357 bsd_to_svr4_char(V,ERASE);
358 bsd_to_svr4_char(V,KILL);
359 bsd_to_svr4_char(V,EOF);
360 bsd_to_svr4_char(V,EOL);
361 bsd_to_svr4_char(V,EOL2);
362 undefined_char(V,SWTCH);
363 bsd_to_svr4_char(V,START);
364 bsd_to_svr4_char(V,STOP);
365 bsd_to_svr4_char(V,SUSP);
366 bsd_to_svr4_char(V,DSUSP);
367 bsd_to_svr4_char(V,REPRINT);
368 bsd_to_svr4_char(V,DISCARD);
369 bsd_to_svr4_char(V,WERASE);
370 bsd_to_svr4_char(V,LNEXT);
371
372 /* Input modes */
373 bsd_to_svr4_flag1(c_iflag,I,GNBRK);
374 bsd_to_svr4_flag1(c_iflag,B,RKINT);
375 bsd_to_svr4_flag1(c_iflag,I,GNPAR);
376 bsd_to_svr4_flag1(c_iflag,P,ARMRK);
377 bsd_to_svr4_flag1(c_iflag,I,NPCK);
378 bsd_to_svr4_flag1(c_iflag,I,STRIP);
379 bsd_to_svr4_flag1(c_iflag,I,NLCR);
380 bsd_to_svr4_flag1(c_iflag,I,GNCR);
381 bsd_to_svr4_flag1(c_iflag,I,CRNL);
382 undefined_flag1(c_iflag,I,UCLC);
383 bsd_to_svr4_flag1(c_iflag,I,XON);
384 bsd_to_svr4_flag1(c_iflag,I,XANY);
385 bsd_to_svr4_flag1(c_iflag,I,XOFF);
386 bsd_to_svr4_flag1(c_iflag,I,MAXBEL);
387 undefined_flag1(c_iflag,D,OSMODE);
388
389 /* Output modes */
390 bsd_to_svr4_flag1(c_oflag,O,POST);
391 undefined_flag1(c_oflag,O,LCUC);
392 bsd_to_svr4_flag1(c_oflag,O,NLCR);
393 undefined_flag1(c_oflag,O,CRNL);
394 undefined_flag1(c_oflag,O,NOCR);
395 undefined_flag1(c_oflag,O,NLRET);
396 undefined_flag1(c_oflag,O,FILL);
397 undefined_flag1(c_oflag,O,FDEL);
398 undefined_flag2(c_oflag,N,LDLY,N,L0,N,L1);
399 undefined_flag4(c_oflag,C,RDLY,C,R0,C,R1,C,R2,C,R3);
400 undefined_flag4(c_oflag,T,ABDLY,T,AB0,T,AB1,T,AB2,T,AB3);
401 undefined_flag2(c_oflag,B,SDLY,B,S0,B,S1);
402 undefined_flag2(c_oflag,V,TDLY,V,T0,V,T1);
403 undefined_flag2(c_oflag,F,FDLY,F,F0,F,F1);
404 undefined_flag1(c_oflag,P,AGEOUT);
405 undefined_flag1(c_oflag,W,RAP);
406
407 /* Control modes */
408 st->c_cflag &= ~SVR4_CBAUD;
409 st->c_cflag |= bsd_to_svr4_speed(bt->c_ospeed, SVR4_CBAUD);
410 bsd_to_svr4_flag4(c_cflag,C,SIZE,C,S5,C,S6,C,S7,C,S8)
411 bsd_to_svr4_flag1(c_cflag,C,STOPB);
412 bsd_to_svr4_flag1(c_cflag,C,READ);
413 bsd_to_svr4_flag1(c_cflag,P,ARENB);
414 bsd_to_svr4_flag1(c_cflag,P,ARODD);
415 bsd_to_svr4_flag1(c_cflag,H,UPCL);
416 bsd_to_svr4_flag1(c_cflag,C,LOCAL);
417 undefined_flag1(c_cflag,R,CV1EN);
418 undefined_flag1(c_cflag,X,MT1EN);
419 undefined_flag1(c_cflag,L,OBLK);
420 undefined_flag1(c_cflag,X,CLUDE);
421 st->c_cflag &= ~SVR4_CIBAUD;
422 st->c_cflag |= bsd_to_svr4_speed(bt->c_ispeed, SVR4_CIBAUD);
423
424 undefined_flag1(c_oflag,P,AREXT);
425
426 /* line discipline modes */
427 bsd_to_svr4_flag1(c_lflag,I,SIG);
428 bsd_to_svr4_flag1(c_lflag,I,CANON);
429 undefined_flag1(c_lflag,X,CASE);
430 bsd_to_svr4_flag1(c_lflag,E,CHO);
431 bsd_to_svr4_flag1(c_lflag,E,CHOE);
432 bsd_to_svr4_flag1(c_lflag,E,CHOK);
433 bsd_to_svr4_flag1(c_lflag,E,CHONL);
434 bsd_to_svr4_flag1(c_lflag,N,OFLSH);
435 bsd_to_svr4_flag1(c_lflag,T,OSTOP);
436 bsd_to_svr4_flag1(c_lflag,E,CHOCTL);
437 bsd_to_svr4_flag1(c_lflag,E,CHOPRT);
438 bsd_to_svr4_flag1(c_lflag,E,CHOKE);
439 undefined_flag1(c_lflag,D,EFECHO);
440 bsd_to_svr4_flag1(c_lflag,F,LUSHO);
441 bsd_to_svr4_flag1(c_lflag,P,ENDIN);
442 bsd_to_svr4_flag1(c_lflag,I,EXTEN);
443}
444
445
446static void
447svr4_termio_to_termios(t, ts)
448 const struct svr4_termio *t;
449 struct svr4_termios *ts;
450{
451 int i;
452
453 ts->c_iflag = (svr4_tcflag_t) t->c_iflag;
454 ts->c_oflag = (svr4_tcflag_t) t->c_oflag;
455 ts->c_cflag = (svr4_tcflag_t) t->c_cflag;
456 ts->c_lflag = (svr4_tcflag_t) t->c_lflag;
457
458 for (i = 0; i < SVR4_NCC; i++)
459 ts->c_cc[i] = (svr4_cc_t) t->c_cc[i];
460}
461
462
463static void
464svr4_termios_to_termio(ts, t)
465 const struct svr4_termios *ts;
466 struct svr4_termio *t;
467{
468 int i;
469
470 t->c_iflag = (u_short) ts->c_iflag;
471 t->c_oflag = (u_short) ts->c_oflag;
472 t->c_cflag = (u_short) ts->c_cflag;
473 t->c_lflag = (u_short) ts->c_lflag;
474 t->c_line = 0; /* XXX */
475
476 for (i = 0; i < SVR4_NCC; i++)
477 t->c_cc[i] = (u_char) ts->c_cc[i];
478}
479
480int
481svr4_term_ioctl(fp, td, retval, fd, cmd, data)
482 struct file *fp;
483 struct thread *td;
484 register_t *retval;
485 int fd;
486 u_long cmd;
487 caddr_t data;
488{
489 struct termios bt;
490 struct svr4_termios st;
491 struct svr4_termio t;
492 int error, new;
493
494 *retval = 0;
495
496 DPRINTF(("TERM ioctl %lx\n", cmd));
497
498 switch (cmd) {
499 case SVR4_TCGETA:
500 case SVR4_TCGETS:
501 DPRINTF(("ioctl(TCGET%c);\n", cmd == SVR4_TCGETA ? 'A' : 'S'));
502 if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t) &bt,
503 td->td_ucred, td)) != 0)
504 return error;
505
506 memset(&st, 0, sizeof(st));
507 bsd_to_svr4_termios(&bt, &st);
508
509#ifdef DEBUG_SVR4
510 print_bsd_termios(&bt);
511 print_svr4_termios(&st);
512#endif /* DEBUG_SVR4 */
513
514 if (cmd == SVR4_TCGETA) {
515 svr4_termios_to_termio(&st, &t);
516 return copyout(&t, data, sizeof(t));
517 }
518 else {
519 return copyout(&st, data, sizeof(st));
520 }
521
522 case SVR4_TCSETA:
523 case SVR4_TCSETS:
524 case SVR4_TCSETAW:
525 case SVR4_TCSETSW:
526 case SVR4_TCSETAF:
527 case SVR4_TCSETSF:
528 DPRINTF(("TCSET{A,S,AW,SW,AF,SF}\n"));
529 /* get full BSD termios so we don't lose information */
530 if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t) &bt,
531 td->td_ucred, td)) != 0)
532 return error;
533
534 switch (cmd) {
535 case SVR4_TCSETS:
536 case SVR4_TCSETSW:
537 case SVR4_TCSETSF:
538 if ((error = copyin(data, &st, sizeof(st))) != 0)
539 return error;
540 new = 1;
541 break;
542
543 case SVR4_TCSETA:
544 case SVR4_TCSETAW:
545 case SVR4_TCSETAF:
546 if ((error = copyin(data, &t, sizeof(t))) != 0)
547 return error;
548
549 svr4_termio_to_termios(&t, &st);
550 new = 0;
551 break;
552
553 default:
554 return EINVAL;
555 }
556
557 svr4_to_bsd_termios(&st, &bt, new);
558
559 switch (cmd) {
560 case SVR4_TCSETA:
561 case SVR4_TCSETS:
562 DPRINTF(("ioctl(TCSET[A|S]);\n"));
563 cmd = TIOCSETA;
564 break;
565 case SVR4_TCSETAW:
566 case SVR4_TCSETSW:
567 DPRINTF(("ioctl(TCSET[A|S]W);\n"));
568 cmd = TIOCSETAW;
569 break;
570 case SVR4_TCSETAF:
571 case SVR4_TCSETSF:
572 DPRINTF(("ioctl(TCSET[A|S]F);\n"));
573 cmd = TIOCSETAF;
574 break;
575 }
576
577#ifdef DEBUG_SVR4
578 print_bsd_termios(&bt);
579 print_svr4_termios(&st);
580#endif /* DEBUG_SVR4 */
581
582 return fo_ioctl(fp, cmd, (caddr_t) &bt, td->td_ucred, td);
583
584 case SVR4_TIOCGWINSZ:
585 DPRINTF(("TIOCGWINSZ\n"));
586 {
587 struct svr4_winsize ws;
588
589 error = fo_ioctl(fp, TIOCGWINSZ, (caddr_t) &ws,
590 td->td_ucred, td);
591 if (error)
592 return error;
593 return copyout(&ws, data, sizeof(ws));
594 }
595
596 case SVR4_TIOCSWINSZ:
597 DPRINTF(("TIOCSWINSZ\n"));
598 {
599 struct svr4_winsize ws;
600
601 if ((error = copyin(data, &ws, sizeof(ws))) != 0)
602 return error;
603 return fo_ioctl(fp, TIOCSWINSZ, (caddr_t) &ws,
604 td->td_ucred, td);
605 }
606
607 default:
608 DPRINTF(("teleport to STREAMS ioctls...\n"));
609 return svr4_stream_ti_ioctl(fp, td, retval, fd, cmd, data);
610 }
611}
32#include <sys/param.h>
33#include <sys/proc.h>
34#include <sys/systm.h>
35#include <sys/file.h>
36#include <sys/filedesc.h>
37#include <sys/termios.h>
38
39#include <sys/sysproto.h>
40
41#include <compat/svr4/svr4.h>
42#include <compat/svr4/svr4_util.h>
43#include <compat/svr4/svr4_ioctl.h>
44#include <compat/svr4/svr4_termios.h>
45
46#ifndef __CONCAT3
47# if __STDC__
48# define __CONCAT3(a,b,c) a ## b ## c
49# else
50# define __CONCAT3(a,b,c) a/**/b/**/c
51# endif
52#endif
53
54static u_long bsd_to_svr4_speed(u_long, u_long);
55static u_long svr4_to_bsd_speed(u_long, u_long);
56static void svr4_to_bsd_termios(const struct svr4_termios *,
57 struct termios *, int);
58static void bsd_to_svr4_termios(const struct termios *,
59 struct svr4_termios *);
60static void svr4_termio_to_termios(const struct svr4_termio *,
61 struct svr4_termios *);
62static void svr4_termios_to_termio(const struct svr4_termios *,
63 struct svr4_termio *);
64#ifdef DEBUG_SVR4
65static void print_svr4_termios(const struct svr4_termios *);
66static void print_bsd_termios(const struct termios *);
67#endif /* DEBUG_SVR4 */
68
69#define undefined_char(a,b) /**/
70#define undefined_flag1(f,a,b) /**/
71#define undefined_flag2(f,a,b,c1,t1,c2,t2) /**/
72#define undefined_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) /**/
73
74#define svr4_to_bsd_char(a,b) \
75 if (new || __CONCAT3(SVR4_,a,b) < SVR4_NCC) { \
76 if (st->c_cc[__CONCAT3(SVR4_,a,b)] == SVR4_POSIX_VDISABLE) \
77 bt->c_cc[__CONCAT(a,b)] = _POSIX_VDISABLE; \
78 else \
79 bt->c_cc[__CONCAT(a,b)] = st->c_cc[__CONCAT3(SVR4_,a,b)]; \
80 }
81
82#define svr4_to_bsd_flag1(f,a,b) \
83 if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \
84 if (st->f & __CONCAT3(SVR4_,a,b)) \
85 bt->f |= __CONCAT(a,b); \
86 else \
87 bt->f &= ~__CONCAT(a,b); \
88 }
89
90#define svr4_to_bsd_flag2(f,a,b,c1,t1,c2,t2) \
91 if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \
92 bt->f &= ~__CONCAT(a,b); \
93 switch (st->f & __CONCAT3(SVR4_,a,b)) { \
94 case __CONCAT3(SVR4_,c1,t1): bt->f |= __CONCAT(c1,t1); break; \
95 case __CONCAT3(SVR4_,c2,t2): bt->f |= __CONCAT(c2,t2); break; \
96 } \
97 }
98
99#define svr4_to_bsd_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) \
100 if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \
101 bt->f &= ~__CONCAT(a,b); \
102 switch (st->f & __CONCAT3(SVR4_,a,b)) { \
103 case __CONCAT3(SVR4_,c1,t1): bt->f |= __CONCAT(c1,t1); break; \
104 case __CONCAT3(SVR4_,c2,t2): bt->f |= __CONCAT(c2,t2); break; \
105 case __CONCAT3(SVR4_,c3,t3): bt->f |= __CONCAT(c3,t3); break; \
106 case __CONCAT3(SVR4_,c4,t4): bt->f |= __CONCAT(c4,t4); break; \
107 } \
108 }
109
110
111#define bsd_to_svr4_char(a,b) \
112 if (bt->c_cc[__CONCAT(a,b)] == _POSIX_VDISABLE) \
113 st->c_cc[__CONCAT3(SVR4_,a,b)] = SVR4_POSIX_VDISABLE; \
114 else \
115 st->c_cc[__CONCAT3(SVR4_,a,b)] = bt->c_cc[__CONCAT(a,b)]
116
117#define bsd_to_svr4_flag1(f,a,b) \
118 if (bt->f & __CONCAT(a,b)) \
119 st->f |= __CONCAT3(SVR4_,a,b); \
120 else \
121 st->f &= ~__CONCAT3(SVR4_,a,b)
122
123#define bsd_to_svr4_flag2(f,a,b,c1,t1,c2,t2) \
124 st->f &= ~__CONCAT(a,b); \
125 switch (bt->f & __CONCAT(a,b)) { \
126 case __CONCAT(c1,t1): st->f |= __CONCAT3(SVR4_,c1,t1); break; \
127 case __CONCAT(c2,t2): st->f |= __CONCAT3(SVR4_,c2,t2); break; \
128 }
129
130#define bsd_to_svr4_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) \
131 st->f &= ~__CONCAT(a,b); \
132 switch (bt->f & __CONCAT(a,b)) { \
133 case __CONCAT(c1,t1): st->f |= __CONCAT3(SVR4_,c1,t1); break; \
134 case __CONCAT(c2,t2): st->f |= __CONCAT3(SVR4_,c2,t2); break; \
135 case __CONCAT(c3,t3): st->f |= __CONCAT3(SVR4_,c3,t3); break; \
136 case __CONCAT(c4,t4): st->f |= __CONCAT3(SVR4_,c4,t4); break; \
137 }
138
139#ifdef DEBUG_SVR4
140static void
141print_svr4_termios(st)
142 const struct svr4_termios *st;
143{
144 int i;
145 DPRINTF(("SVR4\niflag=%lo oflag=%lo cflag=%lo lflag=%lo\n",
146 st->c_iflag, st->c_oflag, st->c_cflag, st->c_lflag));
147 DPRINTF(("cc: "));
148 for (i = 0; i < SVR4_NCCS; i++)
149 DPRINTF(("%o ", st->c_cc[i]));
150 DPRINTF(("\n"));
151}
152
153
154static void
155print_bsd_termios(bt)
156 const struct termios *bt;
157{
158 int i;
159 uprintf("BSD\niflag=%o oflag=%o cflag=%o lflag=%o\n",
160 bt->c_iflag, bt->c_oflag, bt->c_cflag, bt->c_lflag);
161 uprintf("cc: ");
162 for (i = 0; i < NCCS; i++)
163 uprintf("%o ", bt->c_cc[i]);
164 uprintf("\n");
165}
166#endif /* DEBUG_SVR4 */
167
168static u_long
169bsd_to_svr4_speed(sp, mask)
170 u_long sp;
171 u_long mask;
172{
173 switch (sp) {
174#undef getval
175#define getval(a,b) case __CONCAT(a,b): sp = __CONCAT3(SVR4_,a,b)
176 getval(B,0);
177 getval(B,50);
178 getval(B,75);
179 getval(B,110);
180 getval(B,134);
181 getval(B,150);
182 getval(B,200);
183 getval(B,300);
184 getval(B,600);
185 getval(B,1200);
186 getval(B,1800);
187 getval(B,2400);
188 getval(B,4800);
189 getval(B,9600);
190 getval(B,19200);
191 getval(B,38400);
192 getval(B,57600);
193 getval(B,115200);
194 default: sp = SVR4_B9600; /* XXX */
195 }
196
197 while ((mask & 1) == 0) {
198 mask >>= 1;
199 sp <<= 1;
200 }
201
202 return sp;
203}
204
205
206static u_long
207svr4_to_bsd_speed(sp, mask)
208 u_long sp;
209 u_long mask;
210{
211 while ((mask & 1) == 0) {
212 mask >>= 1;
213 sp >>= 1;
214 }
215
216 switch (sp & mask) {
217#undef getval
218#define getval(a,b) case __CONCAT3(SVR4_,a,b): return __CONCAT(a,b)
219 getval(B,0);
220 getval(B,50);
221 getval(B,75);
222 getval(B,110);
223 getval(B,134);
224 getval(B,150);
225 getval(B,200);
226 getval(B,300);
227 getval(B,600);
228 getval(B,1200);
229 getval(B,1800);
230 getval(B,2400);
231 getval(B,4800);
232 getval(B,9600);
233 getval(B,19200);
234 getval(B,38400);
235 getval(B,57600);
236 getval(B,115200);
237 default: return B9600; /* XXX */
238 }
239}
240
241
242static void
243svr4_to_bsd_termios(st, bt, new)
244 const struct svr4_termios *st;
245 struct termios *bt;
246 int new;
247{
248 /* control characters */
249 /*
250 * We process VMIN and VTIME first,
251 * because they are shared with VEOF and VEOL
252 */
253 svr4_to_bsd_char(V,MIN);
254 svr4_to_bsd_char(V,TIME);
255
256 svr4_to_bsd_char(V,INTR);
257 svr4_to_bsd_char(V,QUIT);
258 svr4_to_bsd_char(V,ERASE);
259 svr4_to_bsd_char(V,KILL);
260 svr4_to_bsd_char(V,EOF);
261 svr4_to_bsd_char(V,EOL);
262 svr4_to_bsd_char(V,EOL2);
263 undefined_char(V,SWTCH);
264 svr4_to_bsd_char(V,START);
265 svr4_to_bsd_char(V,STOP);
266 svr4_to_bsd_char(V,SUSP);
267 svr4_to_bsd_char(V,DSUSP);
268 svr4_to_bsd_char(V,REPRINT);
269 svr4_to_bsd_char(V,DISCARD);
270 svr4_to_bsd_char(V,WERASE);
271 svr4_to_bsd_char(V,LNEXT);
272
273 /* Input modes */
274 svr4_to_bsd_flag1(c_iflag,I,GNBRK);
275 svr4_to_bsd_flag1(c_iflag,B,RKINT);
276 svr4_to_bsd_flag1(c_iflag,I,GNPAR);
277 svr4_to_bsd_flag1(c_iflag,P,ARMRK);
278 svr4_to_bsd_flag1(c_iflag,I,NPCK);
279 svr4_to_bsd_flag1(c_iflag,I,STRIP);
280 svr4_to_bsd_flag1(c_iflag,I,NLCR);
281 svr4_to_bsd_flag1(c_iflag,I,GNCR);
282 svr4_to_bsd_flag1(c_iflag,I,CRNL);
283 undefined_flag1(c_iflag,I,UCLC);
284 svr4_to_bsd_flag1(c_iflag,I,XON);
285 svr4_to_bsd_flag1(c_iflag,I,XANY);
286 svr4_to_bsd_flag1(c_iflag,I,XOFF);
287 svr4_to_bsd_flag1(c_iflag,I,MAXBEL);
288 undefined_flag1(c_iflag,D,OSMODE);
289
290 /* Output modes */
291 svr4_to_bsd_flag1(c_oflag,O,POST);
292 undefined_flag1(c_oflag,O,LCUC);
293 svr4_to_bsd_flag1(c_oflag,O,NLCR);
294 undefined_flag1(c_oflag,O,CRNL);
295 undefined_flag1(c_oflag,O,NOCR);
296 undefined_flag1(c_oflag,O,NLRET);
297 undefined_flag1(c_oflag,O,FILL);
298 undefined_flag1(c_oflag,O,FDEL);
299 undefined_flag2(c_oflag,N,LDLY,N,L0,N,L1);
300 undefined_flag4(c_oflag,C,RDLY,C,R0,C,R1,C,R2,C,R3);
301 undefined_flag4(c_oflag,T,ABDLY,T,AB0,T,AB1,T,AB2,T,AB3);
302 undefined_flag2(c_oflag,B,SDLY,B,S0,B,S1);
303 undefined_flag2(c_oflag,V,TDLY,V,T0,V,T1);
304 undefined_flag2(c_oflag,F,FDLY,F,F0,F,F1);
305 undefined_flag1(c_oflag,P,AGEOUT);
306 undefined_flag1(c_oflag,W,RAP);
307
308 /* Control modes */
309 bt->c_ospeed = svr4_to_bsd_speed(st->c_cflag, SVR4_CBAUD);
310 svr4_to_bsd_flag4(c_cflag,C,SIZE,C,S5,C,S6,C,S7,C,S8)
311 svr4_to_bsd_flag1(c_cflag,C,STOPB);
312 svr4_to_bsd_flag1(c_cflag,C,READ);
313 svr4_to_bsd_flag1(c_cflag,P,ARENB);
314 svr4_to_bsd_flag1(c_cflag,P,ARODD);
315 svr4_to_bsd_flag1(c_cflag,H,UPCL);
316 svr4_to_bsd_flag1(c_cflag,C,LOCAL);
317 undefined_flag1(c_cflag,R,CV1EN);
318 undefined_flag1(c_cflag,X,MT1EN);
319 undefined_flag1(c_cflag,L,OBLK);
320 undefined_flag1(c_cflag,X,CLUDE);
321 bt->c_ispeed = svr4_to_bsd_speed(st->c_cflag, SVR4_CIBAUD);
322 undefined_flag1(c_cflag,P,AREXT);
323
324 /* line discipline modes */
325 svr4_to_bsd_flag1(c_lflag,I,SIG);
326 svr4_to_bsd_flag1(c_lflag,I,CANON);
327 undefined_flag1(c_lflag,X,CASE);
328 svr4_to_bsd_flag1(c_lflag,E,CHO);
329 svr4_to_bsd_flag1(c_lflag,E,CHOE);
330 svr4_to_bsd_flag1(c_lflag,E,CHOK);
331 svr4_to_bsd_flag1(c_lflag,E,CHONL);
332 svr4_to_bsd_flag1(c_lflag,N,OFLSH);
333 svr4_to_bsd_flag1(c_lflag,T,OSTOP);
334 svr4_to_bsd_flag1(c_lflag,E,CHOCTL);
335 svr4_to_bsd_flag1(c_lflag,E,CHOPRT);
336 svr4_to_bsd_flag1(c_lflag,E,CHOKE);
337 undefined_flag1(c_lflag,D,EFECHO);
338 svr4_to_bsd_flag1(c_lflag,F,LUSHO);
339 svr4_to_bsd_flag1(c_lflag,P,ENDIN);
340 svr4_to_bsd_flag1(c_lflag,I,EXTEN);
341}
342
343
344static void
345bsd_to_svr4_termios(bt, st)
346 const struct termios *bt;
347 struct svr4_termios *st;
348{
349 /* control characters */
350 /*
351 * We process VMIN and VTIME first,
352 * because they are shared with VEOF and VEOL
353 */
354 bsd_to_svr4_char(V,MIN);
355 bsd_to_svr4_char(V,TIME);
356 bsd_to_svr4_char(V,INTR);
357 bsd_to_svr4_char(V,QUIT);
358 bsd_to_svr4_char(V,ERASE);
359 bsd_to_svr4_char(V,KILL);
360 bsd_to_svr4_char(V,EOF);
361 bsd_to_svr4_char(V,EOL);
362 bsd_to_svr4_char(V,EOL2);
363 undefined_char(V,SWTCH);
364 bsd_to_svr4_char(V,START);
365 bsd_to_svr4_char(V,STOP);
366 bsd_to_svr4_char(V,SUSP);
367 bsd_to_svr4_char(V,DSUSP);
368 bsd_to_svr4_char(V,REPRINT);
369 bsd_to_svr4_char(V,DISCARD);
370 bsd_to_svr4_char(V,WERASE);
371 bsd_to_svr4_char(V,LNEXT);
372
373 /* Input modes */
374 bsd_to_svr4_flag1(c_iflag,I,GNBRK);
375 bsd_to_svr4_flag1(c_iflag,B,RKINT);
376 bsd_to_svr4_flag1(c_iflag,I,GNPAR);
377 bsd_to_svr4_flag1(c_iflag,P,ARMRK);
378 bsd_to_svr4_flag1(c_iflag,I,NPCK);
379 bsd_to_svr4_flag1(c_iflag,I,STRIP);
380 bsd_to_svr4_flag1(c_iflag,I,NLCR);
381 bsd_to_svr4_flag1(c_iflag,I,GNCR);
382 bsd_to_svr4_flag1(c_iflag,I,CRNL);
383 undefined_flag1(c_iflag,I,UCLC);
384 bsd_to_svr4_flag1(c_iflag,I,XON);
385 bsd_to_svr4_flag1(c_iflag,I,XANY);
386 bsd_to_svr4_flag1(c_iflag,I,XOFF);
387 bsd_to_svr4_flag1(c_iflag,I,MAXBEL);
388 undefined_flag1(c_iflag,D,OSMODE);
389
390 /* Output modes */
391 bsd_to_svr4_flag1(c_oflag,O,POST);
392 undefined_flag1(c_oflag,O,LCUC);
393 bsd_to_svr4_flag1(c_oflag,O,NLCR);
394 undefined_flag1(c_oflag,O,CRNL);
395 undefined_flag1(c_oflag,O,NOCR);
396 undefined_flag1(c_oflag,O,NLRET);
397 undefined_flag1(c_oflag,O,FILL);
398 undefined_flag1(c_oflag,O,FDEL);
399 undefined_flag2(c_oflag,N,LDLY,N,L0,N,L1);
400 undefined_flag4(c_oflag,C,RDLY,C,R0,C,R1,C,R2,C,R3);
401 undefined_flag4(c_oflag,T,ABDLY,T,AB0,T,AB1,T,AB2,T,AB3);
402 undefined_flag2(c_oflag,B,SDLY,B,S0,B,S1);
403 undefined_flag2(c_oflag,V,TDLY,V,T0,V,T1);
404 undefined_flag2(c_oflag,F,FDLY,F,F0,F,F1);
405 undefined_flag1(c_oflag,P,AGEOUT);
406 undefined_flag1(c_oflag,W,RAP);
407
408 /* Control modes */
409 st->c_cflag &= ~SVR4_CBAUD;
410 st->c_cflag |= bsd_to_svr4_speed(bt->c_ospeed, SVR4_CBAUD);
411 bsd_to_svr4_flag4(c_cflag,C,SIZE,C,S5,C,S6,C,S7,C,S8)
412 bsd_to_svr4_flag1(c_cflag,C,STOPB);
413 bsd_to_svr4_flag1(c_cflag,C,READ);
414 bsd_to_svr4_flag1(c_cflag,P,ARENB);
415 bsd_to_svr4_flag1(c_cflag,P,ARODD);
416 bsd_to_svr4_flag1(c_cflag,H,UPCL);
417 bsd_to_svr4_flag1(c_cflag,C,LOCAL);
418 undefined_flag1(c_cflag,R,CV1EN);
419 undefined_flag1(c_cflag,X,MT1EN);
420 undefined_flag1(c_cflag,L,OBLK);
421 undefined_flag1(c_cflag,X,CLUDE);
422 st->c_cflag &= ~SVR4_CIBAUD;
423 st->c_cflag |= bsd_to_svr4_speed(bt->c_ispeed, SVR4_CIBAUD);
424
425 undefined_flag1(c_oflag,P,AREXT);
426
427 /* line discipline modes */
428 bsd_to_svr4_flag1(c_lflag,I,SIG);
429 bsd_to_svr4_flag1(c_lflag,I,CANON);
430 undefined_flag1(c_lflag,X,CASE);
431 bsd_to_svr4_flag1(c_lflag,E,CHO);
432 bsd_to_svr4_flag1(c_lflag,E,CHOE);
433 bsd_to_svr4_flag1(c_lflag,E,CHOK);
434 bsd_to_svr4_flag1(c_lflag,E,CHONL);
435 bsd_to_svr4_flag1(c_lflag,N,OFLSH);
436 bsd_to_svr4_flag1(c_lflag,T,OSTOP);
437 bsd_to_svr4_flag1(c_lflag,E,CHOCTL);
438 bsd_to_svr4_flag1(c_lflag,E,CHOPRT);
439 bsd_to_svr4_flag1(c_lflag,E,CHOKE);
440 undefined_flag1(c_lflag,D,EFECHO);
441 bsd_to_svr4_flag1(c_lflag,F,LUSHO);
442 bsd_to_svr4_flag1(c_lflag,P,ENDIN);
443 bsd_to_svr4_flag1(c_lflag,I,EXTEN);
444}
445
446
447static void
448svr4_termio_to_termios(t, ts)
449 const struct svr4_termio *t;
450 struct svr4_termios *ts;
451{
452 int i;
453
454 ts->c_iflag = (svr4_tcflag_t) t->c_iflag;
455 ts->c_oflag = (svr4_tcflag_t) t->c_oflag;
456 ts->c_cflag = (svr4_tcflag_t) t->c_cflag;
457 ts->c_lflag = (svr4_tcflag_t) t->c_lflag;
458
459 for (i = 0; i < SVR4_NCC; i++)
460 ts->c_cc[i] = (svr4_cc_t) t->c_cc[i];
461}
462
463
464static void
465svr4_termios_to_termio(ts, t)
466 const struct svr4_termios *ts;
467 struct svr4_termio *t;
468{
469 int i;
470
471 t->c_iflag = (u_short) ts->c_iflag;
472 t->c_oflag = (u_short) ts->c_oflag;
473 t->c_cflag = (u_short) ts->c_cflag;
474 t->c_lflag = (u_short) ts->c_lflag;
475 t->c_line = 0; /* XXX */
476
477 for (i = 0; i < SVR4_NCC; i++)
478 t->c_cc[i] = (u_char) ts->c_cc[i];
479}
480
481int
482svr4_term_ioctl(fp, td, retval, fd, cmd, data)
483 struct file *fp;
484 struct thread *td;
485 register_t *retval;
486 int fd;
487 u_long cmd;
488 caddr_t data;
489{
490 struct termios bt;
491 struct svr4_termios st;
492 struct svr4_termio t;
493 int error, new;
494
495 *retval = 0;
496
497 DPRINTF(("TERM ioctl %lx\n", cmd));
498
499 switch (cmd) {
500 case SVR4_TCGETA:
501 case SVR4_TCGETS:
502 DPRINTF(("ioctl(TCGET%c);\n", cmd == SVR4_TCGETA ? 'A' : 'S'));
503 if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t) &bt,
504 td->td_ucred, td)) != 0)
505 return error;
506
507 memset(&st, 0, sizeof(st));
508 bsd_to_svr4_termios(&bt, &st);
509
510#ifdef DEBUG_SVR4
511 print_bsd_termios(&bt);
512 print_svr4_termios(&st);
513#endif /* DEBUG_SVR4 */
514
515 if (cmd == SVR4_TCGETA) {
516 svr4_termios_to_termio(&st, &t);
517 return copyout(&t, data, sizeof(t));
518 }
519 else {
520 return copyout(&st, data, sizeof(st));
521 }
522
523 case SVR4_TCSETA:
524 case SVR4_TCSETS:
525 case SVR4_TCSETAW:
526 case SVR4_TCSETSW:
527 case SVR4_TCSETAF:
528 case SVR4_TCSETSF:
529 DPRINTF(("TCSET{A,S,AW,SW,AF,SF}\n"));
530 /* get full BSD termios so we don't lose information */
531 if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t) &bt,
532 td->td_ucred, td)) != 0)
533 return error;
534
535 switch (cmd) {
536 case SVR4_TCSETS:
537 case SVR4_TCSETSW:
538 case SVR4_TCSETSF:
539 if ((error = copyin(data, &st, sizeof(st))) != 0)
540 return error;
541 new = 1;
542 break;
543
544 case SVR4_TCSETA:
545 case SVR4_TCSETAW:
546 case SVR4_TCSETAF:
547 if ((error = copyin(data, &t, sizeof(t))) != 0)
548 return error;
549
550 svr4_termio_to_termios(&t, &st);
551 new = 0;
552 break;
553
554 default:
555 return EINVAL;
556 }
557
558 svr4_to_bsd_termios(&st, &bt, new);
559
560 switch (cmd) {
561 case SVR4_TCSETA:
562 case SVR4_TCSETS:
563 DPRINTF(("ioctl(TCSET[A|S]);\n"));
564 cmd = TIOCSETA;
565 break;
566 case SVR4_TCSETAW:
567 case SVR4_TCSETSW:
568 DPRINTF(("ioctl(TCSET[A|S]W);\n"));
569 cmd = TIOCSETAW;
570 break;
571 case SVR4_TCSETAF:
572 case SVR4_TCSETSF:
573 DPRINTF(("ioctl(TCSET[A|S]F);\n"));
574 cmd = TIOCSETAF;
575 break;
576 }
577
578#ifdef DEBUG_SVR4
579 print_bsd_termios(&bt);
580 print_svr4_termios(&st);
581#endif /* DEBUG_SVR4 */
582
583 return fo_ioctl(fp, cmd, (caddr_t) &bt, td->td_ucred, td);
584
585 case SVR4_TIOCGWINSZ:
586 DPRINTF(("TIOCGWINSZ\n"));
587 {
588 struct svr4_winsize ws;
589
590 error = fo_ioctl(fp, TIOCGWINSZ, (caddr_t) &ws,
591 td->td_ucred, td);
592 if (error)
593 return error;
594 return copyout(&ws, data, sizeof(ws));
595 }
596
597 case SVR4_TIOCSWINSZ:
598 DPRINTF(("TIOCSWINSZ\n"));
599 {
600 struct svr4_winsize ws;
601
602 if ((error = copyin(data, &ws, sizeof(ws))) != 0)
603 return error;
604 return fo_ioctl(fp, TIOCSWINSZ, (caddr_t) &ws,
605 td->td_ucred, td);
606 }
607
608 default:
609 DPRINTF(("teleport to STREAMS ioctls...\n"));
610 return svr4_stream_ti_ioctl(fp, td, retval, fd, cmd, data);
611 }
612}