Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / emulation / svr4 / svr4_termios.c
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: src/sys/svr4/svr4_termios.c,v 1.5 1999/12/08 12:00:48 newton Exp $
29  * $DragonFly: src/sys/emulation/svr4/Attic/svr4_termios.c,v 1.2 2003/06/17 04:28:58 dillon Exp $
30  */
31
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 <svr4/svr4.h>
42 #include <svr4/svr4_util.h>
43 #include <svr4/svr4_ioctl.h>
44 #include <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
54 static u_long bsd_to_svr4_speed __P((u_long, u_long));
55 static u_long svr4_to_bsd_speed __P((u_long, u_long));
56 static void svr4_to_bsd_termios __P((const struct svr4_termios *, 
57                                      struct termios *, int));
58 static void bsd_to_svr4_termios __P((const struct termios *, 
59                                      struct svr4_termios *));
60 static void svr4_termio_to_termios __P((const struct svr4_termio *,
61                                         struct svr4_termios *));
62 static void svr4_termios_to_termio __P((const struct svr4_termios *,
63                                         struct svr4_termio *));
64 #ifdef DEBUG_SVR4
65 static void print_svr4_termios __P((const struct svr4_termios *));
66 static void print_bsd_termios __P((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
140 static void
141 print_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
154 static void
155 print_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
168 static u_long
169 bsd_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
206 static u_long
207 svr4_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
242 static void
243 svr4_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
344 static void
345 bsd_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
447 static void
448 svr4_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
464 static void
465 svr4_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
481 int
482 svr4_term_ioctl(fp, p, retval, fd, cmd, data)
483         struct file *fp;
484         struct proc *p;
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 %x\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, p)) != 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, p)) != 0)
531                         return error;
532
533                 switch (cmd) {
534                 case SVR4_TCSETS:
535                 case SVR4_TCSETSW:
536                 case SVR4_TCSETSF:
537                         if ((error = copyin(data, &st, sizeof(st))) != 0)
538                                 return error;
539                         new = 1;
540                         break;
541
542                 case SVR4_TCSETA:
543                 case SVR4_TCSETAW:
544                 case SVR4_TCSETAF:
545                         if ((error = copyin(data, &t, sizeof(t))) != 0)
546                                 return error;
547
548                         svr4_termio_to_termios(&t, &st);
549                         new = 0;
550                         break;
551
552                 default:
553                         return EINVAL;
554                 }
555
556                 svr4_to_bsd_termios(&st, &bt, new);
557
558                 switch (cmd) {
559                 case SVR4_TCSETA:
560                 case SVR4_TCSETS:
561                         DPRINTF(("ioctl(TCSET[A|S]);\n"));
562                         cmd = TIOCSETA;
563                         break;
564                 case SVR4_TCSETAW:
565                 case SVR4_TCSETSW:
566                         DPRINTF(("ioctl(TCSET[A|S]W);\n"));
567                         cmd = TIOCSETAW;
568                         break;
569                 case SVR4_TCSETAF:
570                 case SVR4_TCSETSF:
571                         DPRINTF(("ioctl(TCSET[A|S]F);\n"));
572                         cmd = TIOCSETAF;
573                         break;
574                 }
575
576 #ifdef DEBUG_SVR4
577                 print_bsd_termios(&bt);
578                 print_svr4_termios(&st);
579 #endif /* DEBUG_SVR4 */
580
581                 return fo_ioctl(fp, cmd, (caddr_t) &bt, p);
582
583         case SVR4_TIOCGWINSZ:
584                 DPRINTF(("TIOCGWINSZ\n"));
585                 {
586                         struct svr4_winsize ws;
587
588                         error = fo_ioctl(fp, TIOCGWINSZ, (caddr_t) &ws, p);
589                         if (error)
590                                 return error;
591                         return copyout(&ws, data, sizeof(ws));
592                 }
593
594         case SVR4_TIOCSWINSZ:
595                 DPRINTF(("TIOCSWINSZ\n"));
596                 {
597                         struct svr4_winsize ws;
598
599                         if ((error = copyin(data, &ws, sizeof(ws))) != 0)
600                                 return error;
601                         return fo_ioctl(fp, TIOCSWINSZ, (caddr_t) &ws, p);
602                 }
603
604         default:
605                 DPRINTF(("teleport to STREAMS ioctls...\n"));
606                 return svr4_stream_ti_ioctl(fp, p, retval, fd, cmd, data);
607         }
608 }