1 /* 2 * Copyright (c) 1993 Markus Wild. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. The name of the author may not be used to endorse or promote products 11 * derived from this software withough specific prior written permission 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * loosely from: Header: sun_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp 25 * $Id: sunos_ioctl.c,v 1.5 1993/11/22 22:54:48 deraadt Exp $ 26 */ 27 28 #include <sys/param.h> 29 #include <sys/proc.h> 30 #include <sys/file.h> 31 #include <sys/filedesc.h> 32 #include <sys/ioctl.h> 33 #include <sys/termios.h> 34 #include <sys/tty.h> 35 36 /* 37 * SunOS ioctl calls. 38 * This file is something of a hodge-podge. 39 * Support gets added as things turn up.... 40 */ 41 42 struct sun_ttysize { 43 int ts_row; 44 int ts_col; 45 }; 46 47 struct sun_termio { 48 u_short c_iflag; 49 u_short c_oflag; 50 u_short c_cflag; 51 u_short c_lflag; 52 char c_line; 53 unsigned char c_cc[8]; 54 }; 55 #define SUN_TCGETA _IOR('T', 1, struct sun_termio) 56 #define SUN_TCSETA _IOW('T', 2, struct sun_termio) 57 #define SUN_TCSETAW _IOW('T', 3, struct sun_termio) 58 #define SUN_TCSETAF _IOW('T', 4, struct sun_termio) 59 #define SUN_TCSBRK _IO('T', 5) 60 61 struct sun_termios { 62 u_long c_iflag; 63 u_long c_oflag; 64 u_long c_cflag; 65 u_long c_lflag; 66 char c_line; 67 u_char c_cc[17]; 68 }; 69 #define SUN_TCXONC _IO('T', 6) 70 #define SUN_TCFLSH _IO('T', 7) 71 #define SUN_TCGETS _IOR('T', 8, struct sun_termios) 72 #define SUN_TCSETS _IOW('T', 9, struct sun_termios) 73 #define SUN_TCSETSW _IOW('T', 10, struct sun_termios) 74 #define SUN_TCSETSF _IOW('T', 11, struct sun_termios) 75 #define SUN_TCSNDBRK _IO('T', 12) 76 #define SUN_TCDRAIN _IO('T', 13) 77 78 static struct speedtab sptab[] = { 79 { 0, 0 }, 80 { 50, 1 }, 81 { 75, 2 }, 82 { 110, 3 }, 83 { 134, 4 }, 84 { 135, 4 }, 85 { 150, 5 }, 86 { 200, 6 }, 87 { 300, 7 }, 88 { 600, 8 }, 89 { 1200, 9 }, 90 { 1800, 10 }, 91 { 2400, 11 }, 92 { 4800, 12 }, 93 { 9600, 13 }, 94 { 19200, 14 }, 95 { 38400, 15 }, 96 { -1, -1 } 97 }; 98 99 static u_long s2btab[] = { 100 0, 101 50, 102 75, 103 110, 104 134, 105 150, 106 200, 107 300, 108 600, 109 1200, 110 1800, 111 2400, 112 4800, 113 9600, 114 19200, 115 38400, 116 }; 117 118 /* 119 * these two conversion functions have mostly been done 120 * with some perl cut&paste, then handedited to comment 121 * out what doesn't exist under NetBSD. 122 * A note from Markus's code: 123 * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated 124 * optimally by gcc m68k, much better than any ?: stuff. 125 * Code may vary with different architectures of course. 126 * 127 * I don't know what optimizer you used, but seeing divu's and 128 * bfextu's in the m68k assembly output did not encourage me... 129 * as well, gcc on the sparc definately generates much better 130 * code with ?:. 131 */ 132 133 static void 134 stios2btios(st, bt) 135 struct sun_termios *st; 136 struct termios *bt; 137 { 138 register u_long l, r; 139 140 l = st->c_iflag; 141 r = ((l & 0x00000001) ? IGNBRK : 0); 142 r |= ((l & 0x00000002) ? BRKINT : 0); 143 r |= ((l & 0x00000004) ? IGNPAR : 0); 144 r |= ((l & 0x00000008) ? PARMRK : 0); 145 r |= ((l & 0x00000010) ? INPCK : 0); 146 r |= ((l & 0x00000020) ? ISTRIP : 0); 147 r |= ((l & 0x00000040) ? INLCR : 0); 148 r |= ((l & 0x00000080) ? IGNCR : 0); 149 r |= ((l & 0x00000100) ? ICRNL : 0); 150 /* ((l & 0x00000200) ? IUCLC : 0) */ 151 r |= ((l & 0x00000400) ? IXON : 0); 152 r |= ((l & 0x00000800) ? IXANY : 0); 153 r |= ((l & 0x00001000) ? IXOFF : 0); 154 r |= ((l & 0x00002000) ? IMAXBEL : 0); 155 bt->c_iflag = r; 156 157 l = st->c_oflag; 158 r = ((l & 0x00000001) ? OPOST : 0); 159 /* ((l & 0x00000002) ? OLCUC : 0) */ 160 r |= ((l & 0x00000004) ? ONLCR : 0); 161 /* ((l & 0x00000008) ? OCRNL : 0) */ 162 /* ((l & 0x00000010) ? ONOCR : 0) */ 163 /* ((l & 0x00000020) ? ONLRET : 0) */ 164 /* ((l & 0x00000040) ? OFILL : 0) */ 165 /* ((l & 0x00000080) ? OFDEL : 0) */ 166 /* ((l & 0x00000100) ? NLDLY : 0) */ 167 /* ((l & 0x00000100) ? NL1 : 0) */ 168 /* ((l & 0x00000600) ? CRDLY : 0) */ 169 /* ((l & 0x00000200) ? CR1 : 0) */ 170 /* ((l & 0x00000400) ? CR2 : 0) */ 171 /* ((l & 0x00000600) ? CR3 : 0) */ 172 /* ((l & 0x00001800) ? TABDLY : 0) */ 173 /* ((l & 0x00000800) ? TAB1 : 0) */ 174 /* ((l & 0x00001000) ? TAB2 : 0) */ 175 r |= ((l & 0x00001800) ? OXTABS : 0); 176 /* ((l & 0x00002000) ? BSDLY : 0) */ 177 /* ((l & 0x00002000) ? BS1 : 0) */ 178 /* ((l & 0x00004000) ? VTDLY : 0) */ 179 /* ((l & 0x00004000) ? VT1 : 0) */ 180 /* ((l & 0x00008000) ? FFDLY : 0) */ 181 /* ((l & 0x00008000) ? FF1 : 0) */ 182 /* ((l & 0x00010000) ? PAGEOUT : 0) */ 183 /* ((l & 0x00020000) ? WRAP : 0) */ 184 bt->c_oflag = r; 185 186 l = st->c_cflag; 187 r = ((l & 0x00000010) ? CS6 : 0); 188 r |= ((l & 0x00000020) ? CS7 : 0); 189 r |= ((l & 0x00000030) ? CS8 : 0); 190 r |= ((l & 0x00000040) ? CSTOPB : 0); 191 r |= ((l & 0x00000080) ? CREAD : 0); 192 r |= ((l & 0x00000100) ? PARENB : 0); 193 r |= ((l & 0x00000200) ? PARODD : 0); 194 r |= ((l & 0x00000400) ? HUPCL : 0); 195 r |= ((l & 0x00000800) ? CLOCAL : 0); 196 /* ((l & 0x00001000) ? LOBLK : 0) */ 197 r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0); 198 bt->c_cflag = r; 199 200 bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f]; 201 202 l = st->c_lflag; 203 r = ((l & 0x00000001) ? ISIG : 0); 204 r |= ((l & 0x00000002) ? ICANON : 0); 205 /* ((l & 0x00000004) ? XCASE : 0) */ 206 r |= ((l & 0x00000008) ? ECHO : 0); 207 r |= ((l & 0x00000010) ? ECHOE : 0); 208 r |= ((l & 0x00000020) ? ECHOK : 0); 209 r |= ((l & 0x00000040) ? ECHONL : 0); 210 r |= ((l & 0x00000080) ? NOFLSH : 0); 211 r |= ((l & 0x00000100) ? TOSTOP : 0); 212 r |= ((l & 0x00000200) ? ECHOCTL : 0); 213 r |= ((l & 0x00000400) ? ECHOPRT : 0); 214 r |= ((l & 0x00000800) ? ECHOKE : 0); 215 /* ((l & 0x00001000) ? DEFECHO : 0) */ 216 r |= ((l & 0x00002000) ? FLUSHO : 0); 217 r |= ((l & 0x00004000) ? PENDIN : 0); 218 bt->c_lflag = r; 219 220 bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE; 221 bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE; 222 bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE; 223 bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE; 224 bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE; 225 bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE; 226 bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE; 227 /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */ 228 bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE; 229 bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE; 230 bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE; 231 bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE; 232 bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE; 233 bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE; 234 bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE; 235 bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE; 236 bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE; 237 } 238 239 240 static void 241 btios2stios(bt, st) 242 struct termios *bt; 243 struct sun_termios *st; 244 { 245 register u_long l, r; 246 247 l = bt->c_iflag; 248 r = ((l & IGNBRK) ? 0x00000001 : 0); 249 r |= ((l & BRKINT) ? 0x00000002 : 0); 250 r |= ((l & IGNPAR) ? 0x00000004 : 0); 251 r |= ((l & PARMRK) ? 0x00000008 : 0); 252 r |= ((l & INPCK) ? 0x00000010 : 0); 253 r |= ((l & ISTRIP) ? 0x00000020 : 0); 254 r |= ((l & INLCR) ? 0x00000040 : 0); 255 r |= ((l & IGNCR) ? 0x00000080 : 0); 256 r |= ((l & ICRNL) ? 0x00000100 : 0); 257 /* ((l & IUCLC) ? 0x00000200 : 0) */ 258 r |= ((l & IXON) ? 0x00000400 : 0); 259 r |= ((l & IXANY) ? 0x00000800 : 0); 260 r |= ((l & IXOFF) ? 0x00001000 : 0); 261 r |= ((l & IMAXBEL) ? 0x00002000 : 0); 262 st->c_iflag = r; 263 264 l = bt->c_oflag; 265 r = ((l & OPOST) ? 0x00000001 : 0); 266 /* ((l & OLCUC) ? 0x00000002 : 0) */ 267 r |= ((l & ONLCR) ? 0x00000004 : 0); 268 /* ((l & OCRNL) ? 0x00000008 : 0) */ 269 /* ((l & ONOCR) ? 0x00000010 : 0) */ 270 /* ((l & ONLRET) ? 0x00000020 : 0) */ 271 /* ((l & OFILL) ? 0x00000040 : 0) */ 272 /* ((l & OFDEL) ? 0x00000080 : 0) */ 273 /* ((l & NLDLY) ? 0x00000100 : 0) */ 274 /* ((l & NL1) ? 0x00000100 : 0) */ 275 /* ((l & CRDLY) ? 0x00000600 : 0) */ 276 /* ((l & CR1) ? 0x00000200 : 0) */ 277 /* ((l & CR2) ? 0x00000400 : 0) */ 278 /* ((l & CR3) ? 0x00000600 : 0) */ 279 /* ((l & TABDLY) ? 0x00001800 : 0) */ 280 /* ((l & TAB1) ? 0x00000800 : 0) */ 281 /* ((l & TAB2) ? 0x00001000 : 0) */ 282 r |= ((l & OXTABS) ? 0x00001800 : 0); 283 /* ((l & BSDLY) ? 0x00002000 : 0) */ 284 /* ((l & BS1) ? 0x00002000 : 0) */ 285 /* ((l & VTDLY) ? 0x00004000 : 0) */ 286 /* ((l & VT1) ? 0x00004000 : 0) */ 287 /* ((l & FFDLY) ? 0x00008000 : 0) */ 288 /* ((l & FF1) ? 0x00008000 : 0) */ 289 /* ((l & PAGEOUT) ? 0x00010000 : 0) */ 290 /* ((l & WRAP) ? 0x00020000 : 0) */ 291 st->c_oflag = r; 292 293 l = bt->c_cflag; 294 r = ((l & CS6) ? 0x00000010 : 0); 295 r |= ((l & CS7) ? 0x00000020 : 0); 296 r |= ((l & CS8) ? 0x00000030 : 0); 297 r |= ((l & CSTOPB) ? 0x00000040 : 0); 298 r |= ((l & CREAD) ? 0x00000080 : 0); 299 r |= ((l & PARENB) ? 0x00000100 : 0); 300 r |= ((l & PARODD) ? 0x00000200 : 0); 301 r |= ((l & HUPCL) ? 0x00000400 : 0); 302 r |= ((l & CLOCAL) ? 0x00000800 : 0); 303 /* ((l & LOBLK) ? 0x00001000 : 0) */ 304 r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0); 305 st->c_cflag = r; 306 307 l = bt->c_lflag; 308 r = ((l & ISIG) ? 0x00000001 : 0); 309 r |= ((l & ICANON) ? 0x00000002 : 0); 310 /* ((l & XCASE) ? 0x00000004 : 0) */ 311 r |= ((l & ECHO) ? 0x00000008 : 0); 312 r |= ((l & ECHOE) ? 0x00000010 : 0); 313 r |= ((l & ECHOK) ? 0x00000020 : 0); 314 r |= ((l & ECHONL) ? 0x00000040 : 0); 315 r |= ((l & NOFLSH) ? 0x00000080 : 0); 316 r |= ((l & TOSTOP) ? 0x00000100 : 0); 317 r |= ((l & ECHOCTL) ? 0x00000200 : 0); 318 r |= ((l & ECHOPRT) ? 0x00000400 : 0); 319 r |= ((l & ECHOKE) ? 0x00000800 : 0); 320 /* ((l & DEFECHO) ? 0x00001000 : 0) */ 321 r |= ((l & FLUSHO) ? 0x00002000 : 0); 322 r |= ((l & PENDIN) ? 0x00004000 : 0); 323 st->c_lflag = r; 324 325 l = ttspeedtab(bt->c_ospeed, sptab); 326 if (l >= 0) 327 st->c_cflag |= l; 328 329 st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0; 330 st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0; 331 st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0; 332 st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0; 333 st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0; 334 st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0; 335 st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0; 336 st->c_cc[7] = 0; 337 /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */ 338 st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0; 339 st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0; 340 st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0; 341 st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0; 342 st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0; 343 st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0; 344 st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0; 345 st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0; 346 st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0; 347 348 st->c_line = 0; 349 } 350 351 static void 352 stios2stio(ts, t) 353 struct sun_termios *ts; 354 struct sun_termio *t; 355 { 356 t->c_iflag = ts->c_iflag; 357 t->c_oflag = ts->c_oflag; 358 t->c_cflag = ts->c_cflag; 359 t->c_lflag = ts->c_lflag; 360 t->c_line = ts->c_line; 361 bcopy(ts->c_cc, t->c_cc, 8); 362 } 363 364 static void 365 stio2stios(t, ts) 366 struct sun_termio *t; 367 struct sun_termios *ts; 368 { 369 ts->c_iflag = t->c_iflag; 370 ts->c_oflag = t->c_oflag; 371 ts->c_cflag = t->c_cflag; 372 ts->c_lflag = t->c_lflag; 373 ts->c_line = t->c_line; 374 bcopy(t->c_cc, ts->c_cc, 8); /* don't touch the upper fields! */ 375 } 376 377 struct sun_ioctl_args { 378 int fd; 379 int cmd; 380 caddr_t data; 381 }; 382 383 int 384 sun_ioctl(p, uap, retval) 385 register struct proc *p; 386 register struct sun_ioctl_args *uap; 387 int *retval; 388 { 389 register struct filedesc *fdp = p->p_fd; 390 register struct file *fp; 391 register int (*ctl)(); 392 int error; 393 394 if ( (unsigned)uap->fd >= fdp->fd_nfiles || 395 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 396 return EBADF; 397 398 if ((fp->f_flag & (FREAD|FWRITE)) == 0) 399 return EBADF; 400 401 ctl = fp->f_ops->fo_ioctl; 402 403 switch (uap->cmd) { 404 case _IOR('t', 0, int): 405 uap->cmd = TIOCGETD; 406 break; 407 case _IOW('t', 1, int): 408 { 409 int disc; 410 411 if ((error = copyin(uap->data, (caddr_t)&disc, 412 sizeof disc)) != 0) 413 return error; 414 415 /* map SunOS NTTYDISC into our termios discipline */ 416 if (disc == 2) 417 disc = 0; 418 /* all other disciplines are not supported by NetBSD */ 419 if (disc) 420 return ENXIO; 421 422 return (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p); 423 } 424 case _IOW('t', 101, int): /* sun SUN_TIOCSSOFTCAR */ 425 { 426 int x; /* unused */ 427 428 return copyin((caddr_t)&x, uap->data, sizeof x); 429 } 430 case _IOR('t', 100, int): /* sun SUN_TIOCSSOFTCAR */ 431 { 432 int x = 0; 433 434 return copyout((caddr_t)&x, uap->data, sizeof x); 435 } 436 case _IO('t', 36): /* sun TIOCCONS, no parameters */ 437 { 438 int on = 1; 439 return (*ctl)(fp, TIOCCONS, (caddr_t)&on, p); 440 } 441 case _IOW('t', 37, struct sun_ttysize): 442 { 443 struct winsize ws; 444 struct sun_ttysize ss; 445 446 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0) 447 return (error); 448 449 if ((error = copyin (uap->data, &ss, sizeof (ss))) != 0) 450 return error; 451 452 ws.ws_row = ss.ts_row; 453 ws.ws_col = ss.ts_col; 454 455 return ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p)); 456 } 457 case _IOW('t', 38, struct sun_ttysize): 458 { 459 struct winsize ws; 460 struct sun_ttysize ss; 461 462 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0) 463 return (error); 464 465 ss.ts_row = ws.ws_row; 466 ss.ts_col = ws.ws_col; 467 468 return copyout ((caddr_t)&ss, uap->data, sizeof (ss)); 469 } 470 case _IOR('t', 130, int): 471 uap->cmd = TIOCSPGRP; 472 break; 473 case _IOR('t', 131, int): 474 uap->cmd = TIOCGPGRP; 475 break; 476 case _IO('t', 132): 477 uap->cmd = TIOCSCTTY; 478 break; 479 case SUN_TCGETA: 480 case SUN_TCGETS: 481 { 482 struct termios bts; 483 struct sun_termios sts; 484 struct sun_termio st; 485 486 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0) 487 return error; 488 489 btios2stios (&bts, &sts); 490 if (uap->cmd == SUN_TCGETA) { 491 stios2stio (&sts, &st); 492 return copyout((caddr_t)&st, uap->data, sizeof (st)); 493 } else 494 return copyout((caddr_t)&sts, uap->data, sizeof (sts)); 495 /*NOTREACHED*/ 496 } 497 case SUN_TCSETA: 498 case SUN_TCSETAW: 499 case SUN_TCSETAF: 500 { 501 struct termios bts; 502 struct sun_termios sts; 503 struct sun_termio st; 504 505 if ((error = copyin(uap->data, (caddr_t)&st, 506 sizeof (st))) != 0) 507 return error; 508 509 /* get full BSD termios so we don't lose information */ 510 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0) 511 return error; 512 513 /* 514 * convert to sun termios, copy in information from 515 * termio, and convert back, then set new values. 516 */ 517 btios2stios(&bts, &sts); 518 stio2stios(&st, &sts); 519 stios2btios(&sts, &bts); 520 521 return (*ctl)(fp, uap->cmd - SUN_TCSETA + TIOCSETA, 522 (caddr_t)&bts, p); 523 } 524 case SUN_TCSETS: 525 case SUN_TCSETSW: 526 case SUN_TCSETSF: 527 { 528 struct termios bts; 529 struct sun_termios sts; 530 531 if ((error = copyin (uap->data, (caddr_t)&sts, 532 sizeof (sts))) != 0) 533 return error; 534 stios2btios (&sts, &bts); 535 return (*ctl)(fp, uap->cmd - SUN_TCSETS + TIOCSETA, 536 (caddr_t)&bts, p); 537 } 538 } 539 return (ioctl(p, uap, retval)); 540 } 541