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