summaryrefslogtreecommitdiff
path: root/sys/compat/ibcs2/ibcs2_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/ibcs2/ibcs2_ioctl.c')
-rw-r--r--sys/compat/ibcs2/ibcs2_ioctl.c504
1 files changed, 504 insertions, 0 deletions
diff --git a/sys/compat/ibcs2/ibcs2_ioctl.c b/sys/compat/ibcs2/ibcs2_ioctl.c
new file mode 100644
index 00000000000..f5b4763ecd5
--- /dev/null
+++ b/sys/compat/ibcs2/ibcs2_ioctl.c
@@ -0,0 +1,504 @@
+/* $NetBSD: ibcs2_ioctl.c,v 1.9 1995/10/10 02:35:16 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Scott Bartram
+ * All rights reserved.
+ *
+ * based on compat/sunos/sun_ioctl.c
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/namei.h>
+#include <sys/dir.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/filedesc.h>
+#include <sys/ioctl.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/reboot.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
+#include <sys/signal.h>
+#include <sys/signalvar.h>
+#include <sys/socket.h>
+#include <sys/termios.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/tty.h>
+#include <sys/vnode.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <sys/utsname.h>
+#include <sys/unistd.h>
+
+#include <net/if.h>
+#include <sys/syscallargs.h>
+
+#include <compat/ibcs2/ibcs2_types.h>
+#include <compat/ibcs2/ibcs2_signal.h>
+#include <compat/ibcs2/ibcs2_socksys.h>
+#include <compat/ibcs2/ibcs2_stropts.h>
+#include <compat/ibcs2/ibcs2_syscallargs.h>
+#include <compat/ibcs2/ibcs2_termios.h>
+#include <compat/ibcs2/ibcs2_util.h>
+
+/*
+ * iBCS2 ioctl calls.
+ */
+
+static struct speedtab sptab[] = {
+ { 0, 0 },
+ { 50, 1 },
+ { 75, 2 },
+ { 110, 3 },
+ { 134, 4 },
+ { 135, 4 },
+ { 150, 5 },
+ { 200, 6 },
+ { 300, 7 },
+ { 600, 8 },
+ { 1200, 9 },
+ { 1800, 10 },
+ { 2400, 11 },
+ { 4800, 12 },
+ { 9600, 13 },
+ { 19200, 14 },
+ { 38400, 15 },
+ { -1, -1 }
+};
+
+static u_long s2btab[] = {
+ 0,
+ 50,
+ 75,
+ 110,
+ 134,
+ 150,
+ 200,
+ 300,
+ 600,
+ 1200,
+ 1800,
+ 2400,
+ 4800,
+ 9600,
+ 19200,
+ 38400,
+};
+
+static void
+stios2btios(st, bt)
+ struct ibcs2_termios *st;
+ struct termios *bt;
+{
+ register u_long l, r;
+
+ l = st->c_iflag; r = 0;
+ if (l & IBCS2_IGNBRK) r |= IGNBRK;
+ if (l & IBCS2_BRKINT) r |= BRKINT;
+ if (l & IBCS2_IGNPAR) r |= IGNPAR;
+ if (l & IBCS2_PARMRK) r |= PARMRK;
+ if (l & IBCS2_INPCK) r |= INPCK;
+ if (l & IBCS2_ISTRIP) r |= ISTRIP;
+ if (l & IBCS2_INLCR) r |= INLCR;
+ if (l & IBCS2_IGNCR) r |= IGNCR;
+ if (l & IBCS2_ICRNL) r |= ICRNL;
+ if (l & IBCS2_IXON) r |= IXON;
+ if (l & IBCS2_IXANY) r |= IXANY;
+ if (l & IBCS2_IXOFF) r |= IXOFF;
+ if (l & IBCS2_IMAXBEL) r |= IMAXBEL;
+ bt->c_iflag = r;
+
+ l = st->c_oflag; r = 0;
+ if (l & IBCS2_OPOST) r |= OPOST;
+ if (l & IBCS2_ONLCR) r |= ONLCR;
+ if (l & IBCS2_TAB3) r |= OXTABS;
+ bt->c_oflag = r;
+
+ l = st->c_cflag; r = 0;
+ switch (l & IBCS2_CSIZE) {
+ case IBCS2_CS5: r |= CS5; break;
+ case IBCS2_CS6: r |= CS6; break;
+ case IBCS2_CS7: r |= CS7; break;
+ case IBCS2_CS8: r |= CS8; break;
+ }
+ if (l & IBCS2_CSTOPB) r |= CSTOPB;
+ if (l & IBCS2_CREAD) r |= CREAD;
+ if (l & IBCS2_PARENB) r |= PARENB;
+ if (l & IBCS2_PARODD) r |= PARODD;
+ if (l & IBCS2_HUPCL) r |= HUPCL;
+ if (l & IBCS2_CLOCAL) r |= CLOCAL;
+ bt->c_cflag = r;
+
+ l = st->c_lflag; r = 0;
+ if (l & IBCS2_ISIG) r |= ISIG;
+ if (l & IBCS2_ICANON) r |= ICANON;
+ if (l & IBCS2_ECHO) r |= ECHO;
+ if (l & IBCS2_ECHOE) r |= ECHOE;
+ if (l & IBCS2_ECHOK) r |= ECHOK;
+ if (l & IBCS2_ECHONL) r |= ECHONL;
+ if (l & IBCS2_NOFLSH) r |= NOFLSH;
+ if (l & IBCS2_TOSTOP) r |= TOSTOP;
+ bt->c_lflag = r;
+
+ bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
+
+ bt->c_cc[VINTR] =
+ st->c_cc[IBCS2_VINTR] ? st->c_cc[IBCS2_VINTR] : _POSIX_VDISABLE;
+ bt->c_cc[VQUIT] =
+ st->c_cc[IBCS2_VQUIT] ? st->c_cc[IBCS2_VQUIT] : _POSIX_VDISABLE;
+ bt->c_cc[VERASE] =
+ st->c_cc[IBCS2_VERASE] ? st->c_cc[IBCS2_VERASE] : _POSIX_VDISABLE;
+ bt->c_cc[VKILL] =
+ st->c_cc[IBCS2_VKILL] ? st->c_cc[IBCS2_VKILL] : _POSIX_VDISABLE;
+ if (bt->c_lflag & ICANON) {
+ bt->c_cc[VEOF] =
+ st->c_cc[IBCS2_VEOF] ? st->c_cc[IBCS2_VEOF] : _POSIX_VDISABLE;
+ bt->c_cc[VEOL] =
+ st->c_cc[IBCS2_VEOL] ? st->c_cc[IBCS2_VEOL] : _POSIX_VDISABLE;
+ } else {
+ bt->c_cc[VMIN] = st->c_cc[IBCS2_VMIN];
+ bt->c_cc[VTIME] = st->c_cc[IBCS2_VTIME];
+ }
+ bt->c_cc[VEOL2] =
+ st->c_cc[IBCS2_VEOL2] ? st->c_cc[IBCS2_VEOL2] : _POSIX_VDISABLE;
+#if 0
+ bt->c_cc[VSWTCH] =
+ st->c_cc[IBCS2_VSWTCH] ? st->c_cc[IBCS2_VSWTCH] : _POSIX_VDISABLE;
+#endif
+ bt->c_cc[VSTART] =
+ st->c_cc[IBCS2_VSTART] ? st->c_cc[IBCS2_VSTART] : _POSIX_VDISABLE;
+ bt->c_cc[VSTOP] =
+ st->c_cc[IBCS2_VSTOP] ? st->c_cc[IBCS2_VSTOP] : _POSIX_VDISABLE;
+ bt->c_cc[VSUSP] =
+ st->c_cc[IBCS2_VSUSP] ? st->c_cc[IBCS2_VSUSP] : _POSIX_VDISABLE;
+ bt->c_cc[VDSUSP] = _POSIX_VDISABLE;
+ bt->c_cc[VREPRINT] = _POSIX_VDISABLE;
+ bt->c_cc[VDISCARD] = _POSIX_VDISABLE;
+ bt->c_cc[VWERASE] = _POSIX_VDISABLE;
+ bt->c_cc[VLNEXT] = _POSIX_VDISABLE;
+ bt->c_cc[VSTATUS] = _POSIX_VDISABLE;
+}
+
+static void
+btios2stios(bt, st)
+ struct termios *bt;
+ struct ibcs2_termios *st;
+{
+ register u_long l, r;
+
+ l = bt->c_iflag; r = 0;
+ if (l & IGNBRK) r |= IBCS2_IGNBRK;
+ if (l & BRKINT) r |= IBCS2_BRKINT;
+ if (l & IGNPAR) r |= IBCS2_IGNPAR;
+ if (l & PARMRK) r |= IBCS2_PARMRK;
+ if (l & INPCK) r |= IBCS2_INPCK;
+ if (l & ISTRIP) r |= IBCS2_ISTRIP;
+ if (l & INLCR) r |= IBCS2_INLCR;
+ if (l & IGNCR) r |= IBCS2_IGNCR;
+ if (l & ICRNL) r |= IBCS2_ICRNL;
+ if (l & IXON) r |= IBCS2_IXON;
+ if (l & IXANY) r |= IBCS2_IXANY;
+ if (l & IXOFF) r |= IBCS2_IXOFF;
+ if (l & IMAXBEL) r |= IBCS2_IMAXBEL;
+ st->c_iflag = r;
+
+ l = bt->c_oflag; r = 0;
+ if (l & OPOST) r |= IBCS2_OPOST;
+ if (l & ONLCR) r |= IBCS2_ONLCR;
+ if (l & OXTABS) r |= IBCS2_TAB3;
+ st->c_oflag = r;
+
+ l = bt->c_cflag; r = 0;
+ switch (l & CSIZE) {
+ case CS5: r |= IBCS2_CS5; break;
+ case CS6: r |= IBCS2_CS6; break;
+ case CS7: r |= IBCS2_CS7; break;
+ case CS8: r |= IBCS2_CS8; break;
+ }
+ if (l & CSTOPB) r |= IBCS2_CSTOPB;
+ if (l & CREAD) r |= IBCS2_CREAD;
+ if (l & PARENB) r |= IBCS2_PARENB;
+ if (l & PARODD) r |= IBCS2_PARODD;
+ if (l & HUPCL) r |= IBCS2_HUPCL;
+ if (l & CLOCAL) r |= IBCS2_CLOCAL;
+ st->c_cflag = r;
+
+ l = bt->c_lflag; r = 0;
+ if (l & ISIG) r |= IBCS2_ISIG;
+ if (l & ICANON) r |= IBCS2_ICANON;
+ if (l & ECHO) r |= IBCS2_ECHO;
+ if (l & ECHOE) r |= IBCS2_ECHOE;
+ if (l & ECHOK) r |= IBCS2_ECHOK;
+ if (l & ECHONL) r |= IBCS2_ECHONL;
+ if (l & NOFLSH) r |= IBCS2_NOFLSH;
+ if (l & TOSTOP) r |= IBCS2_TOSTOP;
+ st->c_lflag = r;
+
+ l = ttspeedtab(bt->c_ospeed, sptab);
+ if (l >= 0)
+ st->c_cflag |= l;
+
+ st->c_cc[IBCS2_VINTR] =
+ bt->c_cc[VINTR] != _POSIX_VDISABLE ? bt->c_cc[VINTR] : 0;
+ st->c_cc[IBCS2_VQUIT] =
+ bt->c_cc[VQUIT] != _POSIX_VDISABLE ? bt->c_cc[VQUIT] : 0;
+ st->c_cc[IBCS2_VERASE] =
+ bt->c_cc[VERASE] != _POSIX_VDISABLE ? bt->c_cc[VERASE] : 0;
+ st->c_cc[IBCS2_VKILL] =
+ bt->c_cc[VKILL] != _POSIX_VDISABLE ? bt->c_cc[VKILL] : 0;
+ if (bt->c_lflag & ICANON) {
+ st->c_cc[IBCS2_VEOF] =
+ bt->c_cc[VEOF] != _POSIX_VDISABLE ? bt->c_cc[VEOF] : 0;
+ st->c_cc[IBCS2_VEOL] =
+ bt->c_cc[VEOL] != _POSIX_VDISABLE ? bt->c_cc[VEOL] : 0;
+ } else {
+ st->c_cc[IBCS2_VMIN] = bt->c_cc[VMIN];
+ st->c_cc[IBCS2_VTIME] = bt->c_cc[VTIME];
+ }
+ st->c_cc[IBCS2_VEOL2] =
+ bt->c_cc[VEOL2] != _POSIX_VDISABLE ? bt->c_cc[VEOL2] : 0;
+ st->c_cc[IBCS2_VSWTCH] =
+ 0;
+ st->c_cc[IBCS2_VSUSP] =
+ bt->c_cc[VSUSP] != _POSIX_VDISABLE ? bt->c_cc[VSUSP] : 0;
+ st->c_cc[IBCS2_VSTART] =
+ bt->c_cc[VSTART] != _POSIX_VDISABLE ? bt->c_cc[VSTART] : 0;
+ st->c_cc[IBCS2_VSTOP] =
+ bt->c_cc[VSTOP] != _POSIX_VDISABLE ? bt->c_cc[VSTOP] : 0;
+
+ st->c_line = 0;
+}
+
+static void
+stios2stio(ts, t)
+ struct ibcs2_termios *ts;
+ struct ibcs2_termio *t;
+{
+
+ t->c_iflag = ts->c_iflag;
+ t->c_oflag = ts->c_oflag;
+ t->c_cflag = ts->c_cflag;
+ t->c_lflag = ts->c_lflag;
+ t->c_line = ts->c_line;
+ bcopy(ts->c_cc, t->c_cc, IBCS2_NCC);
+}
+
+static void
+stio2stios(t, ts)
+ struct ibcs2_termio *t;
+ struct ibcs2_termios *ts;
+{
+
+ ts->c_iflag = t->c_iflag;
+ ts->c_oflag = t->c_oflag;
+ ts->c_cflag = t->c_cflag;
+ ts->c_lflag = t->c_lflag;
+ ts->c_line = t->c_line;
+ bcopy(t->c_cc, ts->c_cc, IBCS2_NCC);
+}
+
+int
+ibcs2_sys_ioctl(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct ibcs2_sys_ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) cmd;
+ syscallarg(caddr_t) data;
+ } */ *uap = v;
+ struct filedesc *fdp = p->p_fd;
+ struct file *fp;
+ int (*ctl)();
+ int error;
+
+ if (SCARG(uap, fd) < 0 || SCARG(uap, fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL) {
+ DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid,
+ SCARG(uap, fd)));
+ return EBADF;
+ }
+
+ if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
+ DPRINTF(("ibcs2_ioctl(%d): bad fp flag ", p->p_pid));
+ return EBADF;
+ }
+
+ ctl = fp->f_ops->fo_ioctl;
+
+ switch (SCARG(uap, cmd)) {
+ case IBCS2_TCGETA:
+ case IBCS2_XCGETA:
+ case IBCS2_OXCGETA:
+ {
+ struct termios bts;
+ struct ibcs2_termios sts;
+ struct ibcs2_termio st;
+
+ if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
+ return error;
+
+ btios2stios (&bts, &sts);
+ if (SCARG(uap, cmd) == IBCS2_TCGETA) {
+ stios2stio (&sts, &st);
+ error = copyout((caddr_t)&st, SCARG(uap, data),
+ sizeof (st));
+ if (error)
+ DPRINTF(("ibcs2_ioctl(%d): copyout failed ",
+ p->p_pid));
+ return error;
+ } else
+ return copyout((caddr_t)&sts, SCARG(uap, data),
+ sizeof (sts));
+ /*NOTREACHED*/
+ }
+
+ case IBCS2_TCSETA:
+ case IBCS2_TCSETAW:
+ case IBCS2_TCSETAF:
+ {
+ struct termios bts;
+ struct ibcs2_termios sts;
+ struct ibcs2_termio st;
+
+ if ((error = copyin(SCARG(uap, data), (caddr_t)&st,
+ sizeof(st))) != 0) {
+ DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ",
+ p->p_pid));
+ return error;
+ }
+
+ /* get full BSD termios so we don't lose information */
+ if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0) {
+ DPRINTF(("ibcs2_ioctl(%d): TCSET ctl failed fd %d ",
+ p->p_pid, SCARG(uap, fd)));
+ return error;
+ }
+
+ /*
+ * convert to iBCS2 termios, copy in information from
+ * termio, and convert back, then set new values.
+ */
+ btios2stios(&bts, &sts);
+ stio2stios(&st, &sts);
+ stios2btios(&sts, &bts);
+
+ return (*ctl)(fp, SCARG(uap, cmd) - IBCS2_TCSETA + TIOCSETA,
+ (caddr_t)&bts, p);
+ }
+
+ case IBCS2_XCSETA:
+ case IBCS2_XCSETAW:
+ case IBCS2_XCSETAF:
+ {
+ struct termios bts;
+ struct ibcs2_termios sts;
+
+ if ((error = copyin(SCARG(uap, data), (caddr_t)&sts,
+ sizeof (sts))) != 0) {
+ return error;
+ }
+ stios2btios (&sts, &bts);
+ return (*ctl)(fp, SCARG(uap, cmd) - IBCS2_XCSETA + TIOCSETA,
+ (caddr_t)&bts, p);
+ }
+
+ case IBCS2_OXCSETA:
+ case IBCS2_OXCSETAW:
+ case IBCS2_OXCSETAF:
+ {
+ struct termios bts;
+ struct ibcs2_termios sts;
+
+ if ((error = copyin(SCARG(uap, data), (caddr_t)&sts,
+ sizeof (sts))) != 0) {
+ return error;
+ }
+ stios2btios (&sts, &bts);
+ return (*ctl)(fp, SCARG(uap, cmd) - IBCS2_OXCSETA + TIOCSETA,
+ (caddr_t)&bts, p);
+ }
+
+ case IBCS2_TCSBRK:
+ DPRINTF(("ibcs2_ioctl(%d): TCSBRK ", p->p_pid));
+ return ENOSYS;
+
+ case IBCS2_TCXONC:
+ DPRINTF(("ibcs2_ioctl(%d): TCXONC ", p->p_pid));
+ return ENOSYS;
+
+ case IBCS2_TCFLSH:
+ DPRINTF(("ibcs2_ioctl(%d): TCFLSH ", p->p_pid));
+ return ENOSYS;
+
+ case IBCS2_TIOCGWINSZ:
+ SCARG(uap, cmd) = TIOCGWINSZ;
+ return sys_ioctl(p, uap, retval);
+
+ case IBCS2_TIOCSWINSZ:
+ SCARG(uap, cmd) = TIOCSWINSZ;
+ return sys_ioctl(p, uap, retval);
+
+ case IBCS2_TIOCGPGRP:
+ return copyout((caddr_t)&p->p_pgrp->pg_id, SCARG(uap, data),
+ sizeof(p->p_pgrp->pg_id));
+
+ case IBCS2_TIOCSPGRP: /* XXX - is uap->data a pointer to pgid? */
+ {
+ struct sys_setpgid_args sa;
+
+ SCARG(&sa, pid) = 0;
+ SCARG(&sa, pgid) = (int)SCARG(uap, data);
+ if (error = sys_setpgid(p, &sa, retval))
+ return error;
+ return 0;
+ }
+
+ case IBCS2_TCGETSC: /* SCO console - get scancode flags */
+ return ENOSYS;
+
+ case IBCS2_TCSETSC: /* SCO console - set scancode flags */
+ return ENOSYS;
+
+ case IBCS2_SIOCSOCKSYS:
+ return ibcs2_socksys(p, uap, retval);
+
+ case IBCS2_I_NREAD: /* STREAMS */
+ SCARG(uap, cmd) = FIONREAD;
+ return sys_ioctl(p, uap, retval);
+
+ default:
+ DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%lx ",
+ p->p_pid, SCARG(uap, cmd)));
+ return ENOSYS;
+ }
+ return ENOSYS;
+}
+