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