svr4_termios.c revision 49267
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 * $Id$ 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/fcntl.h> 37#include <sys/unistd.h> 38#include <sys/termios.h> 39#include <sys/tty.h> 40#include <sys/socket.h> 41#include <sys/mount.h> 42#include <net/if.h> 43#include <sys/malloc.h> 44 45#include <sys/sysproto.h> 46 47#include <svr4/svr4.h> 48#include <svr4/svr4_types.h> 49#include <svr4/svr4_util.h> 50#include <svr4/svr4_signal.h> 51#include <svr4/svr4_ioctl.h> 52#include <svr4/svr4_proto.h> 53#include <svr4/svr4_stropts.h> 54#include <svr4/svr4_termios.h> 55 56 57#ifndef __CONCAT3 58# if __STDC__ 59# define __CONCAT3(a,b,c) a ## b ## c 60# else 61# define __CONCAT3(a,b,c) a/**/b/**/c 62# endif 63#endif 64 65static u_long bsd_to_svr4_speed __P((u_long, u_long)); 66static u_long svr4_to_bsd_speed __P((u_long, u_long)); 67static void svr4_to_bsd_termios __P((const struct svr4_termios *, 68 struct termios *, int)); 69static void bsd_to_svr4_termios __P((const struct termios *, 70 struct svr4_termios *)); 71static void svr4_termio_to_termios __P((const struct svr4_termio *, 72 struct svr4_termios *)); 73static void svr4_termios_to_termio __P((const struct svr4_termios *, 74 struct svr4_termio *)); 75#ifdef DEBUG_SVR4 76static void print_svr4_termios __P((const struct svr4_termios *)); 77static void print_bsd_termios __P((const struct termios *)); 78#endif /* DEBUG_SVR4 */ 79 80#define undefined_char(a,b) /**/ 81#define undefined_flag1(f,a,b) /**/ 82#define undefined_flag2(f,a,b,c1,t1,c2,t2) /**/ 83#define undefined_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) /**/ 84 85#define svr4_to_bsd_char(a,b) \ 86 if (new || __CONCAT3(SVR4_,a,b) < SVR4_NCC) { \ 87 if (st->c_cc[__CONCAT3(SVR4_,a,b)] == SVR4_POSIX_VDISABLE) \ 88 bt->c_cc[__CONCAT(a,b)] = _POSIX_VDISABLE; \ 89 else \ 90 bt->c_cc[__CONCAT(a,b)] = st->c_cc[__CONCAT3(SVR4_,a,b)]; \ 91 } 92 93#define svr4_to_bsd_flag1(f,a,b) \ 94 if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \ 95 if (st->f & __CONCAT3(SVR4_,a,b)) \ 96 bt->f |= __CONCAT(a,b); \ 97 else \ 98 bt->f &= ~__CONCAT(a,b); \ 99 } 100 101#define svr4_to_bsd_flag2(f,a,b,c1,t1,c2,t2) \ 102 if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \ 103 bt->f &= ~__CONCAT(a,b); \ 104 switch (st->f & __CONCAT3(SVR4_,a,b)) { \ 105 case __CONCAT3(SVR4_,c1,t1): bt->f |= __CONCAT(c1,t1); break; \ 106 case __CONCAT3(SVR4_,c2,t2): bt->f |= __CONCAT(c2,t2); break; \ 107 } \ 108 } 109 110#define svr4_to_bsd_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) \ 111 if (new || __CONCAT3(SVR4_,a,b) < 0200000) { \ 112 bt->f &= ~__CONCAT(a,b); \ 113 switch (st->f & __CONCAT3(SVR4_,a,b)) { \ 114 case __CONCAT3(SVR4_,c1,t1): bt->f |= __CONCAT(c1,t1); break; \ 115 case __CONCAT3(SVR4_,c2,t2): bt->f |= __CONCAT(c2,t2); break; \ 116 case __CONCAT3(SVR4_,c3,t3): bt->f |= __CONCAT(c3,t3); break; \ 117 case __CONCAT3(SVR4_,c4,t4): bt->f |= __CONCAT(c4,t4); break; \ 118 } \ 119 } 120 121 122#define bsd_to_svr4_char(a,b) \ 123 if (bt->c_cc[__CONCAT(a,b)] == _POSIX_VDISABLE) \ 124 st->c_cc[__CONCAT3(SVR4_,a,b)] = SVR4_POSIX_VDISABLE; \ 125 else \ 126 st->c_cc[__CONCAT3(SVR4_,a,b)] = bt->c_cc[__CONCAT(a,b)] 127 128#define bsd_to_svr4_flag1(f,a,b) \ 129 if (bt->f & __CONCAT(a,b)) \ 130 st->f |= __CONCAT3(SVR4_,a,b); \ 131 else \ 132 st->f &= ~__CONCAT3(SVR4_,a,b) 133 134#define bsd_to_svr4_flag2(f,a,b,c1,t1,c2,t2) \ 135 st->f &= ~__CONCAT(a,b); \ 136 switch (bt->f & __CONCAT(a,b)) { \ 137 case __CONCAT(c1,t1): st->f |= __CONCAT3(SVR4_,c1,t1); break; \ 138 case __CONCAT(c2,t2): st->f |= __CONCAT3(SVR4_,c2,t2); break; \ 139 } 140 141#define bsd_to_svr4_flag4(f,a,b,c1,t1,c2,t2,c3,t3,c4,t4) \ 142 st->f &= ~__CONCAT(a,b); \ 143 switch (bt->f & __CONCAT(a,b)) { \ 144 case __CONCAT(c1,t1): st->f |= __CONCAT3(SVR4_,c1,t1); break; \ 145 case __CONCAT(c2,t2): st->f |= __CONCAT3(SVR4_,c2,t2); break; \ 146 case __CONCAT(c3,t3): st->f |= __CONCAT3(SVR4_,c3,t3); break; \ 147 case __CONCAT(c4,t4): st->f |= __CONCAT3(SVR4_,c4,t4); break; \ 148 } 149 150#ifdef DEBUG_SVR4 151static void 152print_svr4_termios(st) 153 const struct svr4_termios *st; 154{ 155 int i; 156 DPRINTF(("SVR4\niflag=%lo oflag=%lo cflag=%lo lflag=%lo\n", 157 st->c_iflag, st->c_oflag, st->c_cflag, st->c_lflag)); 158 DPRINTF(("cc: ")); 159 for (i = 0; i < SVR4_NCCS; i++) 160 DPRINTF(("%o ", st->c_cc[i])); 161 DPRINTF(("\n")); 162} 163 164 165static void 166print_bsd_termios(bt) 167 const struct termios *bt; 168{ 169 int i; 170 uprintf("BSD\niflag=%o oflag=%o cflag=%o lflag=%o\n", 171 bt->c_iflag, bt->c_oflag, bt->c_cflag, bt->c_lflag); 172 uprintf("cc: "); 173 for (i = 0; i < NCCS; i++) 174 uprintf("%o ", bt->c_cc[i]); 175 uprintf("\n"); 176} 177#endif /* DEBUG_SVR4 */ 178 179static u_long 180bsd_to_svr4_speed(sp, mask) 181 u_long sp; 182 u_long mask; 183{ 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 */ 206 } 207 208 while ((mask & 1) == 0) { 209 mask >>= 1; 210 sp <<= 1; 211 } 212 213 return sp; 214} 215 216 217static u_long 218svr4_to_bsd_speed(sp, mask) 219 u_long sp; 220 u_long mask; 221{ 222 while ((mask & 1) == 0) { 223 mask >>= 1; 224 sp >>= 1; 225 } 226 227 switch (sp & mask) { 228#undef getval 229#define getval(a,b) case __CONCAT3(SVR4_,a,b): return __CONCAT(a,b) 230 getval(B,0); 231 getval(B,50); 232 getval(B,75); 233 getval(B,110); 234 getval(B,134); 235 getval(B,150); 236 getval(B,200); 237 getval(B,300); 238 getval(B,600); 239 getval(B,1200); 240 getval(B,1800); 241 getval(B,2400); 242 getval(B,4800); 243 getval(B,9600); 244 getval(B,19200); 245 getval(B,38400); 246 getval(B,57600); 247 getval(B,115200); 248 default: return B9600; /* XXX */ 249 } 250} 251 252 253static void 254svr4_to_bsd_termios(st, bt, new) 255 const struct svr4_termios *st; 256 struct termios *bt; 257 int new; 258{ 259 /* control characters */ 260 /* 261 * We process VMIN and VTIME first, 262 * because they are shared with VEOF and VEOL 263 */ 264 svr4_to_bsd_char(V,MIN); 265 svr4_to_bsd_char(V,TIME); 266 267 svr4_to_bsd_char(V,INTR); 268 svr4_to_bsd_char(V,QUIT); 269 svr4_to_bsd_char(V,ERASE); 270 svr4_to_bsd_char(V,KILL); 271 svr4_to_bsd_char(V,EOF); 272 svr4_to_bsd_char(V,EOL); 273 svr4_to_bsd_char(V,EOL2); 274 undefined_char(V,SWTCH); 275 svr4_to_bsd_char(V,START); 276 svr4_to_bsd_char(V,STOP); 277 svr4_to_bsd_char(V,SUSP); 278 svr4_to_bsd_char(V,DSUSP); 279 svr4_to_bsd_char(V,REPRINT); 280 svr4_to_bsd_char(V,DISCARD); 281 svr4_to_bsd_char(V,WERASE); 282 svr4_to_bsd_char(V,LNEXT); 283 284 /* Input modes */ 285 svr4_to_bsd_flag1(c_iflag,I,GNBRK); 286 svr4_to_bsd_flag1(c_iflag,B,RKINT); 287 svr4_to_bsd_flag1(c_iflag,I,GNPAR); 288 svr4_to_bsd_flag1(c_iflag,P,ARMRK); 289 svr4_to_bsd_flag1(c_iflag,I,NPCK); 290 svr4_to_bsd_flag1(c_iflag,I,STRIP); 291 svr4_to_bsd_flag1(c_iflag,I,NLCR); 292 svr4_to_bsd_flag1(c_iflag,I,GNCR); 293 svr4_to_bsd_flag1(c_iflag,I,CRNL); 294 undefined_flag1(c_iflag,I,UCLC); 295 svr4_to_bsd_flag1(c_iflag,I,XON); 296 svr4_to_bsd_flag1(c_iflag,I,XANY); 297 svr4_to_bsd_flag1(c_iflag,I,XOFF); 298 svr4_to_bsd_flag1(c_iflag,I,MAXBEL); 299 undefined_flag1(c_iflag,D,OSMODE); 300 301 /* Output modes */ 302 svr4_to_bsd_flag1(c_oflag,O,POST); 303 undefined_flag1(c_oflag,O,LCUC); 304 svr4_to_bsd_flag1(c_oflag,O,NLCR); 305 undefined_flag1(c_oflag,O,CRNL); 306 undefined_flag1(c_oflag,O,NOCR); 307 undefined_flag1(c_oflag,O,NLRET); 308 undefined_flag1(c_oflag,O,FILL); 309 undefined_flag1(c_oflag,O,FDEL); 310 undefined_flag2(c_oflag,N,LDLY,N,L0,N,L1); 311 undefined_flag4(c_oflag,C,RDLY,C,R0,C,R1,C,R2,C,R3); 312 undefined_flag4(c_oflag,T,ABDLY,T,AB0,T,AB1,T,AB2,T,AB3); 313 undefined_flag2(c_oflag,B,SDLY,B,S0,B,S1); 314 undefined_flag2(c_oflag,V,TDLY,V,T0,V,T1); 315 undefined_flag2(c_oflag,F,FDLY,F,F0,F,F1); 316 undefined_flag1(c_oflag,P,AGEOUT); 317 undefined_flag1(c_oflag,W,RAP); 318 319 /* Control modes */ 320 bt->c_ospeed = svr4_to_bsd_speed(st->c_cflag, SVR4_CBAUD); 321 svr4_to_bsd_flag4(c_cflag,C,SIZE,C,S5,C,S6,C,S7,C,S8) 322 svr4_to_bsd_flag1(c_cflag,C,STOPB); 323 svr4_to_bsd_flag1(c_cflag,C,READ); 324 svr4_to_bsd_flag1(c_cflag,P,ARENB); 325 svr4_to_bsd_flag1(c_cflag,P,ARODD); 326 svr4_to_bsd_flag1(c_cflag,H,UPCL); 327 svr4_to_bsd_flag1(c_cflag,C,LOCAL); 328 undefined_flag1(c_cflag,R,CV1EN); 329 undefined_flag1(c_cflag,X,MT1EN); 330 undefined_flag1(c_cflag,L,OBLK); 331 undefined_flag1(c_cflag,X,CLUDE); 332 bt->c_ispeed = svr4_to_bsd_speed(st->c_cflag, SVR4_CIBAUD); 333 undefined_flag1(c_cflag,P,AREXT); 334 335 /* line discipline modes */ 336 svr4_to_bsd_flag1(c_lflag,I,SIG); 337 svr4_to_bsd_flag1(c_lflag,I,CANON); 338 undefined_flag1(c_lflag,X,CASE); 339 svr4_to_bsd_flag1(c_lflag,E,CHO); 340 svr4_to_bsd_flag1(c_lflag,E,CHOE); 341 svr4_to_bsd_flag1(c_lflag,E,CHOK); 342 svr4_to_bsd_flag1(c_lflag,E,CHONL); 343 svr4_to_bsd_flag1(c_lflag,N,OFLSH); 344 svr4_to_bsd_flag1(c_lflag,T,OSTOP); 345 svr4_to_bsd_flag1(c_lflag,E,CHOCTL); 346 svr4_to_bsd_flag1(c_lflag,E,CHOPRT); 347 svr4_to_bsd_flag1(c_lflag,E,CHOKE); 348 undefined_flag1(c_lflag,D,EFECHO); 349 svr4_to_bsd_flag1(c_lflag,F,LUSHO); 350 svr4_to_bsd_flag1(c_lflag,P,ENDIN); 351 svr4_to_bsd_flag1(c_lflag,I,EXTEN); 352} 353 354 355static void 356bsd_to_svr4_termios(bt, st) 357 const struct termios *bt; 358 struct svr4_termios *st; 359{ 360 /* control characters */ 361 /* 362 * We process VMIN and VTIME first, 363 * because they are shared with VEOF and VEOL 364 */ 365 bsd_to_svr4_char(V,MIN); 366 bsd_to_svr4_char(V,TIME); 367 bsd_to_svr4_char(V,INTR); 368 bsd_to_svr4_char(V,QUIT); 369 bsd_to_svr4_char(V,ERASE); 370 bsd_to_svr4_char(V,KILL); 371 bsd_to_svr4_char(V,EOF); 372 bsd_to_svr4_char(V,EOL); 373 bsd_to_svr4_char(V,EOL2); 374 undefined_char(V,SWTCH); 375 bsd_to_svr4_char(V,START); 376 bsd_to_svr4_char(V,STOP); 377 bsd_to_svr4_char(V,SUSP); 378 bsd_to_svr4_char(V,DSUSP); 379 bsd_to_svr4_char(V,REPRINT); 380 bsd_to_svr4_char(V,DISCARD); 381 bsd_to_svr4_char(V,WERASE); 382 bsd_to_svr4_char(V,LNEXT); 383 384 /* Input modes */ 385 bsd_to_svr4_flag1(c_iflag,I,GNBRK); 386 bsd_to_svr4_flag1(c_iflag,B,RKINT); 387 bsd_to_svr4_flag1(c_iflag,I,GNPAR); 388 bsd_to_svr4_flag1(c_iflag,P,ARMRK); 389 bsd_to_svr4_flag1(c_iflag,I,NPCK); 390 bsd_to_svr4_flag1(c_iflag,I,STRIP); 391 bsd_to_svr4_flag1(c_iflag,I,NLCR); 392 bsd_to_svr4_flag1(c_iflag,I,GNCR); 393 bsd_to_svr4_flag1(c_iflag,I,CRNL); 394 undefined_flag1(c_iflag,I,UCLC); 395 bsd_to_svr4_flag1(c_iflag,I,XON); 396 bsd_to_svr4_flag1(c_iflag,I,XANY); 397 bsd_to_svr4_flag1(c_iflag,I,XOFF); 398 bsd_to_svr4_flag1(c_iflag,I,MAXBEL); 399 undefined_flag1(c_iflag,D,OSMODE); 400 401 /* Output modes */ 402 bsd_to_svr4_flag1(c_oflag,O,POST); 403 undefined_flag1(c_oflag,O,LCUC); 404 bsd_to_svr4_flag1(c_oflag,O,NLCR); 405 undefined_flag1(c_oflag,O,CRNL); 406 undefined_flag1(c_oflag,O,NOCR); 407 undefined_flag1(c_oflag,O,NLRET); 408 undefined_flag1(c_oflag,O,FILL); 409 undefined_flag1(c_oflag,O,FDEL); 410 undefined_flag2(c_oflag,N,LDLY,N,L0,N,L1); 411 undefined_flag4(c_oflag,C,RDLY,C,R0,C,R1,C,R2,C,R3); 412 undefined_flag4(c_oflag,T,ABDLY,T,AB0,T,AB1,T,AB2,T,AB3); 413 undefined_flag2(c_oflag,B,SDLY,B,S0,B,S1); 414 undefined_flag2(c_oflag,V,TDLY,V,T0,V,T1); 415 undefined_flag2(c_oflag,F,FDLY,F,F0,F,F1); 416 undefined_flag1(c_oflag,P,AGEOUT); 417 undefined_flag1(c_oflag,W,RAP); 418 419 /* Control modes */ 420 st->c_cflag &= ~SVR4_CBAUD; 421 st->c_cflag |= bsd_to_svr4_speed(bt->c_ospeed, SVR4_CBAUD); 422 bsd_to_svr4_flag4(c_cflag,C,SIZE,C,S5,C,S6,C,S7,C,S8) 423 bsd_to_svr4_flag1(c_cflag,C,STOPB); 424 bsd_to_svr4_flag1(c_cflag,C,READ); 425 bsd_to_svr4_flag1(c_cflag,P,ARENB); 426 bsd_to_svr4_flag1(c_cflag,P,ARODD); 427 bsd_to_svr4_flag1(c_cflag,H,UPCL); 428 bsd_to_svr4_flag1(c_cflag,C,LOCAL); 429 undefined_flag1(c_cflag,R,CV1EN); 430 undefined_flag1(c_cflag,X,MT1EN); 431 undefined_flag1(c_cflag,L,OBLK); 432 undefined_flag1(c_cflag,X,CLUDE); 433 st->c_cflag &= ~SVR4_CIBAUD; 434 st->c_cflag |= bsd_to_svr4_speed(bt->c_ispeed, SVR4_CIBAUD); 435 436 undefined_flag1(c_oflag,P,AREXT); 437 438 /* line discipline modes */ 439 bsd_to_svr4_flag1(c_lflag,I,SIG); 440 bsd_to_svr4_flag1(c_lflag,I,CANON); 441 undefined_flag1(c_lflag,X,CASE); 442 bsd_to_svr4_flag1(c_lflag,E,CHO); 443 bsd_to_svr4_flag1(c_lflag,E,CHOE); 444 bsd_to_svr4_flag1(c_lflag,E,CHOK); 445 bsd_to_svr4_flag1(c_lflag,E,CHONL); 446 bsd_to_svr4_flag1(c_lflag,N,OFLSH); 447 bsd_to_svr4_flag1(c_lflag,T,OSTOP); 448 bsd_to_svr4_flag1(c_lflag,E,CHOCTL); 449 bsd_to_svr4_flag1(c_lflag,E,CHOPRT); 450 bsd_to_svr4_flag1(c_lflag,E,CHOKE); 451 undefined_flag1(c_lflag,D,EFECHO); 452 bsd_to_svr4_flag1(c_lflag,F,LUSHO); 453 bsd_to_svr4_flag1(c_lflag,P,ENDIN); 454 bsd_to_svr4_flag1(c_lflag,I,EXTEN); 455} 456 457 458static void 459svr4_termio_to_termios(t, ts) 460 const struct svr4_termio *t; 461 struct svr4_termios *ts; 462{ 463 int i; 464 465 ts->c_iflag = (svr4_tcflag_t) t->c_iflag; 466 ts->c_oflag = (svr4_tcflag_t) t->c_oflag; 467 ts->c_cflag = (svr4_tcflag_t) t->c_cflag; 468 ts->c_lflag = (svr4_tcflag_t) t->c_lflag; 469 470 for (i = 0; i < SVR4_NCC; i++) 471 ts->c_cc[i] = (svr4_cc_t) t->c_cc[i]; 472} 473 474 475static void 476svr4_termios_to_termio(ts, t) 477 const struct svr4_termios *ts; 478 struct svr4_termio *t; 479{ 480 int i; 481 482 t->c_iflag = (u_short) ts->c_iflag; 483 t->c_oflag = (u_short) ts->c_oflag; 484 t->c_cflag = (u_short) ts->c_cflag; 485 t->c_lflag = (u_short) ts->c_lflag; 486 t->c_line = 0; /* XXX */ 487 488 for (i = 0; i < SVR4_NCC; i++) 489 t->c_cc[i] = (u_char) ts->c_cc[i]; 490} 491 492int 493svr4_term_ioctl(fp, p, retval, fd, cmd, data) 494 struct file *fp; 495 struct proc *p; 496 register_t *retval; 497 int fd; 498 u_long cmd; 499 caddr_t data; 500{ 501 struct termios bt; 502 struct svr4_termios st; 503 struct svr4_termio t; 504 int error, new; 505 int (*ctl) __P((struct file *, u_long, caddr_t, struct proc *)) = 506 fp->f_ops->fo_ioctl; 507 508 *retval = 0; 509 510 DPRINTF(("TERM ioctl %x\n", cmd)); 511 512 switch (cmd) { 513 case SVR4_TCGETA: 514 case SVR4_TCGETS: 515 DPRINTF(("ioctl(TCGET%c);\n", cmd == SVR4_TCGETA ? 'A' : 'S')); 516 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t) &bt, p)) != 0) 517 return error; 518 519 memset(&st, 0, sizeof(st)); 520 bsd_to_svr4_termios(&bt, &st); 521 522#ifdef DEBUG_SVR4 523 print_bsd_termios(&bt); 524 print_svr4_termios(&st); 525#endif /* DEBUG_SVR4 */ 526 527 if (cmd == SVR4_TCGETA) { 528 svr4_termios_to_termio(&st, &t); 529 return copyout(&t, data, sizeof(t)); 530 } 531 else { 532 return copyout(&st, data, sizeof(st)); 533 } 534 535 case SVR4_TCSETA: 536 case SVR4_TCSETS: 537 case SVR4_TCSETAW: 538 case SVR4_TCSETSW: 539 case SVR4_TCSETAF: 540 case SVR4_TCSETSF: 541 DPRINTF(("TCSET{A,S,AW,SW,AF,SF}\n")); 542 /* get full BSD termios so we don't lose information */ 543 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t) &bt, p)) != 0) 544 return error; 545 546 switch (cmd) { 547 case SVR4_TCSETS: 548 case SVR4_TCSETSW: 549 case SVR4_TCSETSF: 550 if ((error = copyin(data, &st, sizeof(st))) != 0) 551 return error; 552 new = 1; 553 break; 554 555 case SVR4_TCSETA: 556 case SVR4_TCSETAW: 557 case SVR4_TCSETAF: 558 if ((error = copyin(data, &t, sizeof(t))) != 0) 559 return error; 560 561 svr4_termio_to_termios(&t, &st); 562 new = 0; 563 break; 564 565 default: 566 return EINVAL; 567 } 568 569 svr4_to_bsd_termios(&st, &bt, new); 570 571 switch (cmd) { 572 case SVR4_TCSETA: 573 case SVR4_TCSETS: 574 DPRINTF(("ioctl(TCSET[A|S]);\n")); 575 cmd = TIOCSETA; 576 break; 577 case SVR4_TCSETAW: 578 case SVR4_TCSETSW: 579 DPRINTF(("ioctl(TCSET[A|S]W);\n")); 580 cmd = TIOCSETAW; 581 break; 582 case SVR4_TCSETAF: 583 case SVR4_TCSETSF: 584 DPRINTF(("ioctl(TCSET[A|S]F);\n")); 585 cmd = TIOCSETAF; 586 break; 587 } 588 589#ifdef DEBUG_SVR4 590 print_bsd_termios(&bt); 591 print_svr4_termios(&st); 592#endif /* DEBUG_SVR4 */ 593 594 return (*ctl)(fp, cmd, (caddr_t) &bt, p); 595 596 case SVR4_TIOCGWINSZ: 597 DPRINTF(("TIOCGWINSZ\n")); 598 { 599 struct svr4_winsize ws; 600 601 error = (*ctl)(fp, TIOCGWINSZ, (caddr_t) &ws, p); 602 if (error) 603 return error; 604 return copyout(&ws, data, sizeof(ws)); 605 } 606 607 case SVR4_TIOCSWINSZ: 608 DPRINTF(("TIOCSWINSZ\n")); 609 { 610 struct svr4_winsize ws; 611 612 if ((error = copyin(data, &ws, sizeof(ws))) != 0) 613 return error; 614 return (*ctl)(fp, TIOCSWINSZ, (caddr_t) &ws, p); 615 } 616 617 default: 618 DPRINTF(("teleport to STREAMS ioctls...\n")); 619 return svr4_stream_ti_ioctl(fp, p, retval, fd, cmd, data); 620 } 621} 622