Annotation of sys/compat/ibcs2/ibcs2_ioctl.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ibcs2_ioctl.c,v 1.12 2004/09/19 21:34:42 mickey Exp $ */
2: /* $NetBSD: ibcs2_ioctl.c,v 1.12 1996/08/10 09:08:26 mycroft Exp $ */
3:
4: /*
5: * Copyright (c) 1994, 1995 Scott Bartram
6: * All rights reserved.
7: *
8: * based on compat/sunos/sun_ioctl.c
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. The name of the author may not be used to endorse or promote products
16: * derived from this software without specific prior written permission
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28: */
29:
30: #include <sys/param.h>
31: #include <sys/systm.h>
32: #include <sys/namei.h>
33: #include <sys/dirent.h>
34: #include <sys/proc.h>
35: #include <sys/file.h>
36: #include <sys/stat.h>
37: #include <sys/filedesc.h>
38: #include <sys/ioctl.h>
39: #include <sys/kernel.h>
40: #include <sys/malloc.h>
41: #include <sys/mbuf.h>
42: #include <sys/mman.h>
43: #include <sys/mount.h>
44: #include <sys/reboot.h>
45: #include <sys/resource.h>
46: #include <sys/resourcevar.h>
47: #include <sys/signal.h>
48: #include <sys/signalvar.h>
49: #include <sys/socket.h>
50: #include <sys/termios.h>
51: #include <sys/time.h>
52: #include <sys/times.h>
53: #include <sys/tty.h>
54: #include <sys/vnode.h>
55: #include <sys/uio.h>
56: #include <sys/wait.h>
57: #include <sys/utsname.h>
58: #include <sys/unistd.h>
59:
60: #include <net/if.h>
61: #include <sys/syscallargs.h>
62:
63: #include <compat/ibcs2/ibcs2_types.h>
64: #include <compat/ibcs2/ibcs2_signal.h>
65: #include <compat/ibcs2/ibcs2_socksys.h>
66: #include <compat/ibcs2/ibcs2_stropts.h>
67: #include <compat/ibcs2/ibcs2_syscallargs.h>
68: #include <compat/ibcs2/ibcs2_termios.h>
69: #include <compat/ibcs2/ibcs2_util.h>
70:
71: /*
72: * iBCS2 ioctl calls.
73: */
74:
75: static const struct speedtab sptab[] = {
76: { 0, 0 },
77: { 50, 1 },
78: { 75, 2 },
79: { 110, 3 },
80: { 134, 4 },
81: { 135, 4 },
82: { 150, 5 },
83: { 200, 6 },
84: { 300, 7 },
85: { 600, 8 },
86: { 1200, 9 },
87: { 1800, 10 },
88: { 2400, 11 },
89: { 4800, 12 },
90: { 9600, 13 },
91: { 19200, 14 },
92: { 38400, 15 },
93: { -1, -1 }
94: };
95:
96: static const u_long s2btab[] = {
97: 0,
98: 50,
99: 75,
100: 110,
101: 134,
102: 150,
103: 200,
104: 300,
105: 600,
106: 1200,
107: 1800,
108: 2400,
109: 4800,
110: 9600,
111: 19200,
112: 38400,
113: };
114:
115: static void stios2btios(struct ibcs2_termios *, struct termios *);
116: static void btios2stios(struct termios *, struct ibcs2_termios *);
117: static void stios2stio(struct ibcs2_termios *, struct ibcs2_termio *);
118: static void stio2stios(struct ibcs2_termio *, struct ibcs2_termios *);
119:
120: static void
121: stios2btios(st, bt)
122: struct ibcs2_termios *st;
123: struct termios *bt;
124: {
125: register u_long l, r;
126:
127: l = st->c_iflag; r = 0;
128: if (l & IBCS2_IGNBRK) r |= IGNBRK;
129: if (l & IBCS2_BRKINT) r |= BRKINT;
130: if (l & IBCS2_IGNPAR) r |= IGNPAR;
131: if (l & IBCS2_PARMRK) r |= PARMRK;
132: if (l & IBCS2_INPCK) r |= INPCK;
133: if (l & IBCS2_ISTRIP) r |= ISTRIP;
134: if (l & IBCS2_INLCR) r |= INLCR;
135: if (l & IBCS2_IGNCR) r |= IGNCR;
136: if (l & IBCS2_ICRNL) r |= ICRNL;
137: if (l & IBCS2_IXON) r |= IXON;
138: if (l & IBCS2_IXANY) r |= IXANY;
139: if (l & IBCS2_IXOFF) r |= IXOFF;
140: if (l & IBCS2_IMAXBEL) r |= IMAXBEL;
141: bt->c_iflag = r;
142:
143: l = st->c_oflag; r = 0;
144: if (l & IBCS2_OPOST) r |= OPOST;
145: if (l & IBCS2_ONLCR) r |= ONLCR;
146: if (l & IBCS2_TAB3) r |= OXTABS;
147: bt->c_oflag = r;
148:
149: l = st->c_cflag; r = 0;
150: switch (l & IBCS2_CSIZE) {
151: case IBCS2_CS5: r |= CS5; break;
152: case IBCS2_CS6: r |= CS6; break;
153: case IBCS2_CS7: r |= CS7; break;
154: case IBCS2_CS8: r |= CS8; break;
155: }
156: if (l & IBCS2_CSTOPB) r |= CSTOPB;
157: if (l & IBCS2_CREAD) r |= CREAD;
158: if (l & IBCS2_PARENB) r |= PARENB;
159: if (l & IBCS2_PARODD) r |= PARODD;
160: if (l & IBCS2_HUPCL) r |= HUPCL;
161: if (l & IBCS2_CLOCAL) r |= CLOCAL;
162: bt->c_cflag = r;
163:
164: l = st->c_lflag; r = 0;
165: if (l & IBCS2_ISIG) r |= ISIG;
166: if (l & IBCS2_ICANON) r |= ICANON;
167: if (l & IBCS2_ECHO) r |= ECHO;
168: if (l & IBCS2_ECHOE) r |= ECHOE;
169: if (l & IBCS2_ECHOK) r |= ECHOK;
170: if (l & IBCS2_ECHONL) r |= ECHONL;
171: if (l & IBCS2_NOFLSH) r |= NOFLSH;
172: if (l & IBCS2_TOSTOP) r |= TOSTOP;
173: bt->c_lflag = r;
174:
175: bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
176:
177: bt->c_cc[VINTR] =
178: st->c_cc[IBCS2_VINTR] ? st->c_cc[IBCS2_VINTR] : _POSIX_VDISABLE;
179: bt->c_cc[VQUIT] =
180: st->c_cc[IBCS2_VQUIT] ? st->c_cc[IBCS2_VQUIT] : _POSIX_VDISABLE;
181: bt->c_cc[VERASE] =
182: st->c_cc[IBCS2_VERASE] ? st->c_cc[IBCS2_VERASE] : _POSIX_VDISABLE;
183: bt->c_cc[VKILL] =
184: st->c_cc[IBCS2_VKILL] ? st->c_cc[IBCS2_VKILL] : _POSIX_VDISABLE;
185: if (bt->c_lflag & ICANON) {
186: bt->c_cc[VEOF] =
187: st->c_cc[IBCS2_VEOF] ? st->c_cc[IBCS2_VEOF] : _POSIX_VDISABLE;
188: bt->c_cc[VEOL] =
189: st->c_cc[IBCS2_VEOL] ? st->c_cc[IBCS2_VEOL] : _POSIX_VDISABLE;
190: } else {
191: bt->c_cc[VMIN] = st->c_cc[IBCS2_VMIN];
192: bt->c_cc[VTIME] = st->c_cc[IBCS2_VTIME];
193: }
194: bt->c_cc[VEOL2] =
195: st->c_cc[IBCS2_VEOL2] ? st->c_cc[IBCS2_VEOL2] : _POSIX_VDISABLE;
196: #if 0
197: bt->c_cc[VSWTCH] =
198: st->c_cc[IBCS2_VSWTCH] ? st->c_cc[IBCS2_VSWTCH] : _POSIX_VDISABLE;
199: #endif
200: bt->c_cc[VSTART] =
201: st->c_cc[IBCS2_VSTART] ? st->c_cc[IBCS2_VSTART] : _POSIX_VDISABLE;
202: bt->c_cc[VSTOP] =
203: st->c_cc[IBCS2_VSTOP] ? st->c_cc[IBCS2_VSTOP] : _POSIX_VDISABLE;
204: bt->c_cc[VSUSP] =
205: st->c_cc[IBCS2_VSUSP] ? st->c_cc[IBCS2_VSUSP] : _POSIX_VDISABLE;
206: bt->c_cc[VDSUSP] = _POSIX_VDISABLE;
207: bt->c_cc[VREPRINT] = _POSIX_VDISABLE;
208: bt->c_cc[VDISCARD] = _POSIX_VDISABLE;
209: bt->c_cc[VWERASE] = _POSIX_VDISABLE;
210: bt->c_cc[VLNEXT] = _POSIX_VDISABLE;
211: bt->c_cc[VSTATUS] = _POSIX_VDISABLE;
212: }
213:
214: static void
215: btios2stios(bt, st)
216: struct termios *bt;
217: struct ibcs2_termios *st;
218: {
219: register u_long l, r;
220:
221: l = bt->c_iflag; r = 0;
222: if (l & IGNBRK) r |= IBCS2_IGNBRK;
223: if (l & BRKINT) r |= IBCS2_BRKINT;
224: if (l & IGNPAR) r |= IBCS2_IGNPAR;
225: if (l & PARMRK) r |= IBCS2_PARMRK;
226: if (l & INPCK) r |= IBCS2_INPCK;
227: if (l & ISTRIP) r |= IBCS2_ISTRIP;
228: if (l & INLCR) r |= IBCS2_INLCR;
229: if (l & IGNCR) r |= IBCS2_IGNCR;
230: if (l & ICRNL) r |= IBCS2_ICRNL;
231: if (l & IXON) r |= IBCS2_IXON;
232: if (l & IXANY) r |= IBCS2_IXANY;
233: if (l & IXOFF) r |= IBCS2_IXOFF;
234: if (l & IMAXBEL) r |= IBCS2_IMAXBEL;
235: st->c_iflag = r;
236:
237: l = bt->c_oflag; r = 0;
238: if (l & OPOST) r |= IBCS2_OPOST;
239: if (l & ONLCR) r |= IBCS2_ONLCR;
240: if (l & OXTABS) r |= IBCS2_TAB3;
241: st->c_oflag = r;
242:
243: l = bt->c_cflag; r = 0;
244: switch (l & CSIZE) {
245: case CS5: r |= IBCS2_CS5; break;
246: case CS6: r |= IBCS2_CS6; break;
247: case CS7: r |= IBCS2_CS7; break;
248: case CS8: r |= IBCS2_CS8; break;
249: }
250: if (l & CSTOPB) r |= IBCS2_CSTOPB;
251: if (l & CREAD) r |= IBCS2_CREAD;
252: if (l & PARENB) r |= IBCS2_PARENB;
253: if (l & PARODD) r |= IBCS2_PARODD;
254: if (l & HUPCL) r |= IBCS2_HUPCL;
255: if (l & CLOCAL) r |= IBCS2_CLOCAL;
256: st->c_cflag = r;
257:
258: l = bt->c_lflag; r = 0;
259: if (l & ISIG) r |= IBCS2_ISIG;
260: if (l & ICANON) r |= IBCS2_ICANON;
261: if (l & ECHO) r |= IBCS2_ECHO;
262: if (l & ECHOE) r |= IBCS2_ECHOE;
263: if (l & ECHOK) r |= IBCS2_ECHOK;
264: if (l & ECHONL) r |= IBCS2_ECHONL;
265: if (l & NOFLSH) r |= IBCS2_NOFLSH;
266: if (l & TOSTOP) r |= IBCS2_TOSTOP;
267: st->c_lflag = r;
268:
269: l = ttspeedtab(bt->c_ospeed, sptab);
270: if (l >= 0)
271: st->c_cflag |= l;
272:
273: st->c_cc[IBCS2_VINTR] =
274: bt->c_cc[VINTR] != _POSIX_VDISABLE ? bt->c_cc[VINTR] : 0;
275: st->c_cc[IBCS2_VQUIT] =
276: bt->c_cc[VQUIT] != _POSIX_VDISABLE ? bt->c_cc[VQUIT] : 0;
277: st->c_cc[IBCS2_VERASE] =
278: bt->c_cc[VERASE] != _POSIX_VDISABLE ? bt->c_cc[VERASE] : 0;
279: st->c_cc[IBCS2_VKILL] =
280: bt->c_cc[VKILL] != _POSIX_VDISABLE ? bt->c_cc[VKILL] : 0;
281: if (bt->c_lflag & ICANON) {
282: st->c_cc[IBCS2_VEOF] =
283: bt->c_cc[VEOF] != _POSIX_VDISABLE ? bt->c_cc[VEOF] : 0;
284: st->c_cc[IBCS2_VEOL] =
285: bt->c_cc[VEOL] != _POSIX_VDISABLE ? bt->c_cc[VEOL] : 0;
286: } else {
287: st->c_cc[IBCS2_VMIN] = bt->c_cc[VMIN];
288: st->c_cc[IBCS2_VTIME] = bt->c_cc[VTIME];
289: }
290: st->c_cc[IBCS2_VEOL2] =
291: bt->c_cc[VEOL2] != _POSIX_VDISABLE ? bt->c_cc[VEOL2] : 0;
292: st->c_cc[IBCS2_VSWTCH] =
293: 0;
294: st->c_cc[IBCS2_VSUSP] =
295: bt->c_cc[VSUSP] != _POSIX_VDISABLE ? bt->c_cc[VSUSP] : 0;
296: st->c_cc[IBCS2_VSTART] =
297: bt->c_cc[VSTART] != _POSIX_VDISABLE ? bt->c_cc[VSTART] : 0;
298: st->c_cc[IBCS2_VSTOP] =
299: bt->c_cc[VSTOP] != _POSIX_VDISABLE ? bt->c_cc[VSTOP] : 0;
300:
301: st->c_line = 0;
302: }
303:
304: static void
305: stios2stio(ts, t)
306: struct ibcs2_termios *ts;
307: struct ibcs2_termio *t;
308: {
309:
310: t->c_iflag = ts->c_iflag;
311: t->c_oflag = ts->c_oflag;
312: t->c_cflag = ts->c_cflag;
313: t->c_lflag = ts->c_lflag;
314: t->c_line = ts->c_line;
315: bcopy(ts->c_cc, t->c_cc, IBCS2_NCC);
316: }
317:
318: static void
319: stio2stios(t, ts)
320: struct ibcs2_termio *t;
321: struct ibcs2_termios *ts;
322: {
323:
324: ts->c_iflag = t->c_iflag;
325: ts->c_oflag = t->c_oflag;
326: ts->c_cflag = t->c_cflag;
327: ts->c_lflag = t->c_lflag;
328: ts->c_line = t->c_line;
329: bcopy(t->c_cc, ts->c_cc, IBCS2_NCC);
330: }
331:
332: int
333: ibcs2_sys_ioctl(p, v, retval)
334: struct proc *p;
335: void *v;
336: register_t *retval;
337: {
338: struct ibcs2_sys_ioctl_args /* {
339: syscallarg(int) fd;
340: syscallarg(int) cmd;
341: syscallarg(caddr_t) data;
342: } */ *uap = v;
343: struct filedesc *fdp = p->p_fd;
344: struct file *fp;
345: int (*ctl)(struct file *, u_long, caddr_t, struct proc *);
346: int error;
347:
348: if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
349: return (EBADF);
350: FREF(fp);
351:
352: if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
353: DPRINTF(("ibcs2_ioctl(%d): bad fp flag ", p->p_pid));
354: error = EBADF;
355: goto out;
356: }
357:
358: ctl = fp->f_ops->fo_ioctl;
359:
360: switch (SCARG(uap, cmd)) {
361: case IBCS2_TCGETA:
362: case IBCS2_XCGETA:
363: case IBCS2_OXCGETA:
364: {
365: struct termios bts;
366: struct ibcs2_termios sts;
367: struct ibcs2_termio st;
368:
369: if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
370: goto out;
371:
372: btios2stios (&bts, &sts);
373: if (SCARG(uap, cmd) == IBCS2_TCGETA) {
374: stios2stio (&sts, &st);
375: error = copyout((caddr_t)&st, SCARG(uap, data),
376: sizeof (st));
377: if (error)
378: DPRINTF(("ibcs2_ioctl(%d): copyout failed ",
379: p->p_pid));
380: goto out;
381: } else {
382: error = copyout((caddr_t)&sts, SCARG(uap, data),
383: sizeof (sts));
384: goto out;
385: }
386: /*NOTREACHED*/
387: }
388:
389: case IBCS2_TCSETA:
390: case IBCS2_TCSETAW:
391: case IBCS2_TCSETAF:
392: {
393: struct termios bts;
394: struct ibcs2_termios sts;
395: struct ibcs2_termio st;
396:
397: if ((error = copyin(SCARG(uap, data), (caddr_t)&st,
398: sizeof(st))) != 0) {
399: DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ",
400: p->p_pid));
401: goto out;
402: }
403:
404: /* get full BSD termios so we don't lose information */
405: if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0) {
406: DPRINTF(("ibcs2_ioctl(%d): TCSET ctl failed fd %d ",
407: p->p_pid, SCARG(uap, fd)));
408: goto out;
409: }
410:
411: /*
412: * convert to iBCS2 termios, copy in information from
413: * termio, and convert back, then set new values.
414: */
415: btios2stios(&bts, &sts);
416: stio2stios(&st, &sts);
417: stios2btios(&sts, &bts);
418:
419: error = (*ctl)(fp, SCARG(uap, cmd) - IBCS2_TCSETA + TIOCSETA,
420: (caddr_t)&bts, p);
421: goto out;
422: }
423:
424: case IBCS2_XCSETA:
425: case IBCS2_XCSETAW:
426: case IBCS2_XCSETAF:
427: {
428: struct termios bts;
429: struct ibcs2_termios sts;
430:
431: if ((error = copyin(SCARG(uap, data), (caddr_t)&sts,
432: sizeof (sts))) != 0) {
433: goto out;
434: }
435: stios2btios (&sts, &bts);
436: error = (*ctl)(fp, SCARG(uap, cmd) - IBCS2_XCSETA + TIOCSETA,
437: (caddr_t)&bts, p);
438: goto out;
439: }
440:
441: case IBCS2_OXCSETA:
442: case IBCS2_OXCSETAW:
443: case IBCS2_OXCSETAF:
444: {
445: struct termios bts;
446: struct ibcs2_termios sts;
447:
448: if ((error = copyin(SCARG(uap, data), (caddr_t)&sts,
449: sizeof (sts))) != 0) {
450: goto out;
451: }
452: stios2btios (&sts, &bts);
453: error = (*ctl)(fp, SCARG(uap, cmd) - IBCS2_OXCSETA + TIOCSETA,
454: (caddr_t)&bts, p);
455: goto out;
456: }
457:
458: case IBCS2_TCSBRK:
459: DPRINTF(("ibcs2_ioctl(%d): TCSBRK ", p->p_pid));
460: error = ENOSYS;
461: goto out;
462:
463: case IBCS2_TCXONC:
464: {
465: switch ((int)SCARG(uap, data)) {
466: case 0:
467: case 1:
468: DPRINTF(("ibcs2_ioctl(%d): TCXONC ", p->p_pid));
469: error = ENOSYS;
470: goto out;
471: case 2:
472: error = (*ctl)(fp, TIOCSTOP, (caddr_t)0, p);
473: goto out;
474: case 3:
475: error = (*ctl)(fp, TIOCSTART, (caddr_t)1, p);
476: goto out;
477: default:
478: error = EINVAL;
479: goto out;
480: }
481: }
482:
483: case IBCS2_TCFLSH:
484: {
485: int arg;
486:
487: switch ((int)SCARG(uap, data)) {
488: case 0:
489: arg = FREAD;
490: break;
491: case 1:
492: arg = FWRITE;
493: break;
494: case 2:
495: arg = FREAD | FWRITE;
496: break;
497: default:
498: error = EINVAL;
499: goto out;
500: }
501: error = (*ctl)(fp, TIOCFLUSH, (caddr_t)&arg, p);
502: goto out;
503: }
504:
505: case IBCS2_TIOCGWINSZ:
506: SCARG(uap, cmd) = TIOCGWINSZ;
507: error = sys_ioctl(p, uap, retval);
508: goto out;
509:
510: case IBCS2_TIOCSWINSZ:
511: SCARG(uap, cmd) = TIOCSWINSZ;
512: error = sys_ioctl(p, uap, retval);
513: goto out;
514:
515: case IBCS2_TIOCGPGRP:
516: error = copyout((caddr_t)&p->p_pgrp->pg_id, SCARG(uap, data),
517: sizeof(p->p_pgrp->pg_id));
518: goto out;
519:
520: case IBCS2_TIOCSPGRP: /* XXX - is uap->data a pointer to pgid? */
521: {
522: struct sys_setpgid_args sa;
523:
524: SCARG(&sa, pid) = 0;
525: SCARG(&sa, pgid) = (int)SCARG(uap, data);
526: if ((error = sys_setpgid(p, &sa, retval)) != 0)
527: goto out;
528: error = 0;
529: goto out;
530: }
531:
532: case IBCS2_TCGETSC: /* SCO console - get scancode flags */
533: error = ENOSYS;
534: goto out;
535:
536: case IBCS2_TCSETSC: /* SCO console - set scancode flags */
537: error = ENOSYS;
538: goto out;
539:
540: case IBCS2_SIOCSOCKSYS:
541: error = ibcs2_socksys(p, uap, retval);
542: goto out;
543:
544: case IBCS2_FIONBIO:
545: {
546: int arg;
547:
548: if ((error = copyin(SCARG(uap, data), &arg,
549: sizeof(arg))) != 0)
550: goto out;
551:
552: error = (*ctl)(fp, FIONBIO, (caddr_t)&arg, p);
553: goto out;
554: }
555: case IBCS2_FIONREAD:
556: case IBCS2_I_NREAD: /* STREAMS */
557: SCARG(uap, cmd) = FIONREAD;
558: error = sys_ioctl(p, uap, retval);
559: goto out;
560:
561: default:
562: DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%lx ",
563: p->p_pid, SCARG(uap, cmd)));
564: error = ENOSYS;
565: goto out;
566: }
567: error = ENOSYS;
568:
569: out:
570: FRELE(fp);
571: return (error);
572: }
573:
CVSweb