1 /* $NetBSD: sunos32_ioctl.c,v 1.6 2001/06/14 20:32:45 thorpej Exp $ */ 2 /* from: NetBSD: sunos_ioctl.c,v 1.35 2001/02/03 22:20:02 mrg Exp */ 3 4 /* 5 * Copyright (c) 2001 Matthew R. Green 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1993 Markus Wild. 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. The name of the author may not be used to endorse or promote products 42 * derived from this software without specific prior written permission 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 48 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 49 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 53 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 * 55 * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp 56 */ 57 58 #if defined(_KERNEL_OPT) 59 #include "opt_compat_netbsd32.h" 60 #include "opt_execfmt.h" 61 #endif 62 63 #include <sys/param.h> 64 #include <sys/proc.h> 65 #include <sys/systm.h> 66 #include <sys/file.h> 67 #include <sys/filedesc.h> 68 #include <sys/ioctl.h> 69 #include <sys/termios.h> 70 #include <sys/tty.h> 71 #include <sys/socket.h> 72 #include <sys/audioio.h> 73 #include <sys/vnode.h> 74 #include <sys/mount.h> 75 #include <sys/disklabel.h> 76 #include <sys/syscallargs.h> 77 78 #include <miscfs/specfs/specdev.h> 79 80 #include <net/if.h> 81 82 #include <dev/sun/disklabel.h> 83 84 #include <compat/sunos/sunos.h> 85 #include <compat/sunos/sunos_syscallargs.h> 86 #include <compat/netbsd32/netbsd32.h> 87 #include <compat/netbsd32/netbsd32_syscallargs.h> 88 #include <compat/sunos32/sunos32.h> 89 #include <compat/sunos32/sunos32_syscallargs.h> 90 #include <compat/common/compat_util.h> 91 92 /* 93 * SunOS ioctl calls. 94 * This file is something of a hodge-podge. 95 * Support gets added as things turn up.... 96 */ 97 98 static struct speedtab sptab[] = { 99 { 0, 0 }, 100 { 50, 1 }, 101 { 75, 2 }, 102 { 110, 3 }, 103 { 134, 4 }, 104 { 135, 4 }, 105 { 150, 5 }, 106 { 200, 6 }, 107 { 300, 7 }, 108 { 600, 8 }, 109 { 1200, 9 }, 110 { 1800, 10 }, 111 { 2400, 11 }, 112 { 4800, 12 }, 113 { 9600, 13 }, 114 { 19200, 14 }, 115 { 38400, 15 }, 116 { -1, -1 } 117 }; 118 119 static netbsd32_u_long s2btab[] = { 120 0, 121 50, 122 75, 123 110, 124 134, 125 150, 126 200, 127 300, 128 600, 129 1200, 130 1800, 131 2400, 132 4800, 133 9600, 134 19200, 135 38400, 136 }; 137 138 static void stios2btios __P((struct sunos_termios *, struct termios *)); 139 static void btios2stios __P((struct termios *, struct sunos_termios *)); 140 static void stios2stio __P((struct sunos_termios *, struct sunos_termio *)); 141 static void stio2stios __P((struct sunos_termio *, struct sunos_termios *)); 142 143 /* 144 * These two conversion functions have mostly been done 145 * with some perl cut&paste, then hand-edited to comment 146 * out what doesn't exist under NetBSD. 147 * A note from Markus's code: 148 * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated 149 * optimally by gcc m68k, much better than any ?: stuff. 150 * Code may vary with different architectures of course. 151 * 152 * I don't know what optimizer you used, but seeing divu's and 153 * bfextu's in the m68k assembly output did not encourage me... 154 * as well, gcc on the sparc definitely generates much better 155 * code with `?:'. 156 */ 157 158 static void 159 stios2btios(st, bt) 160 struct sunos_termios *st; 161 struct termios *bt; 162 { 163 netbsd32_u_long l, r; 164 165 l = st->c_iflag; 166 r = ((l & 0x00000001) ? IGNBRK : 0); 167 r |= ((l & 0x00000002) ? BRKINT : 0); 168 r |= ((l & 0x00000004) ? IGNPAR : 0); 169 r |= ((l & 0x00000008) ? PARMRK : 0); 170 r |= ((l & 0x00000010) ? INPCK : 0); 171 r |= ((l & 0x00000020) ? ISTRIP : 0); 172 r |= ((l & 0x00000040) ? INLCR : 0); 173 r |= ((l & 0x00000080) ? IGNCR : 0); 174 r |= ((l & 0x00000100) ? ICRNL : 0); 175 /* ((l & 0x00000200) ? IUCLC : 0) */ 176 r |= ((l & 0x00000400) ? IXON : 0); 177 r |= ((l & 0x00000800) ? IXANY : 0); 178 r |= ((l & 0x00001000) ? IXOFF : 0); 179 r |= ((l & 0x00002000) ? IMAXBEL : 0); 180 bt->c_iflag = r; 181 182 l = st->c_oflag; 183 r = ((l & 0x00000001) ? OPOST : 0); 184 /* ((l & 0x00000002) ? OLCUC : 0) */ 185 r |= ((l & 0x00000004) ? ONLCR : 0); 186 /* ((l & 0x00000008) ? OCRNL : 0) */ 187 /* ((l & 0x00000010) ? ONOCR : 0) */ 188 /* ((l & 0x00000020) ? ONLRET : 0) */ 189 /* ((l & 0x00000040) ? OFILL : 0) */ 190 /* ((l & 0x00000080) ? OFDEL : 0) */ 191 /* ((l & 0x00000100) ? NLDLY : 0) */ 192 /* ((l & 0x00000100) ? NL1 : 0) */ 193 /* ((l & 0x00000600) ? CRDLY : 0) */ 194 /* ((l & 0x00000200) ? CR1 : 0) */ 195 /* ((l & 0x00000400) ? CR2 : 0) */ 196 /* ((l & 0x00000600) ? CR3 : 0) */ 197 /* ((l & 0x00001800) ? TABDLY : 0) */ 198 /* ((l & 0x00000800) ? TAB1 : 0) */ 199 /* ((l & 0x00001000) ? TAB2 : 0) */ 200 r |= ((l & 0x00001800) ? OXTABS : 0); 201 /* ((l & 0x00002000) ? BSDLY : 0) */ 202 /* ((l & 0x00002000) ? BS1 : 0) */ 203 /* ((l & 0x00004000) ? VTDLY : 0) */ 204 /* ((l & 0x00004000) ? VT1 : 0) */ 205 /* ((l & 0x00008000) ? FFDLY : 0) */ 206 /* ((l & 0x00008000) ? FF1 : 0) */ 207 /* ((l & 0x00010000) ? PAGEOUT : 0) */ 208 /* ((l & 0x00020000) ? WRAP : 0) */ 209 bt->c_oflag = r; 210 211 l = st->c_cflag; 212 switch (l & 0x00000030) { 213 case 0: 214 r = CS5; 215 break; 216 case 0x00000010: 217 r = CS6; 218 break; 219 case 0x00000020: 220 r = CS7; 221 break; 222 case 0x00000030: 223 r = CS8; 224 break; 225 } 226 r |= ((l & 0x00000040) ? CSTOPB : 0); 227 r |= ((l & 0x00000080) ? CREAD : 0); 228 r |= ((l & 0x00000100) ? PARENB : 0); 229 r |= ((l & 0x00000200) ? PARODD : 0); 230 r |= ((l & 0x00000400) ? HUPCL : 0); 231 r |= ((l & 0x00000800) ? CLOCAL : 0); 232 /* ((l & 0x00001000) ? LOBLK : 0) */ 233 r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0); 234 bt->c_cflag = r; 235 236 bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f]; 237 238 l = st->c_lflag; 239 r = ((l & 0x00000001) ? ISIG : 0); 240 r |= ((l & 0x00000002) ? ICANON : 0); 241 /* ((l & 0x00000004) ? XCASE : 0) */ 242 r |= ((l & 0x00000008) ? ECHO : 0); 243 r |= ((l & 0x00000010) ? ECHOE : 0); 244 r |= ((l & 0x00000020) ? ECHOK : 0); 245 r |= ((l & 0x00000040) ? ECHONL : 0); 246 r |= ((l & 0x00000080) ? NOFLSH : 0); 247 r |= ((l & 0x00000100) ? TOSTOP : 0); 248 r |= ((l & 0x00000200) ? ECHOCTL : 0); 249 r |= ((l & 0x00000400) ? ECHOPRT : 0); 250 r |= ((l & 0x00000800) ? ECHOKE : 0); 251 /* ((l & 0x00001000) ? DEFECHO : 0) */ 252 r |= ((l & 0x00002000) ? FLUSHO : 0); 253 r |= ((l & 0x00004000) ? PENDIN : 0); 254 bt->c_lflag = r; 255 256 bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE; 257 bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE; 258 bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE; 259 bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE; 260 bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE; 261 bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE; 262 bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE; 263 /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */ 264 bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE; 265 bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE; 266 bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE; 267 bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE; 268 bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE; 269 bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE; 270 bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE; 271 bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE; 272 bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE; 273 274 /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */ 275 bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF]; 276 bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL]; 277 } 278 279 280 static void 281 btios2stios(bt, st) 282 struct termios *bt; 283 struct sunos_termios *st; 284 { 285 netbsd32_u_long l, r; 286 int s; 287 288 l = bt->c_iflag; 289 r = ((l & IGNBRK) ? 0x00000001 : 0); 290 r |= ((l & BRKINT) ? 0x00000002 : 0); 291 r |= ((l & IGNPAR) ? 0x00000004 : 0); 292 r |= ((l & PARMRK) ? 0x00000008 : 0); 293 r |= ((l & INPCK) ? 0x00000010 : 0); 294 r |= ((l & ISTRIP) ? 0x00000020 : 0); 295 r |= ((l & INLCR) ? 0x00000040 : 0); 296 r |= ((l & IGNCR) ? 0x00000080 : 0); 297 r |= ((l & ICRNL) ? 0x00000100 : 0); 298 /* ((l & IUCLC) ? 0x00000200 : 0) */ 299 r |= ((l & IXON) ? 0x00000400 : 0); 300 r |= ((l & IXANY) ? 0x00000800 : 0); 301 r |= ((l & IXOFF) ? 0x00001000 : 0); 302 r |= ((l & IMAXBEL) ? 0x00002000 : 0); 303 st->c_iflag = r; 304 305 l = bt->c_oflag; 306 r = ((l & OPOST) ? 0x00000001 : 0); 307 /* ((l & OLCUC) ? 0x00000002 : 0) */ 308 r |= ((l & ONLCR) ? 0x00000004 : 0); 309 /* ((l & OCRNL) ? 0x00000008 : 0) */ 310 /* ((l & ONOCR) ? 0x00000010 : 0) */ 311 /* ((l & ONLRET) ? 0x00000020 : 0) */ 312 /* ((l & OFILL) ? 0x00000040 : 0) */ 313 /* ((l & OFDEL) ? 0x00000080 : 0) */ 314 /* ((l & NLDLY) ? 0x00000100 : 0) */ 315 /* ((l & NL1) ? 0x00000100 : 0) */ 316 /* ((l & CRDLY) ? 0x00000600 : 0) */ 317 /* ((l & CR1) ? 0x00000200 : 0) */ 318 /* ((l & CR2) ? 0x00000400 : 0) */ 319 /* ((l & CR3) ? 0x00000600 : 0) */ 320 /* ((l & TABDLY) ? 0x00001800 : 0) */ 321 /* ((l & TAB1) ? 0x00000800 : 0) */ 322 /* ((l & TAB2) ? 0x00001000 : 0) */ 323 r |= ((l & OXTABS) ? 0x00001800 : 0); 324 /* ((l & BSDLY) ? 0x00002000 : 0) */ 325 /* ((l & BS1) ? 0x00002000 : 0) */ 326 /* ((l & VTDLY) ? 0x00004000 : 0) */ 327 /* ((l & VT1) ? 0x00004000 : 0) */ 328 /* ((l & FFDLY) ? 0x00008000 : 0) */ 329 /* ((l & FF1) ? 0x00008000 : 0) */ 330 /* ((l & PAGEOUT) ? 0x00010000 : 0) */ 331 /* ((l & WRAP) ? 0x00020000 : 0) */ 332 st->c_oflag = r; 333 334 l = bt->c_cflag; 335 switch (l & CSIZE) { 336 case CS5: 337 r = 0; 338 break; 339 case CS6: 340 r = 0x00000010; 341 break; 342 case CS7: 343 r = 0x00000020; 344 break; 345 case CS8: 346 r = 0x00000030; 347 break; 348 } 349 r |= ((l & CSTOPB) ? 0x00000040 : 0); 350 r |= ((l & CREAD) ? 0x00000080 : 0); 351 r |= ((l & PARENB) ? 0x00000100 : 0); 352 r |= ((l & PARODD) ? 0x00000200 : 0); 353 r |= ((l & HUPCL) ? 0x00000400 : 0); 354 r |= ((l & CLOCAL) ? 0x00000800 : 0); 355 /* ((l & LOBLK) ? 0x00001000 : 0) */ 356 r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0); 357 st->c_cflag = r; 358 359 l = bt->c_lflag; 360 r = ((l & ISIG) ? 0x00000001 : 0); 361 r |= ((l & ICANON) ? 0x00000002 : 0); 362 /* ((l & XCASE) ? 0x00000004 : 0) */ 363 r |= ((l & ECHO) ? 0x00000008 : 0); 364 r |= ((l & ECHOE) ? 0x00000010 : 0); 365 r |= ((l & ECHOK) ? 0x00000020 : 0); 366 r |= ((l & ECHONL) ? 0x00000040 : 0); 367 r |= ((l & NOFLSH) ? 0x00000080 : 0); 368 r |= ((l & TOSTOP) ? 0x00000100 : 0); 369 r |= ((l & ECHOCTL) ? 0x00000200 : 0); 370 r |= ((l & ECHOPRT) ? 0x00000400 : 0); 371 r |= ((l & ECHOKE) ? 0x00000800 : 0); 372 /* ((l & DEFECHO) ? 0x00001000 : 0) */ 373 r |= ((l & FLUSHO) ? 0x00002000 : 0); 374 r |= ((l & PENDIN) ? 0x00004000 : 0); 375 st->c_lflag = r; 376 377 s = ttspeedtab(bt->c_ospeed, sptab); 378 if (s >= 0) 379 st->c_cflag |= s; 380 381 st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0; 382 st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0; 383 st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0; 384 st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0; 385 st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0; 386 st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0; 387 st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0; 388 st->c_cc[7] = 0; 389 /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */ 390 st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0; 391 st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0; 392 st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0; 393 st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0; 394 st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0; 395 st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0; 396 st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0; 397 st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0; 398 st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0; 399 400 if (!(bt->c_lflag & ICANON)) { 401 /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */ 402 st->c_cc[4] = bt->c_cc[VMIN]; 403 st->c_cc[5] = bt->c_cc[VTIME]; 404 } 405 406 st->c_line = 0; 407 } 408 409 static void 410 stios2stio(ts, t) 411 struct sunos_termios *ts; 412 struct sunos_termio *t; 413 { 414 t->c_iflag = ts->c_iflag; 415 t->c_oflag = ts->c_oflag; 416 t->c_cflag = ts->c_cflag; 417 t->c_lflag = ts->c_lflag; 418 t->c_line = ts->c_line; 419 memcpy(t->c_cc, ts->c_cc, 8); 420 } 421 422 static void 423 stio2stios(t, ts) 424 struct sunos_termio *t; 425 struct sunos_termios *ts; 426 { 427 ts->c_iflag = t->c_iflag; 428 ts->c_oflag = t->c_oflag; 429 ts->c_cflag = t->c_cflag; 430 ts->c_lflag = t->c_lflag; 431 ts->c_line = t->c_line; 432 memcpy(ts->c_cc, t->c_cc, 8); /* don't touch the upper fields! */ 433 } 434 435 int 436 sunos32_sys_ioctl(p, v, retval) 437 struct proc *p; 438 void *v; 439 register_t *retval; 440 { 441 struct sunos32_sys_ioctl_args /* { 442 int fd; 443 netbsd32_u_long com; 444 netbsd32_caddr_t data; 445 } */ *uap = v; 446 struct filedesc *fdp = p->p_fd; 447 struct file *fp; 448 int (*ctl) __P((struct file *, u_long, caddr_t, struct proc *)); 449 int error; 450 451 if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL) 452 return EBADF; 453 454 if ((fp->f_flag & (FREAD|FWRITE)) == 0) 455 return EBADF; 456 457 ctl = fp->f_ops->fo_ioctl; 458 459 switch (SCARG(uap, com)) { 460 case _IOR('t', 0, int): 461 SCARG(uap, com) = TIOCGETD; 462 break; 463 case _IOW('t', 1, int): 464 { 465 int disc; 466 467 if ((error = copyin((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&disc, 468 sizeof disc)) != 0) 469 return error; 470 471 /* map SunOS NTTYDISC into our termios discipline */ 472 if (disc == 2) 473 disc = 0; 474 /* all other disciplines are not supported by NetBSD */ 475 if (disc) 476 return ENXIO; 477 478 return (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p); 479 } 480 case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */ 481 { 482 int x; /* unused */ 483 484 return copyin((caddr_t)&x, (caddr_t)(u_long)SCARG(uap, data), sizeof x); 485 } 486 case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */ 487 { 488 int x = 0; 489 490 return copyout((caddr_t)&x, (caddr_t)(u_long)SCARG(uap, data), sizeof x); 491 } 492 case _IO('t', 36): /* sun TIOCCONS, no parameters */ 493 { 494 int on = 1; 495 return (*ctl)(fp, TIOCCONS, (caddr_t)&on, p); 496 } 497 case _IOW('t', 37, struct sunos_ttysize): 498 { 499 struct winsize ws; 500 struct sunos_ttysize ss; 501 502 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0) 503 return (error); 504 505 if ((error = copyin ((caddr_t)(u_long)SCARG(uap, data), &ss, sizeof (ss))) != 0) 506 return error; 507 508 ws.ws_row = ss.ts_row; 509 ws.ws_col = ss.ts_col; 510 511 return ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p)); 512 } 513 case _IOW('t', 38, struct sunos_ttysize): 514 { 515 struct winsize ws; 516 struct sunos_ttysize ss; 517 518 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0) 519 return (error); 520 521 ss.ts_row = ws.ws_row; 522 ss.ts_col = ws.ws_col; 523 524 return copyout ((caddr_t)&ss, (caddr_t)(u_long)SCARG(uap, data), sizeof (ss)); 525 } 526 case _IOW('t', 130, int): /* TIOCSETPGRP: posix variant */ 527 SCARG(uap, com) = TIOCSPGRP; 528 break; 529 case _IOR('t', 131, int): /* TIOCGETPGRP: posix variant */ 530 { 531 /* 532 * sigh, must do error translation on pty devices 533 * (see also kern/tty_pty.c) 534 */ 535 int pgrp; 536 struct vnode *vp; 537 error = (*ctl)(fp, TIOCGPGRP, (caddr_t)&pgrp, p); 538 if (error) { 539 vp = (struct vnode *)fp->f_data; 540 if (error == EIO && vp != NULL && 541 vp->v_type == VCHR && major(vp->v_rdev) == 21) 542 error = ENOTTY; 543 return (error); 544 } 545 return copyout((caddr_t)&pgrp, (caddr_t)(u_long)SCARG(uap, data), sizeof(pgrp)); 546 } 547 case _IO('t', 132): 548 SCARG(uap, com) = TIOCSCTTY; 549 break; 550 case SUNOS_TCGETA: 551 case SUNOS_TCGETS: 552 { 553 struct termios bts; 554 struct sunos_termios sts; 555 struct sunos_termio st; 556 557 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0) 558 return error; 559 560 btios2stios (&bts, &sts); 561 if (SCARG(uap, com) == SUNOS_TCGETA) { 562 stios2stio (&sts, &st); 563 return copyout((caddr_t)&st, (caddr_t)(u_long)SCARG(uap, data), 564 sizeof (st)); 565 } else 566 return copyout((caddr_t)&sts, (caddr_t)(u_long)SCARG(uap, data), 567 sizeof (sts)); 568 /*NOTREACHED*/ 569 } 570 case SUNOS_TCSETA: 571 case SUNOS_TCSETAW: 572 case SUNOS_TCSETAF: 573 { 574 struct termios bts; 575 struct sunos_termios sts; 576 struct sunos_termio st; 577 578 if ((error = copyin((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&st, 579 sizeof (st))) != 0) 580 return error; 581 582 /* get full BSD termios so we don't lose information */ 583 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0) 584 return error; 585 586 /* 587 * convert to sun termios, copy in information from 588 * termio, and convert back, then set new values. 589 */ 590 btios2stios(&bts, &sts); 591 stio2stios(&st, &sts); 592 stios2btios(&sts, &bts); 593 594 return (*ctl)(fp, SCARG(uap, com) - SUNOS_TCSETA + TIOCSETA, 595 (caddr_t)&bts, p); 596 } 597 case SUNOS_TCSETS: 598 case SUNOS_TCSETSW: 599 case SUNOS_TCSETSF: 600 { 601 struct termios bts; 602 struct sunos_termios sts; 603 604 if ((error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&sts, 605 sizeof (sts))) != 0) 606 return error; 607 stios2btios (&sts, &bts); 608 return (*ctl)(fp, SCARG(uap, com) - SUNOS_TCSETS + TIOCSETA, 609 (caddr_t)&bts, p); 610 } 611 /* 612 * Pseudo-tty ioctl translations. 613 */ 614 case _IOW('t', 32, int): { /* TIOCTCNTL */ 615 int error, on; 616 617 error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&on, sizeof (on)); 618 if (error) 619 return error; 620 return (*ctl)(fp, TIOCUCNTL, (caddr_t)&on, p); 621 } 622 case _IOW('t', 33, int): { /* TIOCSIGNAL */ 623 int error, sig; 624 625 error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&sig, sizeof (sig)); 626 if (error) 627 return error; 628 return (*ctl)(fp, TIOCSIG, (caddr_t)&sig, p); 629 } 630 631 /* 632 * Socket ioctl translations. 633 */ 634 #define IFREQ_IN(a) { \ 635 struct ifreq ifreq; \ 636 error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq)); \ 637 if (error) \ 638 return error; \ 639 return (*ctl)(fp, a, (caddr_t)&ifreq, p); \ 640 } 641 #define IFREQ_INOUT(a) { \ 642 struct ifreq ifreq; \ 643 error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq)); \ 644 if (error) \ 645 return error; \ 646 if ((error = (*ctl)(fp, a, (caddr_t)&ifreq, p)) != 0) \ 647 return error; \ 648 return copyout ((caddr_t)&ifreq, (caddr_t)(u_long)SCARG(uap, data), sizeof (ifreq)); \ 649 } 650 651 case _IOW('i', 12, struct ifreq): 652 /* SIOCSIFADDR */ 653 break; 654 655 case _IOWR('i', 13, struct ifreq): 656 IFREQ_INOUT(OSIOCGIFADDR); 657 658 case _IOW('i', 14, struct ifreq): 659 /* SIOCSIFDSTADDR */ 660 break; 661 662 case _IOWR('i', 15, struct ifreq): 663 IFREQ_INOUT(OSIOCGIFDSTADDR); 664 665 case _IOW('i', 16, struct ifreq): 666 /* SIOCSIFFLAGS */ 667 break; 668 669 case _IOWR('i', 17, struct ifreq): 670 /* SIOCGIFFLAGS */ 671 break; 672 673 case _IOW('i', 21, struct ifreq): 674 IFREQ_IN(SIOCSIFMTU); 675 676 case _IOWR('i', 22, struct ifreq): 677 IFREQ_INOUT(SIOCGIFMTU); 678 679 case _IOWR('i', 23, struct ifreq): 680 IFREQ_INOUT(SIOCGIFBRDADDR); 681 682 case _IOW('i', 24, struct ifreq): 683 IFREQ_IN(SIOCSIFBRDADDR); 684 685 case _IOWR('i', 25, struct ifreq): 686 IFREQ_INOUT(OSIOCGIFNETMASK); 687 688 case _IOW('i', 26, struct ifreq): 689 IFREQ_IN(SIOCSIFNETMASK); 690 691 case _IOWR('i', 27, struct ifreq): 692 IFREQ_INOUT(SIOCGIFMETRIC); 693 694 case _IOWR('i', 28, struct ifreq): 695 IFREQ_IN(SIOCSIFMETRIC); 696 697 case _IOW('i', 30, struct arpreq): 698 /* SIOCSARP */ 699 break; 700 701 case _IOWR('i', 31, struct arpreq): 702 /* SIOCGARP */ 703 break; 704 705 case _IOW('i', 32, struct arpreq): 706 /* SIOCDARP */ 707 break; 708 709 case _IOW('i', 18, struct ifreq): /* SIOCSIFMEM */ 710 case _IOWR('i', 19, struct ifreq): /* SIOCGIFMEM */ 711 case _IOW('i', 40, struct ifreq): /* SIOCUPPER */ 712 case _IOW('i', 41, struct ifreq): /* SIOCLOWER */ 713 case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */ 714 case _IOWR('i', 45, struct ifreq): /* SIOCGETSYNC */ 715 case _IOWR('i', 46, struct ifreq): /* SIOCSDSTATS */ 716 case _IOWR('i', 47, struct ifreq): /* SIOCSESTATS */ 717 case _IOW('i', 48, int): /* SIOCSPROMISC */ 718 case _IOW('i', 49, struct ifreq): /* SIOCADDMULTI */ 719 case _IOW('i', 50, struct ifreq): /* SIOCDELMULTI */ 720 return EOPNOTSUPP; 721 722 case _IOWR('i', 20, struct ifconf): /* SIOCGIFCONF */ 723 { 724 struct ifconf ifconf; 725 726 /* 727 * XXX: two more problems 728 * 1. our sockaddr's are variable length, not always sizeof(sockaddr) 729 * 2. this returns a name per protocol, ie. it returns two "lo0"'s 730 */ 731 error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&ifconf, 732 sizeof (ifconf)); 733 if (error) 734 return error; 735 error = (*ctl)(fp, OSIOCGIFCONF, (caddr_t)&ifconf, p); 736 if (error) 737 return error; 738 return copyout ((caddr_t)&ifconf, (caddr_t)(u_long)SCARG(uap, data), 739 sizeof (ifconf)); 740 } 741 742 /* 743 * Audio ioctl translations. 744 */ 745 case _IOR('A', 1, struct sunos_audio_info): /* AUDIO_GETINFO */ 746 sunos_au_getinfo: 747 { 748 struct audio_info aui; 749 struct sunos_audio_info sunos_aui; 750 751 error = (*ctl)(fp, AUDIO_GETINFO, (caddr_t)&aui, p); 752 if (error) 753 return error; 754 755 sunos_aui.play = *(struct sunos_audio_prinfo *)&aui.play; 756 sunos_aui.record = *(struct sunos_audio_prinfo *)&aui.record; 757 758 /* `avail_ports' is `seek' in BSD */ 759 sunos_aui.play.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE; 760 sunos_aui.record.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE; 761 762 sunos_aui.play.waiting = 0; 763 sunos_aui.record.waiting = 0; 764 sunos_aui.play.eof = 0; 765 sunos_aui.record.eof = 0; 766 sunos_aui.monitor_gain = 0; /* aui.__spare; XXX */ 767 /*XXXsunos_aui.output_muted = 0;*/ 768 /*XXX*/sunos_aui.reserved[0] = 0; 769 /*XXX*/sunos_aui.reserved[1] = 0; 770 /*XXX*/sunos_aui.reserved[2] = 0; 771 /*XXX*/sunos_aui.reserved[3] = 0; 772 773 return copyout ((caddr_t)&sunos_aui, (caddr_t)(u_long)SCARG(uap, data), 774 sizeof (sunos_aui)); 775 } 776 777 case _IOWR('A', 2, struct sunos_audio_info): /* AUDIO_SETINFO */ 778 { 779 struct audio_info aui; 780 struct sunos_audio_info sunos_aui; 781 782 error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&sunos_aui, 783 sizeof (sunos_aui)); 784 if (error) 785 return error; 786 787 aui.play = *(struct audio_prinfo *)&sunos_aui.play; 788 aui.record = *(struct audio_prinfo *)&sunos_aui.record; 789 /* aui.__spare = sunos_aui.monitor_gain; */ 790 aui.blocksize = ~0; 791 aui.hiwat = ~0; 792 aui.lowat = ~0; 793 /* XXX somebody check this please. - is: aui.backlog = ~0; */ 794 aui.mode = ~0; 795 /* 796 * The bsd driver does not distinguish between paused and 797 * active. (In the sun driver, not active means samples are 798 * not ouput at all, but paused means the last streams buffer 799 * is drained and then output stops.) If either are 0, then 800 * when stop output. Otherwise, if either are non-zero, 801 * we resume. 802 */ 803 if (sunos_aui.play.pause == 0 || sunos_aui.play.active == 0) 804 aui.play.pause = 0; 805 else if (sunos_aui.play.pause != (u_char)~0 || 806 sunos_aui.play.active != (u_char)~0) 807 aui.play.pause = 1; 808 if (sunos_aui.record.pause == 0 || sunos_aui.record.active == 0) 809 aui.record.pause = 0; 810 else if (sunos_aui.record.pause != (u_char)~0 || 811 sunos_aui.record.active != (u_char)~0) 812 aui.record.pause = 1; 813 814 error = (*ctl)(fp, AUDIO_SETINFO, (caddr_t)&aui, p); 815 if (error) 816 return error; 817 /* Return new state */ 818 goto sunos_au_getinfo; 819 } 820 case _IO('A', 3): /* AUDIO_DRAIN */ 821 return (*ctl)(fp, AUDIO_DRAIN, (void *)0, p); 822 case _IOR('A', 4, int): /* AUDIO_GETDEV */ 823 { 824 int devtype = SUNOS_AUDIO_DEV_AMD; 825 return copyout ((caddr_t)&devtype, (caddr_t)(u_long)SCARG(uap, data), 826 sizeof (devtype)); 827 } 828 829 /* 830 * Selected streams ioctls. 831 */ 832 #define SUNOS_S_FLUSHR 1 833 #define SUNOS_S_FLUSHW 2 834 #define SUNOS_S_FLUSHRW 3 835 836 #define SUNOS_S_INPUT 1 837 #define SUNOS_S_HIPRI 2 838 #define SUNOS_S_OUTPUT 4 839 #define SUNOS_S_MSG 8 840 841 case _IO('S', 5): /* I_FLUSH */ 842 { 843 int tmp = 0; 844 switch ((int)(u_long)SCARG(uap, data)) { 845 case SUNOS_S_FLUSHR: tmp = FREAD; 846 case SUNOS_S_FLUSHW: tmp = FWRITE; 847 case SUNOS_S_FLUSHRW: tmp = FREAD|FWRITE; 848 } 849 return (*ctl)(fp, TIOCFLUSH, (caddr_t)&tmp, p); 850 } 851 case _IO('S', 9): /* I_SETSIG */ 852 { 853 int on = 1; 854 if (((int)(u_long)SCARG(uap, data) & 855 (SUNOS_S_HIPRI|SUNOS_S_INPUT)) == 856 SUNOS_S_HIPRI) 857 return EOPNOTSUPP; 858 return (*ctl)(fp, FIOASYNC, (caddr_t)&on, p); 859 } 860 /* 861 * SunOS disk ioctls, taken from arch/sparc/sparc/disksubr.c 862 * (which was from the old sparc/scsi/sun_disklabel.c), and 863 * modified to suite. 864 */ 865 case DKIOCGGEOM: 866 { 867 struct disklabel dl; 868 869 error = (*ctl)(fp, DIOCGDINFO, (caddr_t)&dl, p); 870 if (error) 871 return (error); 872 873 #define datageom ((struct sun_dkgeom *)(u_long)SCARG(uap, data)) 874 memset((caddr_t)(u_long)SCARG(uap, data), 0, sizeof(*datageom)); 875 876 datageom->sdkc_ncylinders = dl.d_ncylinders; 877 datageom->sdkc_acylinders = dl.d_acylinders; 878 datageom->sdkc_ntracks = dl.d_ntracks; 879 datageom->sdkc_nsectors = dl.d_nsectors; 880 datageom->sdkc_interleave = dl.d_interleave; 881 datageom->sdkc_sparespercyl = dl.d_sparespercyl; 882 datageom->sdkc_rpm = dl.d_rpm; 883 datageom->sdkc_pcylinders = dl.d_ncylinders + dl.d_acylinders; 884 #undef datageom 885 break; 886 } 887 888 case DKIOCINFO: 889 /* Homey don't do DKIOCINFO */ 890 memset((caddr_t)(u_long)SCARG(uap, data), 0, sizeof(struct sun_dkctlr)); 891 break; 892 893 case DKIOCGPART: 894 { 895 struct partinfo pi; 896 897 error = (*ctl)(fp, DIOCGPART, (caddr_t)&pi, p); 898 if (error) 899 return (error); 900 901 if (pi.disklab->d_secpercyl == 0) 902 return (ERANGE); /* XXX */ 903 if (pi.part->p_offset % pi.disklab->d_secpercyl != 0) 904 return (ERANGE); /* XXX */ 905 #define datapart ((struct sun_dkpart *)(u_long)SCARG(uap, data)) 906 datapart->sdkp_cyloffset = pi.part->p_offset / pi.disklab->d_secpercyl; 907 datapart->sdkp_nsectors = pi.part->p_size; 908 #undef datapart 909 } 910 911 } 912 return (netbsd32_ioctl(p, uap, retval)); 913 } 914 915 /* SunOS fcntl(2) cmds not implemented */ 916 #define SUN_F_RGETLK 10 917 #define SUN_F_RSETLK 11 918 #define SUN_F_CNVT 12 919 #define SUN_F_RSETLKW 13 920 921 /* SunOS flock translation */ 922 struct sunos_flock { 923 short l_type; 924 short l_whence; 925 netbsd32_long l_start; 926 netbsd32_long l_len; 927 short l_pid; 928 short l_xxx; 929 }; 930 931 static void bsd_to_sunos_flock __P((struct flock *, struct sunos_flock *)); 932 static void sunos_to_bsd_flock __P((struct sunos_flock *, struct flock *)); 933 934 #define SUNOS_F_RDLCK 1 935 #define SUNOS_F_WRLCK 2 936 #define SUNOS_F_UNLCK 3 937 938 static void 939 bsd_to_sunos_flock(iflp, oflp) 940 struct flock *iflp; 941 struct sunos_flock *oflp; 942 { 943 switch (iflp->l_type) { 944 case F_RDLCK: 945 oflp->l_type = SUNOS_F_RDLCK; 946 break; 947 case F_WRLCK: 948 oflp->l_type = SUNOS_F_WRLCK; 949 break; 950 case F_UNLCK: 951 oflp->l_type = SUNOS_F_UNLCK; 952 break; 953 default: 954 oflp->l_type = -1; 955 break; 956 } 957 958 oflp->l_whence = (short) iflp->l_whence; 959 oflp->l_start = (netbsd32_long) iflp->l_start; 960 oflp->l_len = (netbsd32_long) iflp->l_len; 961 oflp->l_pid = (short) iflp->l_pid; 962 oflp->l_xxx = 0; 963 } 964 965 966 static void 967 sunos_to_bsd_flock(iflp, oflp) 968 struct sunos_flock *iflp; 969 struct flock *oflp; 970 { 971 switch (iflp->l_type) { 972 case SUNOS_F_RDLCK: 973 oflp->l_type = F_RDLCK; 974 break; 975 case SUNOS_F_WRLCK: 976 oflp->l_type = F_WRLCK; 977 break; 978 case SUNOS_F_UNLCK: 979 oflp->l_type = F_UNLCK; 980 break; 981 default: 982 oflp->l_type = -1; 983 break; 984 } 985 986 oflp->l_whence = iflp->l_whence; 987 oflp->l_start = (off_t) iflp->l_start; 988 oflp->l_len = (off_t) iflp->l_len; 989 oflp->l_pid = (pid_t) iflp->l_pid; 990 991 } 992 static struct { 993 netbsd32_long sun_flg; 994 netbsd32_long bsd_flg; 995 } sunfcntl_flgtab[] = { 996 /* F_[GS]ETFLags that differ: */ 997 #define SUN_FSETBLK 0x0010 998 #define SUN_SHLOCK 0x0080 999 #define SUN_EXLOCK 0x0100 1000 #define SUN_FNBIO 0x1000 1001 #define SUN_FSYNC 0x2000 1002 #define SUN_NONBLOCK 0x4000 1003 #define SUN_FNOCTTY 0x8000 1004 { SUN_NONBLOCK, O_NONBLOCK }, 1005 { SUN_FNBIO, O_NONBLOCK }, 1006 { SUN_SHLOCK, O_SHLOCK }, 1007 { SUN_EXLOCK, O_EXLOCK }, 1008 { SUN_FSYNC, O_FSYNC }, 1009 { SUN_FSETBLK, 0 }, 1010 { SUN_FNOCTTY, 0 } 1011 }; 1012 1013 int 1014 sunos32_sys_fcntl(p, v, retval) 1015 struct proc *p; 1016 void *v; 1017 register_t *retval; 1018 { 1019 struct sunos32_sys_fcntl_args /* { 1020 syscallarg(int) fd; 1021 syscallarg(int) cmd; 1022 syscallarg(netbsd32_voidp) arg; 1023 } */ *uap = v; 1024 netbsd32_long flg; 1025 int n, ret; 1026 1027 switch (SCARG(uap, cmd)) { 1028 case F_SETFL: 1029 flg = (netbsd32_long)SCARG(uap, arg); 1030 n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]); 1031 while (--n >= 0) { 1032 if (flg & sunfcntl_flgtab[n].sun_flg) { 1033 flg &= ~sunfcntl_flgtab[n].sun_flg; 1034 flg |= sunfcntl_flgtab[n].bsd_flg; 1035 } 1036 } 1037 SCARG(uap, arg) = (netbsd32_voidp)flg; 1038 break; 1039 1040 case F_GETLK: 1041 case F_SETLK: 1042 case F_SETLKW: 1043 { 1044 int error; 1045 struct sunos_flock ifl; 1046 struct flock *flp, fl; 1047 caddr_t sg = stackgap_init(p->p_emul); 1048 struct sys_fcntl_args fa; 1049 1050 SCARG(&fa, fd) = SCARG(uap, fd); 1051 SCARG(&fa, cmd) = SCARG(uap, cmd); 1052 1053 flp = stackgap_alloc(&sg, sizeof(struct flock)); 1054 SCARG(&fa, arg) = (void *) flp; 1055 1056 error = copyin((caddr_t)(u_long)SCARG(uap, arg), &ifl, sizeof ifl); 1057 if (error) 1058 return error; 1059 1060 sunos_to_bsd_flock(&ifl, &fl); 1061 1062 error = copyout(&fl, flp, sizeof fl); 1063 if (error) 1064 return error; 1065 1066 error = sys_fcntl(p, &fa, retval); 1067 if (error || SCARG(&fa, cmd) != F_GETLK) 1068 return error; 1069 1070 error = copyin(flp, &fl, sizeof fl); 1071 if (error) 1072 return error; 1073 1074 bsd_to_sunos_flock(&fl, &ifl); 1075 1076 return copyout(&ifl, (caddr_t)(u_long)SCARG(uap, arg), sizeof ifl); 1077 } 1078 break; 1079 case SUN_F_RGETLK: 1080 case SUN_F_RSETLK: 1081 case SUN_F_CNVT: 1082 case SUN_F_RSETLKW: 1083 return (EOPNOTSUPP); 1084 } 1085 1086 ret = netbsd32_fcntl(p, uap, retval); 1087 1088 switch (SCARG(uap, cmd)) { 1089 case F_GETFL: 1090 n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]); 1091 while (--n >= 0) { 1092 if (ret & sunfcntl_flgtab[n].bsd_flg) { 1093 ret &= ~sunfcntl_flgtab[n].bsd_flg; 1094 ret |= sunfcntl_flgtab[n].sun_flg; 1095 } 1096 } 1097 break; 1098 } 1099 1100 return (ret); 1101 } 1102