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