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