svr4_termios.c revision 54305
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 54305 1999-12-08 12:01:59Z newton $ 29 */ 30 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 <svr4/svr4.h> 41#include <svr4/svr4_util.h> 42#include <svr4/svr4_ioctl.h> 43#include <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 __P((u_long, u_long)); 54static u_long svr4_to_bsd_speed __P((u_long, u_long)); 55static void svr4_to_bsd_termios __P((const struct svr4_termios *, 56 struct termios *, int)); 57static void bsd_to_svr4_termios __P((const struct termios *, 58 struct svr4_termios *)); 59static void svr4_termio_to_termios __P((const struct svr4_termio *, 60 struct svr4_termios *)); 61static void svr4_termios_to_termio __P((const struct svr4_termios *, 62 struct svr4_termio *)); 63#ifdef DEBUG_SVR4 64static void print_svr4_termios __P((const struct svr4_termios *)); 65static void print_bsd_termios __P((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, p, retval, fd, cmd, data) 482 struct file *fp; 483 struct proc *p; 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 %x\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, p)) != 0) 503 return error; 504 505 memset(&st, 0, sizeof(st)); 506 bsd_to_svr4_termios(&bt, &st); 507 508#ifdef DEBUG_SVR4 509 print_bsd_termios(&bt); 510 print_svr4_termios(&st); 511#endif /* DEBUG_SVR4 */ 512 513 if (cmd == SVR4_TCGETA) { 514 svr4_termios_to_termio(&st, &t); 515 return copyout(&t, data, sizeof(t)); 516 } 517 else { 518 return copyout(&st, data, sizeof(st)); 519 } 520 521 case SVR4_TCSETA: 522 case SVR4_TCSETS: 523 case SVR4_TCSETAW: 524 case SVR4_TCSETSW: 525 case SVR4_TCSETAF: 526 case SVR4_TCSETSF: 527 DPRINTF(("TCSET{A,S,AW,SW,AF,SF}\n")); 528 /* get full BSD termios so we don't lose information */ 529 if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t) &bt, p)) != 0) 530 return error; 531 532 switch (cmd) { 533 case SVR4_TCSETS: 534 case SVR4_TCSETSW: 535 case SVR4_TCSETSF: 536 if ((error = copyin(data, &st, sizeof(st))) != 0) 537 return error; 538 new = 1; 539 break; 540 541 case SVR4_TCSETA: 542 case SVR4_TCSETAW: 543 case SVR4_TCSETAF: 544 if ((error = copyin(data, &t, sizeof(t))) != 0) 545 return error; 546 547 svr4_termio_to_termios(&t, &st); 548 new = 0; 549 break; 550 551 default: 552 return EINVAL; 553 } 554 555 svr4_to_bsd_termios(&st, &bt, new); 556 557 switch (cmd) { 558 case SVR4_TCSETA: 559 case SVR4_TCSETS: 560 DPRINTF(("ioctl(TCSET[A|S]);\n")); 561 cmd = TIOCSETA; 562 break; 563 case SVR4_TCSETAW: 564 case SVR4_TCSETSW: 565 DPRINTF(("ioctl(TCSET[A|S]W);\n")); 566 cmd = TIOCSETAW; 567 break; 568 case SVR4_TCSETAF: 569 case SVR4_TCSETSF: 570 DPRINTF(("ioctl(TCSET[A|S]F);\n")); 571 cmd = TIOCSETAF; 572 break; 573 } 574 575#ifdef DEBUG_SVR4 576 print_bsd_termios(&bt); 577 print_svr4_termios(&st); 578#endif /* DEBUG_SVR4 */ 579 580 return fo_ioctl(fp, cmd, (caddr_t) &bt, p); 581 582 case SVR4_TIOCGWINSZ: 583 DPRINTF(("TIOCGWINSZ\n")); 584 { 585 struct svr4_winsize ws; 586 587 error = fo_ioctl(fp, TIOCGWINSZ, (caddr_t) &ws, p); 588 if (error) 589 return error; 590 return copyout(&ws, data, sizeof(ws)); 591 } 592 593 case SVR4_TIOCSWINSZ: 594 DPRINTF(("TIOCSWINSZ\n")); 595 { 596 struct svr4_winsize ws; 597 598 if ((error = copyin(data, &ws, sizeof(ws))) != 0) 599 return error; 600 return fo_ioctl(fp, TIOCSWINSZ, (caddr_t) &ws, p); 601 } 602 603 default: 604 DPRINTF(("teleport to STREAMS ioctls...\n")); 605 return svr4_stream_ti_ioctl(fp, p, retval, fd, cmd, data); 606 } 607} 608