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}
|