Annotation of sys/compat/ultrix/ultrix_ioctl.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ultrix_ioctl.c,v 1.11 2004/09/19 21:34:43 mickey Exp $ */
! 2: /* $NetBSD: ultrix_ioctl.c,v 1.3.4.1 1996/06/13 18:22:37 jonathan Exp $ */
! 3: /* from : NetBSD: sunos_ioctl.c,v 1.21 1995/10/07 06:27:31 mycroft Exp */
! 4:
! 5: /*
! 6: * Copyright (c) 1993 Markus Wild.
! 7: * All rights reserved.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: * 2. 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: * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
! 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/ioctl.h>
! 37: #include <sys/termios.h>
! 38: #include <sys/tty.h>
! 39: #include <sys/socket.h>
! 40: #include <sys/audioio.h>
! 41: #include <net/if.h>
! 42:
! 43: #include <sys/mount.h>
! 44:
! 45: #include <compat/ultrix/ultrix_syscallargs.h>
! 46: #include <sys/syscallargs.h>
! 47:
! 48: #include <compat/sunos/sunos.h>
! 49:
! 50: #include "ultrix_tty.h"
! 51:
! 52: #define emul_termio ultrix_termio
! 53: #define emul_termios ultrix_termios
! 54:
! 55: /*
! 56: * SunOS ioctl calls.
! 57: * This file is something of a hodge-podge.
! 58: * Support gets added as things turn up....
! 59: */
! 60:
! 61: static const struct speedtab sptab[] = {
! 62: { 0, 0 },
! 63: { 50, 1 },
! 64: { 75, 2 },
! 65: { 110, 3 },
! 66: { 134, 4 },
! 67: { 135, 4 },
! 68: { 150, 5 },
! 69: { 200, 6 },
! 70: { 300, 7 },
! 71: { 600, 8 },
! 72: { 1200, 9 },
! 73: { 1800, 10 },
! 74: { 2400, 11 },
! 75: { 4800, 12 },
! 76: { 9600, 13 },
! 77: { 19200, 14 },
! 78: { 38400, 15 },
! 79: { -1, -1 }
! 80: };
! 81:
! 82: static const u_long s2btab[] = {
! 83: 0,
! 84: 50,
! 85: 75,
! 86: 110,
! 87: 134,
! 88: 150,
! 89: 200,
! 90: 300,
! 91: 600,
! 92: 1200,
! 93: 1800,
! 94: 2400,
! 95: 4800,
! 96: 9600,
! 97: 19200,
! 98: 38400,
! 99: };
! 100:
! 101:
! 102: /*
! 103: * Translate a single tty control char from the emulation value
! 104: * to native termios, and vice-versa. Special-case
! 105: * the value of POSIX_VDISABLE, mapping it to and from 0.
! 106: */
! 107: #define NATIVE_TO_EMUL_CC(bsd_cc) \
! 108: (((bsd_cc) != _POSIX_VDISABLE) ? (bsd_cc) : 0)
! 109:
! 110: #define EMUL_TO_NATIVE_CC(emul_cc) \
! 111: (emul_cc) ? (emul_cc) : _POSIX_VDISABLE;
! 112:
! 113:
! 114:
! 115: /*
! 116: * these two conversion functions have mostly been done
! 117: * with some perl cut&paste, then handedited to comment
! 118: * out what doesn't exist under NetBSD.
! 119: * A note from Markus's code:
! 120: * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
! 121: * optimally by gcc m68k, much better than any ?: stuff.
! 122: * Code may vary with different architectures of course.
! 123: *
! 124: * I don't know what optimizer you used, but seeing divu's and
! 125: * bfextu's in the m68k assembly output did not encourage me...
! 126: * as well, gcc on the sparc definately generates much better
! 127: * code with ?:.
! 128: */
! 129:
! 130:
! 131: static void
! 132: stios2btios(st, bt)
! 133: struct emul_termios *st;
! 134: struct termios *bt;
! 135: {
! 136: register u_long l, r;
! 137:
! 138: l = st->c_iflag;
! 139: r = ((l & 0x00000001) ? IGNBRK : 0);
! 140: r |= ((l & 0x00000002) ? BRKINT : 0);
! 141: r |= ((l & 0x00000004) ? IGNPAR : 0);
! 142: r |= ((l & 0x00000008) ? PARMRK : 0);
! 143: r |= ((l & 0x00000010) ? INPCK : 0);
! 144: r |= ((l & 0x00000020) ? ISTRIP : 0);
! 145: r |= ((l & 0x00000040) ? INLCR : 0);
! 146: r |= ((l & 0x00000080) ? IGNCR : 0);
! 147: r |= ((l & 0x00000100) ? ICRNL : 0);
! 148: /* ((l & 0x00000200) ? IUCLC : 0) */
! 149: r |= ((l & 0x00000400) ? IXON : 0);
! 150: r |= ((l & 0x00000800) ? IXANY : 0);
! 151: r |= ((l & 0x00001000) ? IXOFF : 0);
! 152: r |= ((l & 0x00002000) ? IMAXBEL : 0);
! 153: bt->c_iflag = r;
! 154:
! 155: l = st->c_oflag;
! 156: r = ((l & 0x00000001) ? OPOST : 0);
! 157: /* ((l & 0x00000002) ? OLCUC : 0) */
! 158: r |= ((l & 0x00000004) ? ONLCR : 0);
! 159: /* ((l & 0x00000008) ? OCRNL : 0) */
! 160: /* ((l & 0x00000010) ? ONOCR : 0) */
! 161: /* ((l & 0x00000020) ? ONLRET : 0) */
! 162: /* ((l & 0x00000040) ? OFILL : 0) */
! 163: /* ((l & 0x00000080) ? OFDEL : 0) */
! 164: /* ((l & 0x00000100) ? NLDLY : 0) */
! 165: /* ((l & 0x00000100) ? NL1 : 0) */
! 166: /* ((l & 0x00000600) ? CRDLY : 0) */
! 167: /* ((l & 0x00000200) ? CR1 : 0) */
! 168: /* ((l & 0x00000400) ? CR2 : 0) */
! 169: /* ((l & 0x00000600) ? CR3 : 0) */
! 170: /* ((l & 0x00001800) ? TABDLY : 0) */
! 171: /* ((l & 0x00000800) ? TAB1 : 0) */
! 172: /* ((l & 0x00001000) ? TAB2 : 0) */
! 173: r |= ((l & 0x00001800) ? OXTABS : 0);
! 174: /* ((l & 0x00002000) ? BSDLY : 0) */
! 175: /* ((l & 0x00002000) ? BS1 : 0) */
! 176: /* ((l & 0x00004000) ? VTDLY : 0) */
! 177: /* ((l & 0x00004000) ? VT1 : 0) */
! 178: /* ((l & 0x00008000) ? FFDLY : 0) */
! 179: /* ((l & 0x00008000) ? FF1 : 0) */
! 180: /* ((l & 0x00010000) ? PAGEOUT : 0) */
! 181: /* ((l & 0x00020000) ? WRAP : 0) */
! 182: bt->c_oflag = r;
! 183:
! 184: l = st->c_cflag;
! 185: switch (l & 0x00000030) {
! 186: case 0:
! 187: r = CS5;
! 188: break;
! 189: case 0x00000010:
! 190: r = CS6;
! 191: break;
! 192: case 0x00000020:
! 193: r = CS7;
! 194: break;
! 195: case 0x00000030:
! 196: r = CS8;
! 197: break;
! 198: }
! 199: r |= ((l & 0x00000040) ? CSTOPB : 0);
! 200: r |= ((l & 0x00000080) ? CREAD : 0);
! 201: r |= ((l & 0x00000100) ? PARENB : 0);
! 202: r |= ((l & 0x00000200) ? PARODD : 0);
! 203: r |= ((l & 0x00000400) ? HUPCL : 0);
! 204: r |= ((l & 0x00000800) ? CLOCAL : 0);
! 205: /* ((l & 0x00001000) ? LOBLK : 0) */
! 206: r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
! 207: bt->c_cflag = r;
! 208:
! 209: bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
! 210:
! 211: l = st->c_lflag;
! 212: r = ((l & 0x00000001) ? ISIG : 0);
! 213: r |= ((l & 0x00000002) ? ICANON : 0);
! 214: /* ((l & 0x00000004) ? XCASE : 0) */
! 215: r |= ((l & 0x00000008) ? ECHO : 0);
! 216: r |= ((l & 0x00000010) ? ECHOE : 0);
! 217: r |= ((l & 0x00000020) ? ECHOK : 0);
! 218: r |= ((l & 0x00000040) ? ECHONL : 0);
! 219: r |= ((l & 0x00000080) ? NOFLSH : 0);
! 220: r |= ((l & 0x00000100) ? TOSTOP : 0);
! 221: r |= ((l & 0x00000200) ? ECHOCTL : 0);
! 222: r |= ((l & 0x00000400) ? ECHOPRT : 0);
! 223: r |= ((l & 0x00000800) ? ECHOKE : 0);
! 224: /* ((l & 0x00001000) ? DEFECHO : 0) */
! 225: r |= ((l & 0x00002000) ? FLUSHO : 0);
! 226: r |= ((l & 0x00004000) ? PENDIN : 0);
! 227: bt->c_lflag = r;
! 228:
! 229: bt->c_cc[VINTR] = EMUL_TO_NATIVE_CC(st->c_cc[0]);
! 230: bt->c_cc[VQUIT] = EMUL_TO_NATIVE_CC(st->c_cc[1]);
! 231: bt->c_cc[VERASE] = EMUL_TO_NATIVE_CC(st->c_cc[2]);
! 232: bt->c_cc[VKILL] = EMUL_TO_NATIVE_CC(st->c_cc[3]);
! 233: bt->c_cc[VEOF] = EMUL_TO_NATIVE_CC(st->c_cc[4]);
! 234: bt->c_cc[VEOL] = EMUL_TO_NATIVE_CC(st->c_cc[5]);
! 235: bt->c_cc[VEOL2] = EMUL_TO_NATIVE_CC(st->c_cc[6]);
! 236: /* not present on NetBSD */
! 237: /* bt->c_cc[VSWTCH] = EMUL_TO_NATIVE_CC(st->c_cc[7]); */
! 238: bt->c_cc[VSTART] = EMUL_TO_NATIVE_CC(st->c_cc[10]);
! 239: bt->c_cc[VSTOP] = EMUL_TO_NATIVE_CC(st->c_cc[11]);
! 240: bt->c_cc[VSUSP] = EMUL_TO_NATIVE_CC(st->c_cc[12]);
! 241: bt->c_cc[VDSUSP] = EMUL_TO_NATIVE_CC(st->c_cc[13]);
! 242: bt->c_cc[VREPRINT] = EMUL_TO_NATIVE_CC(st->c_cc[14]);
! 243: bt->c_cc[VDISCARD] = EMUL_TO_NATIVE_CC(st->c_cc[15]);
! 244: bt->c_cc[VWERASE] = EMUL_TO_NATIVE_CC(st->c_cc[16]);
! 245: bt->c_cc[VLNEXT] = EMUL_TO_NATIVE_CC(st->c_cc[17]);
! 246: bt->c_cc[VSTATUS] = EMUL_TO_NATIVE_CC(st->c_cc[18]);
! 247:
! 248: #ifdef COMPAT_ULTRIX
! 249: /* Ultrix termio/termios has real vmin/vtime */
! 250: bt->c_cc[VMIN] = EMUL_TO_NATIVE_CC(st->c_cc[8]);
! 251: bt->c_cc[VTIME] = EMUL_TO_NATIVE_CC(st->c_cc[9]);
! 252: #else
! 253: /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
! 254: bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
! 255: bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
! 256: #endif
! 257:
! 258: }
! 259:
! 260: /*
! 261: * Convert bsd termios to "sunos" emulated termios
! 262: */
! 263: static void
! 264: btios2stios(bt, st)
! 265: struct termios *bt;
! 266: struct emul_termios *st;
! 267: {
! 268: register u_long l, r;
! 269:
! 270: l = bt->c_iflag;
! 271: r = ((l & IGNBRK) ? 0x00000001 : 0);
! 272: r |= ((l & BRKINT) ? 0x00000002 : 0);
! 273: r |= ((l & IGNPAR) ? 0x00000004 : 0);
! 274: r |= ((l & PARMRK) ? 0x00000008 : 0);
! 275: r |= ((l & INPCK) ? 0x00000010 : 0);
! 276: r |= ((l & ISTRIP) ? 0x00000020 : 0);
! 277: r |= ((l & INLCR) ? 0x00000040 : 0);
! 278: r |= ((l & IGNCR) ? 0x00000080 : 0);
! 279: r |= ((l & ICRNL) ? 0x00000100 : 0);
! 280: /* ((l & IUCLC) ? 0x00000200 : 0) */
! 281: r |= ((l & IXON) ? 0x00000400 : 0);
! 282: r |= ((l & IXANY) ? 0x00000800 : 0);
! 283: r |= ((l & IXOFF) ? 0x00001000 : 0);
! 284: r |= ((l & IMAXBEL) ? 0x00002000 : 0);
! 285: st->c_iflag = r;
! 286:
! 287: l = bt->c_oflag;
! 288: r = ((l & OPOST) ? 0x00000001 : 0);
! 289: /* ((l & OLCUC) ? 0x00000002 : 0) */
! 290: r |= ((l & ONLCR) ? 0x00000004 : 0);
! 291: /* ((l & OCRNL) ? 0x00000008 : 0) */
! 292: /* ((l & ONOCR) ? 0x00000010 : 0) */
! 293: /* ((l & ONLRET) ? 0x00000020 : 0) */
! 294: /* ((l & OFILL) ? 0x00000040 : 0) */
! 295: /* ((l & OFDEL) ? 0x00000080 : 0) */
! 296: /* ((l & NLDLY) ? 0x00000100 : 0) */
! 297: /* ((l & NL1) ? 0x00000100 : 0) */
! 298: /* ((l & CRDLY) ? 0x00000600 : 0) */
! 299: /* ((l & CR1) ? 0x00000200 : 0) */
! 300: /* ((l & CR2) ? 0x00000400 : 0) */
! 301: /* ((l & CR3) ? 0x00000600 : 0) */
! 302: /* ((l & TABDLY) ? 0x00001800 : 0) */
! 303: /* ((l & TAB1) ? 0x00000800 : 0) */
! 304: /* ((l & TAB2) ? 0x00001000 : 0) */
! 305: r |= ((l & OXTABS) ? 0x00001800 : 0);
! 306: /* ((l & BSDLY) ? 0x00002000 : 0) */
! 307: /* ((l & BS1) ? 0x00002000 : 0) */
! 308: /* ((l & VTDLY) ? 0x00004000 : 0) */
! 309: /* ((l & VT1) ? 0x00004000 : 0) */
! 310: /* ((l & FFDLY) ? 0x00008000 : 0) */
! 311: /* ((l & FF1) ? 0x00008000 : 0) */
! 312: /* ((l & PAGEOUT) ? 0x00010000 : 0) */
! 313: /* ((l & WRAP) ? 0x00020000 : 0) */
! 314: st->c_oflag = r;
! 315:
! 316: l = bt->c_cflag;
! 317: switch (l & CSIZE) {
! 318: case CS5:
! 319: r = 0;
! 320: break;
! 321: case CS6:
! 322: r = 0x00000010;
! 323: break;
! 324: case CS7:
! 325: r = 0x00000020;
! 326: break;
! 327: case CS8:
! 328: r = 0x00000030;
! 329: break;
! 330: }
! 331: r |= ((l & CSTOPB) ? 0x00000040 : 0);
! 332: r |= ((l & CREAD) ? 0x00000080 : 0);
! 333: r |= ((l & PARENB) ? 0x00000100 : 0);
! 334: r |= ((l & PARODD) ? 0x00000200 : 0);
! 335: r |= ((l & HUPCL) ? 0x00000400 : 0);
! 336: r |= ((l & CLOCAL) ? 0x00000800 : 0);
! 337: /* ((l & LOBLK) ? 0x00001000 : 0) */
! 338: r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
! 339: st->c_cflag = r;
! 340:
! 341: l = bt->c_lflag;
! 342: r = ((l & ISIG) ? 0x00000001 : 0);
! 343: r |= ((l & ICANON) ? 0x00000002 : 0);
! 344: /* ((l & XCASE) ? 0x00000004 : 0) */
! 345: r |= ((l & ECHO) ? 0x00000008 : 0);
! 346: r |= ((l & ECHOE) ? 0x00000010 : 0);
! 347: r |= ((l & ECHOK) ? 0x00000020 : 0);
! 348: r |= ((l & ECHONL) ? 0x00000040 : 0);
! 349: r |= ((l & NOFLSH) ? 0x00000080 : 0);
! 350: r |= ((l & TOSTOP) ? 0x00000100 : 0);
! 351: r |= ((l & ECHOCTL) ? 0x00000200 : 0);
! 352: r |= ((l & ECHOPRT) ? 0x00000400 : 0);
! 353: r |= ((l & ECHOKE) ? 0x00000800 : 0);
! 354: /* ((l & DEFECHO) ? 0x00001000 : 0) */
! 355: r |= ((l & FLUSHO) ? 0x00002000 : 0);
! 356: r |= ((l & PENDIN) ? 0x00004000 : 0);
! 357: st->c_lflag = r;
! 358:
! 359: l = ttspeedtab(bt->c_ospeed, sptab);
! 360: if (l >= 0)
! 361: st->c_cflag |= l;
! 362:
! 363: st->c_cc[0] = NATIVE_TO_EMUL_CC(bt->c_cc[VINTR]);
! 364: st->c_cc[1] = NATIVE_TO_EMUL_CC(bt->c_cc[VQUIT]);
! 365: st->c_cc[2] = NATIVE_TO_EMUL_CC(bt->c_cc[VERASE]);
! 366: st->c_cc[3] = NATIVE_TO_EMUL_CC(bt->c_cc[VKILL]);
! 367: st->c_cc[4] = NATIVE_TO_EMUL_CC(bt->c_cc[VEOF]);
! 368: st->c_cc[5] = NATIVE_TO_EMUL_CC(bt->c_cc[VEOL]);
! 369: st->c_cc[6] = NATIVE_TO_EMUL_CC(bt->c_cc[VEOL2]);
! 370: /* XXX - the next line was an ifdef instead of an ifndef - but i still
! 371: have to find out what to do here
! 372: */
! 373: #ifndef COMPAT_ULTRIX
! 374: st->c_cc[7] = NATIVE_TO_EMUL_CC(bt->c_cc[VSWTCH]);
! 375: #else
! 376: st->c_cc[7] = 0;
! 377: #endif
! 378: st->c_cc[10] = NATIVE_TO_EMUL_CC(bt->c_cc[VSTART]);
! 379: st->c_cc[11] = NATIVE_TO_EMUL_CC(bt->c_cc[VSTOP]);
! 380: st->c_cc[12]= NATIVE_TO_EMUL_CC(bt->c_cc[VSUSP]);
! 381: st->c_cc[13]= NATIVE_TO_EMUL_CC(bt->c_cc[VDSUSP]);
! 382: st->c_cc[14]= NATIVE_TO_EMUL_CC(bt->c_cc[VREPRINT]);
! 383: st->c_cc[15]= NATIVE_TO_EMUL_CC(bt->c_cc[VDISCARD]);
! 384: st->c_cc[16]= NATIVE_TO_EMUL_CC(bt->c_cc[VWERASE]);
! 385: st->c_cc[17]= NATIVE_TO_EMUL_CC(bt->c_cc[VLNEXT]);
! 386: st->c_cc[18]= NATIVE_TO_EMUL_CC(bt->c_cc[VSTATUS]);
! 387:
! 388: #ifdef COMPAT_ULTRIX
! 389: st->c_cc[8]= NATIVE_TO_EMUL_CC(bt->c_cc[VMIN]);
! 390: st->c_cc[9]= NATIVE_TO_EMUL_CC(bt->c_cc[VTIME]);
! 391: #else
! 392: if (!(bt->c_lflag & ICANON)) {
! 393: /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
! 394: st->c_cc[4] = bt->c_cc[VMIN];
! 395: st->c_cc[5] = bt->c_cc[VTIME];
! 396: }
! 397: #endif
! 398:
! 399: #ifdef COMPAT_SUNOS
! 400: st->c_line = 0; /* 4.3bsd "old" line discipline */
! 401: #else
! 402: st->c_line = 2; /* 4.3bsd "new" line discipline */
! 403: #endif
! 404: }
! 405:
! 406: #define TERMIO_NCC 10 /* ultrix termio NCC is 10 */
! 407:
! 408: /*
! 409: * Convert emulated struct termios to termio(?)
! 410: */
! 411: static void
! 412: stios2stio(ts, t)
! 413: struct emul_termios *ts;
! 414: struct emul_termio *t;
! 415: {
! 416: t->c_iflag = ts->c_iflag;
! 417: t->c_oflag = ts->c_oflag;
! 418: t->c_cflag = ts->c_cflag;
! 419: t->c_lflag = ts->c_lflag;
! 420: t->c_line = ts->c_line;
! 421: bcopy(ts->c_cc, t->c_cc, TERMIO_NCC);
! 422: }
! 423:
! 424: /*
! 425: * Convert the other way
! 426: */
! 427: static void
! 428: stio2stios(t, ts)
! 429: struct emul_termio *t;
! 430: struct emul_termios *ts;
! 431: {
! 432: ts->c_iflag = t->c_iflag;
! 433: ts->c_oflag = t->c_oflag;
! 434: ts->c_cflag = t->c_cflag;
! 435: ts->c_lflag = t->c_lflag;
! 436: ts->c_line = t->c_line;
! 437: bcopy(t->c_cc, ts->c_cc, TERMIO_NCC); /* don't touch the upper fields! */
! 438: }
! 439:
! 440: int
! 441: ultrix_sys_ioctl(p, v, retval)
! 442: register struct proc *p;
! 443: void *v;
! 444: register_t *retval;
! 445: {
! 446: struct ultrix_sys_ioctl_args *uap = v;
! 447: struct filedesc *fdp = p->p_fd;
! 448: struct file *fp;
! 449: register int (*ctl)();
! 450: int error;
! 451:
! 452: if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
! 453: return EBADF;
! 454: FREF(fp);
! 455:
! 456: if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
! 457: error = EBADF;
! 458: goto out;
! 459: }
! 460:
! 461: ctl = fp->f_ops->fo_ioctl;
! 462:
! 463: switch (SCARG(uap, com)) {
! 464: case _IOR('t', 0, int):
! 465: SCARG(uap, com) = TIOCGETD;
! 466: break;
! 467: case _IOW('t', 1, int):
! 468: {
! 469: int disc;
! 470:
! 471: if ((error = copyin(SCARG(uap, data), (caddr_t)&disc,
! 472: sizeof disc)) != 0)
! 473: goto out;
! 474:
! 475: /* map SunOS NTTYDISC into our termios discipline */
! 476: if (disc == 2)
! 477: disc = 0;
! 478: /* all other disciplines are not supported by NetBSD */
! 479: if (disc) {
! 480: error = ENXIO;
! 481: goto out;
! 482: }
! 483:
! 484: error = (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p);
! 485: goto out;
! 486: }
! 487: case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */
! 488: {
! 489: int x; /* unused */
! 490:
! 491: error = copyin((caddr_t)&x, SCARG(uap, data), sizeof x);
! 492: goto out;
! 493: }
! 494: case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */
! 495: {
! 496: int x = 0;
! 497:
! 498: error = copyout((caddr_t)&x, SCARG(uap, data), sizeof x);
! 499: goto out;
! 500: }
! 501: case _IO('t', 36): /* sun TIOCCONS, no parameters */
! 502: {
! 503: int on = 1;
! 504: error = (*ctl)(fp, TIOCCONS, (caddr_t)&on, p);
! 505: goto out;
! 506: }
! 507: case _IOW('t', 37, struct sunos_ttysize):
! 508: {
! 509: struct winsize ws;
! 510: struct sunos_ttysize ss;
! 511:
! 512: if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
! 513: goto out;
! 514:
! 515: if ((error = copyin (SCARG(uap, data), &ss, sizeof (ss))) != 0)
! 516: goto out;
! 517:
! 518: ws.ws_row = ss.ts_row;
! 519: ws.ws_col = ss.ts_col;
! 520:
! 521: error = ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p));
! 522: goto out;
! 523: }
! 524: case _IOW('t', 38, struct sunos_ttysize):
! 525: {
! 526: struct winsize ws;
! 527: struct sunos_ttysize ss;
! 528:
! 529: if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
! 530: goto out;
! 531:
! 532: ss.ts_row = ws.ws_row;
! 533: ss.ts_col = ws.ws_col;
! 534:
! 535: error = copyout ((caddr_t)&ss, SCARG(uap, data), sizeof (ss));
! 536: goto out;
! 537: }
! 538: case _IOW('t', 130, int):
! 539: SCARG(uap, com) = TIOCSPGRP;
! 540: break;
! 541: case _IOR('t', 131, int):
! 542: SCARG(uap, com) = TIOCGPGRP;
! 543: break;
! 544: case _IO('t', 132):
! 545: SCARG(uap, com) = TIOCSCTTY;
! 546: break;
! 547: /* Emulate termio or termios tcget() */
! 548: case ULTRIX_TCGETA:
! 549: case ULTRIX_TCGETS:
! 550: {
! 551: struct termios bts;
! 552: struct ultrix_termios sts;
! 553: struct ultrix_termio st;
! 554:
! 555: if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
! 556: goto out;
! 557:
! 558: btios2stios (&bts, &sts);
! 559: if (SCARG(uap, com) == ULTRIX_TCGETA) {
! 560: stios2stio (&sts, &st);
! 561: error = copyout((caddr_t)&st, SCARG(uap, data),
! 562: sizeof (st));
! 563: goto out;
! 564: } else {
! 565: error = copyout((caddr_t)&sts, SCARG(uap, data),
! 566: sizeof (sts));
! 567: goto out;
! 568: }
! 569: /*NOTREACHED*/
! 570: }
! 571: /* Emulate termio tcset() */
! 572: case ULTRIX_TCSETA:
! 573: case ULTRIX_TCSETAW:
! 574: case ULTRIX_TCSETAF:
! 575: {
! 576: struct termios bts;
! 577: struct ultrix_termios sts;
! 578: struct ultrix_termio st;
! 579:
! 580: if ((error = copyin(SCARG(uap, data), (caddr_t)&st,
! 581: sizeof (st))) != 0)
! 582: goto out;
! 583:
! 584: /* get full BSD termios so we don't lose information */
! 585: if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
! 586: goto out;
! 587:
! 588: /*
! 589: * convert to sun termios, copy in information from
! 590: * termio, and convert back, then set new values.
! 591: */
! 592: btios2stios(&bts, &sts);
! 593: stio2stios(&st, &sts);
! 594: stios2btios(&sts, &bts);
! 595:
! 596: /*
! 597: * map ioctl code: ultrix tcsets are numbered in reverse order
! 598: */
! 599: error = (*ctl)(fp, ULTRIX_TCSETA - SCARG(uap, com) + TIOCSETA,
! 600: (caddr_t)&bts, p);
! 601: printf("ultrix TCSETA %lx returns %d\n",
! 602: ULTRIX_TCSETA - SCARG(uap, com), error);
! 603: goto out;
! 604: }
! 605: /* Emulate termios tcset() */
! 606: case ULTRIX_TCSETS:
! 607: case ULTRIX_TCSETSW:
! 608: case ULTRIX_TCSETSF:
! 609: {
! 610: struct termios bts;
! 611: struct ultrix_termios sts;
! 612:
! 613: if ((error = copyin (SCARG(uap, data), (caddr_t)&sts,
! 614: sizeof (sts))) != 0)
! 615: goto out;
! 616: stios2btios (&sts, &bts);
! 617: error = (*ctl)(fp, ULTRIX_TCSETS - SCARG(uap, com) + TIOCSETA,
! 618: (caddr_t)&bts, p);
! 619: goto out;
! 620: }
! 621: /*
! 622: * Pseudo-tty ioctl translations.
! 623: */
! 624: case _IOW('t', 32, int): { /* TIOCTCNTL */
! 625: int error, on;
! 626:
! 627: error = copyin (SCARG(uap, data), (caddr_t)&on, sizeof (on));
! 628: if (error != 0)
! 629: goto out;
! 630: error = (*ctl)(fp, TIOCUCNTL, (caddr_t)&on, p);
! 631: goto out;
! 632: }
! 633: case _IOW('t', 33, int): { /* TIOCSIGNAL */
! 634: int error, sig;
! 635:
! 636: error = copyin (SCARG(uap, data), (caddr_t)&sig, sizeof (sig));
! 637: if (error != 0)
! 638: goto out;
! 639: error = (*ctl)(fp, TIOCSIG, (caddr_t)&sig, p);
! 640: goto out;
! 641: }
! 642:
! 643: /*
! 644: * Socket ioctl translations.
! 645: */
! 646: #define IN_TYPE(a, type_t) { \
! 647: type_t localbuf; \
! 648: if ((error = copyin (SCARG(uap, data), \
! 649: (caddr_t)&localbuf, sizeof (type_t))) != 0) \
! 650: goto out; \
! 651: error = (*ctl)(fp, a, (caddr_t)&localbuf, p); \
! 652: goto out; \
! 653: }
! 654:
! 655: #define INOUT_TYPE(a, type_t) { \
! 656: type_t localbuf; \
! 657: if ((error = copyin (SCARG(uap, data), (caddr_t)&localbuf, \
! 658: sizeof (type_t))) != 0) \
! 659: goto out; \
! 660: if ((error = (*ctl)(fp, a, (caddr_t)&localbuf, p)) != 0) \
! 661: goto out; \
! 662: error = copyout ((caddr_t)&localbuf, SCARG(uap, data), sizeof (type_t)); \
! 663: goto out; \
! 664: }
! 665:
! 666:
! 667: #define IFREQ_IN(a) { \
! 668: struct ifreq ifreq; \
! 669: if ((error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq))) != 0) \
! 670: goto out; \
! 671: error = (*ctl)(fp, a, (caddr_t)&ifreq, p); \
! 672: goto out; \
! 673: }
! 674:
! 675: #define IFREQ_INOUT(a) { \
! 676: struct ifreq ifreq; \
! 677: if ((error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq))) != 0) \
! 678: goto out; \
! 679: if ((error = (*ctl)(fp, a, (caddr_t)&ifreq, p)) != 0) \
! 680: goto out; \
! 681: error = copyout ((caddr_t)&ifreq, SCARG(uap, data), sizeof (ifreq)); \
! 682: goto out; \
! 683: }
! 684:
! 685: case _IOW('i', 12, struct ifreq):
! 686: /* SIOCSIFADDR */
! 687: break;
! 688:
! 689: case _IOWR('i', 13, struct ifreq):
! 690: IFREQ_INOUT(OSIOCGIFADDR);
! 691:
! 692: case _IOW('i', 14, struct ifreq):
! 693: /* SIOCSIFDSTADDR */
! 694: break;
! 695:
! 696: case _IOWR('i', 15, struct ifreq):
! 697: IFREQ_INOUT(OSIOCGIFDSTADDR);
! 698:
! 699: case _IOW('i', 16, struct ifreq):
! 700: /* SIOCSIFFLAGS */
! 701: break;
! 702:
! 703: case _IOWR('i', 17, struct ifreq):
! 704: /* SIOCGIFFLAGS */
! 705: break;
! 706:
! 707: case _IOW('i', 21, struct ifreq):
! 708: IFREQ_IN(SIOCSIFMTU);
! 709:
! 710: case _IOWR('i', 22, struct ifreq):
! 711: IFREQ_INOUT(SIOCGIFMTU);
! 712:
! 713: case _IOWR('i', 23, struct ifreq):
! 714: IFREQ_INOUT(SIOCGIFBRDADDR);
! 715:
! 716: case _IOW('i', 24, struct ifreq):
! 717: IFREQ_IN(SIOCSIFBRDADDR);
! 718:
! 719: case _IOWR('i', 25, struct ifreq):
! 720: IFREQ_INOUT(OSIOCGIFNETMASK);
! 721:
! 722: case _IOW('i', 26, struct ifreq):
! 723: IFREQ_IN(SIOCSIFNETMASK);
! 724:
! 725: case _IOWR('i', 27, struct ifreq):
! 726: IFREQ_INOUT(SIOCGIFMETRIC);
! 727:
! 728: case _IOWR('i', 28, struct ifreq):
! 729: IFREQ_IN(SIOCSIFMETRIC);
! 730:
! 731: case _IOW('i', 30, struct arpreq):
! 732: /* SIOCSARP */
! 733: break;
! 734:
! 735: case _IOWR('i', 31, struct arpreq):
! 736: /* SIOCGARP */
! 737: break;
! 738:
! 739: case _IOW('i', 32, struct arpreq):
! 740: /* SIOCDARP */
! 741: break;
! 742:
! 743: case _IOW('i', 18, struct ifreq): /* SIOCSIFMEM */
! 744: case _IOWR('i', 19, struct ifreq): /* SIOCGIFMEM */
! 745: case _IOW('i', 40, struct ifreq): /* SIOCUPPER */
! 746: case _IOW('i', 41, struct ifreq): /* SIOCLOWER */
! 747: case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */
! 748: case _IOWR('i', 45, struct ifreq): /* SIOCGETSYNC */
! 749: case _IOWR('i', 46, struct ifreq): /* SIOCSDSTATS */
! 750: case _IOWR('i', 47, struct ifreq): /* SIOCSESTATS */
! 751: case _IOW('i', 48, int): /* SIOCSPROMISC */
! 752: case _IOW('i', 49, struct ifreq): /* SIOCADDMULTI */
! 753: case _IOW('i', 50, struct ifreq): /* SIOCDELMULTI */
! 754: error = EOPNOTSUPP;
! 755: goto out;
! 756:
! 757: case _IOWR('i', 20, struct ifconf): /* SIOCGIFCONF */
! 758: {
! 759: struct ifconf ifconf;
! 760:
! 761: /*
! 762: * XXX: two more problems
! 763: * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
! 764: * 2. this returns a name per protocol, ie. it returns two "lo0"'s
! 765: */
! 766: if ((error = copyin (SCARG(uap, data), (caddr_t)&ifconf,
! 767: sizeof (ifconf))) != 0)
! 768: goto out;
! 769: if ((error = (*ctl)(fp, OSIOCGIFCONF,
! 770: * (caddr_t)&ifconf, p)) !=0 )
! 771: goto out;
! 772: error = copyout ((caddr_t)&ifconf, SCARG(uap, data),
! 773: sizeof (ifconf));
! 774: goto out;
! 775: }
! 776:
! 777: }
! 778: error = (sys_ioctl(p, uap, retval));
! 779:
! 780: out:
! 781: FRELE(fp);
! 782: return (error);
! 783: }
CVSweb