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