summaryrefslogtreecommitdiff
path: root/sys/compat/hpux/hpux_tty.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /sys/compat/hpux/hpux_tty.c
initial import of NetBSD tree
Diffstat (limited to 'sys/compat/hpux/hpux_tty.c')
-rw-r--r--sys/compat/hpux/hpux_tty.c548
1 files changed, 548 insertions, 0 deletions
diff --git a/sys/compat/hpux/hpux_tty.c b/sys/compat/hpux/hpux_tty.c
new file mode 100644
index 00000000000..d95e1731b5f
--- /dev/null
+++ b/sys/compat/hpux/hpux_tty.c
@@ -0,0 +1,548 @@
+/* $NetBSD: hpux_tty.c,v 1.11 1995/10/07 06:26:40 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * 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. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ * from: Utah $Hdr: hpux_tty.c 1.14 93/08/05$
+ *
+ * @(#)hpux_tty.c 8.3 (Berkeley) 1/12/94
+ */
+
+/*
+ * stty/gtty/termio emulation stuff
+ */
+
+#ifndef COMPAT_43
+#define COMPAT_43
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/filedesc.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/tty.h>
+#include <sys/file.h>
+#include <sys/conf.h>
+#include <sys/buf.h>
+#include <sys/kernel.h>
+
+#include <compat/hpux/hpux.h>
+#include <compat/hpux/hpux_termio.h>
+#include <compat/hpux/hpux_syscallargs.h>
+
+/*
+ * Map BSD/POSIX style termios info to and from SYS5 style termio stuff.
+ */
+int
+hpux_termio(fd, com, data, p)
+ int fd, com;
+ caddr_t data;
+ struct proc *p;
+{
+ struct file *fp;
+ struct termios tios;
+ struct hpux_termios htios;
+ int line, error, (*ioctlrout)();
+ int newi = 0;
+
+ fp = p->p_fd->fd_ofiles[fd];
+ ioctlrout = fp->f_ops->fo_ioctl;
+ switch (com) {
+ case HPUXTCGETATTR:
+ newi = 1;
+ /* fall into ... */
+ case HPUXTCGETA:
+ /*
+ * Get BSD terminal state
+ */
+ if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p))
+ break;
+ bzero((char *)&htios, sizeof htios);
+ /*
+ * Set iflag.
+ * Same through ICRNL, no BSD equivs for IUCLC, IENQAK
+ */
+ htios.c_iflag = tios.c_iflag & 0x1ff;
+ if (tios.c_iflag & IXON)
+ htios.c_iflag |= TIO_IXON;
+ if (tios.c_iflag & IXOFF)
+ htios.c_iflag |= TIO_IXOFF;
+ if (tios.c_iflag & IXANY)
+ htios.c_iflag |= TIO_IXANY;
+ /*
+ * Set oflag.
+ * No BSD equivs for OLCUC/OCRNL/ONOCR/ONLRET/OFILL/OFDEL
+ * or any of the delays.
+ */
+ if (tios.c_oflag & OPOST)
+ htios.c_oflag |= TIO_OPOST;
+ if (tios.c_oflag & ONLCR)
+ htios.c_oflag |= TIO_ONLCR;
+ if (tios.c_oflag & OXTABS)
+ htios.c_oflag |= TIO_TAB3;
+ /*
+ * Set cflag.
+ * Baud from ospeed, rest from cflag.
+ */
+ htios.c_cflag = bsdtohpuxbaud(tios.c_ospeed);
+ switch (tios.c_cflag & CSIZE) {
+ case CS5:
+ htios.c_cflag |= TIO_CS5; break;
+ case CS6:
+ htios.c_cflag |= TIO_CS6; break;
+ case CS7:
+ htios.c_cflag |= TIO_CS7; break;
+ case CS8:
+ htios.c_cflag |= TIO_CS8; break;
+ }
+ if (tios.c_cflag & CSTOPB)
+ htios.c_cflag |= TIO_CSTOPB;
+ if (tios.c_cflag & CREAD)
+ htios.c_cflag |= TIO_CREAD;
+ if (tios.c_cflag & PARENB)
+ htios.c_cflag |= TIO_PARENB;
+ if (tios.c_cflag & PARODD)
+ htios.c_cflag |= TIO_PARODD;
+ if (tios.c_cflag & HUPCL)
+ htios.c_cflag |= TIO_HUPCL;
+ if (tios.c_cflag & CLOCAL)
+ htios.c_cflag |= TIO_CLOCAL;
+ /*
+ * Set lflag.
+ * No BSD equiv for XCASE.
+ */
+ if (tios.c_lflag & ECHOE)
+ htios.c_lflag |= TIO_ECHOE;
+ if (tios.c_lflag & ECHOK)
+ htios.c_lflag |= TIO_ECHOK;
+ if (tios.c_lflag & ECHO)
+ htios.c_lflag |= TIO_ECHO;
+ if (tios.c_lflag & ECHONL)
+ htios.c_lflag |= TIO_ECHONL;
+ if (tios.c_lflag & ISIG)
+ htios.c_lflag |= TIO_ISIG;
+ if (tios.c_lflag & ICANON)
+ htios.c_lflag |= TIO_ICANON;
+ if (tios.c_lflag & NOFLSH)
+ htios.c_lflag |= TIO_NOFLSH;
+ /*
+ * Line discipline
+ */
+ if (!newi) {
+ line = 0;
+ (void) (*ioctlrout)(fp, TIOCGETD, (caddr_t)&line, p);
+ htios.c_reserved = line;
+ }
+ /*
+ * Set editing chars.
+ * No BSD equiv for VSWTCH.
+ */
+ htios.c_cc[HPUXVINTR] = tios.c_cc[VINTR];
+ htios.c_cc[HPUXVQUIT] = tios.c_cc[VQUIT];
+ htios.c_cc[HPUXVERASE] = tios.c_cc[VERASE];
+ htios.c_cc[HPUXVKILL] = tios.c_cc[VKILL];
+ htios.c_cc[HPUXVEOF] = tios.c_cc[VEOF];
+ htios.c_cc[HPUXVEOL] = tios.c_cc[VEOL];
+ htios.c_cc[HPUXVEOL2] = tios.c_cc[VEOL2];
+ htios.c_cc[HPUXVSWTCH] = 0;
+#if 1
+ /*
+ * XXX since VMIN and VTIME are not implemented,
+ * we need to return something reasonable.
+ * Otherwise a GETA/SETA combo would always put
+ * the tty in non-blocking mode (since VMIN == VTIME == 0).
+ */
+ if (fp->f_flag & FNONBLOCK) {
+ htios.c_cc[HPUXVMINS] = 0;
+ htios.c_cc[HPUXVTIMES] = 0;
+ } else {
+ htios.c_cc[HPUXVMINS] = 6;
+ htios.c_cc[HPUXVTIMES] = 1;
+ }
+#else
+ htios.c_cc[HPUXVMINS] = tios.c_cc[VMIN];
+ htios.c_cc[HPUXVTIMES] = tios.c_cc[VTIME];
+#endif
+ htios.c_cc[HPUXVSUSP] = tios.c_cc[VSUSP];
+ htios.c_cc[HPUXVSTART] = tios.c_cc[VSTART];
+ htios.c_cc[HPUXVSTOP] = tios.c_cc[VSTOP];
+ if (newi)
+ bcopy((char *)&htios, data, sizeof htios);
+ else
+ termiostotermio(&htios, (struct hpux_termio *)data);
+ break;
+
+ case HPUXTCSETATTR:
+ case HPUXTCSETATTRD:
+ case HPUXTCSETATTRF:
+ newi = 1;
+ /* fall into ... */
+ case HPUXTCSETA:
+ case HPUXTCSETAW:
+ case HPUXTCSETAF:
+ /*
+ * Get old characteristics and determine if we are a tty.
+ */
+ if (error = (*ioctlrout)(fp, TIOCGETA, (caddr_t)&tios, p))
+ break;
+ if (newi)
+ bcopy(data, (char *)&htios, sizeof htios);
+ else
+ termiototermios((struct termio *)data, &htios, &tios);
+ /*
+ * Set iflag.
+ * Same through ICRNL, no HP-UX equiv for IMAXBEL
+ */
+ tios.c_iflag &= ~(IXON|IXOFF|IXANY|0x1ff);
+ tios.c_iflag |= htios.c_iflag & 0x1ff;
+ if (htios.c_iflag & TIO_IXON)
+ tios.c_iflag |= IXON;
+ if (htios.c_iflag & TIO_IXOFF)
+ tios.c_iflag |= IXOFF;
+ if (htios.c_iflag & TIO_IXANY)
+ tios.c_iflag |= IXANY;
+ /*
+ * Set oflag.
+ * No HP-UX equiv for ONOEOT
+ */
+ tios.c_oflag &= ~(OPOST|ONLCR|OXTABS);
+ if (htios.c_oflag & TIO_OPOST)
+ tios.c_oflag |= OPOST;
+ if (htios.c_oflag & TIO_ONLCR)
+ tios.c_oflag |= ONLCR;
+ if (htios.c_oflag & TIO_TAB3)
+ tios.c_oflag |= OXTABS;
+ /*
+ * Set cflag.
+ * No HP-UX equiv for CCTS_OFLOW/CCTS_IFLOW/MDMBUF
+ */
+ tios.c_cflag &=
+ ~(CSIZE|CSTOPB|CREAD|PARENB|PARODD|HUPCL|CLOCAL);
+ switch (htios.c_cflag & TIO_CSIZE) {
+ case TIO_CS5:
+ tios.c_cflag |= CS5; break;
+ case TIO_CS6:
+ tios.c_cflag |= CS6; break;
+ case TIO_CS7:
+ tios.c_cflag |= CS7; break;
+ case TIO_CS8:
+ tios.c_cflag |= CS8; break;
+ }
+ if (htios.c_cflag & TIO_CSTOPB)
+ tios.c_cflag |= CSTOPB;
+ if (htios.c_cflag & TIO_CREAD)
+ tios.c_cflag |= CREAD;
+ if (htios.c_cflag & TIO_PARENB)
+ tios.c_cflag |= PARENB;
+ if (htios.c_cflag & TIO_PARODD)
+ tios.c_cflag |= PARODD;
+ if (htios.c_cflag & TIO_HUPCL)
+ tios.c_cflag |= HUPCL;
+ if (htios.c_cflag & TIO_CLOCAL)
+ tios.c_cflag |= CLOCAL;
+ /*
+ * Set lflag.
+ * No HP-UX equiv for ECHOKE/ECHOPRT/ECHOCTL
+ * IEXTEN treated as part of ICANON
+ */
+ tios.c_lflag &= ~(ECHOE|ECHOK|ECHO|ISIG|ICANON|IEXTEN|NOFLSH);
+ if (htios.c_lflag & TIO_ECHOE)
+ tios.c_lflag |= ECHOE;
+ if (htios.c_lflag & TIO_ECHOK)
+ tios.c_lflag |= ECHOK;
+ if (htios.c_lflag & TIO_ECHO)
+ tios.c_lflag |= ECHO;
+ if (htios.c_lflag & TIO_ECHONL)
+ tios.c_lflag |= ECHONL;
+ if (htios.c_lflag & TIO_ISIG)
+ tios.c_lflag |= ISIG;
+ if (htios.c_lflag & TIO_ICANON)
+ tios.c_lflag |= (ICANON|IEXTEN);
+ if (htios.c_lflag & TIO_NOFLSH)
+ tios.c_lflag |= NOFLSH;
+ /*
+ * Set editing chars.
+ * No HP-UX equivs of VWERASE/VREPRINT/VDSUSP/VLNEXT
+ * /VDISCARD/VSTATUS/VERASE2
+ */
+ tios.c_cc[VINTR] = htios.c_cc[HPUXVINTR];
+ tios.c_cc[VQUIT] = htios.c_cc[HPUXVQUIT];
+ tios.c_cc[VERASE] = htios.c_cc[HPUXVERASE];
+ tios.c_cc[VKILL] = htios.c_cc[HPUXVKILL];
+ tios.c_cc[VEOF] = htios.c_cc[HPUXVEOF];
+ tios.c_cc[VEOL] = htios.c_cc[HPUXVEOL];
+ tios.c_cc[VEOL2] = htios.c_cc[HPUXVEOL2];
+ tios.c_cc[VMIN] = htios.c_cc[HPUXVMINS];
+ tios.c_cc[VTIME] = htios.c_cc[HPUXVTIMES];
+ tios.c_cc[VSUSP] = htios.c_cc[HPUXVSUSP];
+ tios.c_cc[VSTART] = htios.c_cc[HPUXVSTART];
+ tios.c_cc[VSTOP] = htios.c_cc[HPUXVSTOP];
+
+ /*
+ * Set the new stuff
+ */
+ if (com == HPUXTCSETA || com == HPUXTCSETATTR)
+ com = TIOCSETA;
+ else if (com == HPUXTCSETAW || com == HPUXTCSETATTRD)
+ com = TIOCSETAW;
+ else
+ com = TIOCSETAF;
+ error = (*ioctlrout)(fp, com, (caddr_t)&tios, p);
+ if (error == 0) {
+ /*
+ * Set line discipline
+ */
+ if (!newi) {
+ line = htios.c_reserved;
+ (void) (*ioctlrout)(fp, TIOCSETD,
+ (caddr_t)&line, p);
+ }
+ /*
+ * Set non-blocking IO if VMIN == VTIME == 0, clear
+ * if not. Should handle the other cases as well.
+ * Note it isn't correct to just turn NBIO off like
+ * we do as it could be on as the result of a fcntl
+ * operation.
+ *
+ * XXX - wouldn't need to do this at all if VMIN/VTIME
+ * were implemented.
+ */
+ {
+ struct hpux_sys_fcntl_args {
+ int fdes, cmd, arg;
+ } args;
+ int flags, nbio;
+
+ nbio = (htios.c_cc[HPUXVMINS] == 0 &&
+ htios.c_cc[HPUXVTIMES] == 0);
+ if (nbio && (fp->f_flag & FNONBLOCK) == 0 ||
+ !nbio && (fp->f_flag & FNONBLOCK)) {
+ args.fdes = fd;
+ args.cmd = F_GETFL;
+ args.arg = 0;
+ (void) hpux_sys_fcntl(p, &args, &flags);
+ if (nbio)
+ flags |= HPUXNDELAY;
+ else
+ flags &= ~HPUXNDELAY;
+ args.cmd = F_SETFL;
+ args.arg = flags;
+ (void) hpux_sys_fcntl(p, &args, &flags);
+ }
+ }
+ }
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ return(error);
+}
+
+int
+termiototermios(tio, tios, bsdtios)
+ struct hpux_termio *tio;
+ struct hpux_termios *tios;
+ struct termios *bsdtios;
+{
+ int i;
+
+ bzero((char *)tios, sizeof *tios);
+ tios->c_iflag = tio->c_iflag;
+ tios->c_oflag = tio->c_oflag;
+ tios->c_cflag = tio->c_cflag;
+ tios->c_lflag = tio->c_lflag;
+ tios->c_reserved = tio->c_line;
+ for (i = 0; i <= HPUXVSWTCH; i++)
+ tios->c_cc[i] = tio->c_cc[i];
+ if (tios->c_lflag & TIO_ICANON) {
+ tios->c_cc[HPUXVEOF] = tio->c_cc[HPUXVEOF];
+ tios->c_cc[HPUXVEOL] = tio->c_cc[HPUXVEOL];
+ tios->c_cc[HPUXVMINS] = 0;
+ tios->c_cc[HPUXVTIMES] = 0;
+ } else {
+ tios->c_cc[HPUXVEOF] = 0;
+ tios->c_cc[HPUXVEOL] = 0;
+ tios->c_cc[HPUXVMINS] = tio->c_cc[HPUXVMIN];
+ tios->c_cc[HPUXVTIMES] = tio->c_cc[HPUXVTIME];
+ }
+ tios->c_cc[HPUXVSUSP] = bsdtios->c_cc[VSUSP];
+ tios->c_cc[HPUXVSTART] = bsdtios->c_cc[VSTART];
+ tios->c_cc[HPUXVSTOP] = bsdtios->c_cc[VSTOP];
+}
+
+int
+termiostotermio(tios, tio)
+ struct hpux_termios *tios;
+ struct hpux_termio *tio;
+{
+ int i;
+
+ tio->c_iflag = tios->c_iflag;
+ tio->c_oflag = tios->c_oflag;
+ tio->c_cflag = tios->c_cflag;
+ tio->c_lflag = tios->c_lflag;
+ tio->c_line = tios->c_reserved;
+ for (i = 0; i <= HPUXVSWTCH; i++)
+ tio->c_cc[i] = tios->c_cc[i];
+ if (tios->c_lflag & TIO_ICANON) {
+ tio->c_cc[HPUXVEOF] = tios->c_cc[HPUXVEOF];
+ tio->c_cc[HPUXVEOL] = tios->c_cc[HPUXVEOL];
+ } else {
+ tio->c_cc[HPUXVMIN] = tios->c_cc[HPUXVMINS];
+ tio->c_cc[HPUXVTIME] = tios->c_cc[HPUXVTIMES];
+ }
+}
+
+int
+bsdtohpuxbaud(bsdspeed)
+ long bsdspeed;
+{
+ switch (bsdspeed) {
+ case B0: return(TIO_B0);
+ case B50: return(TIO_B50);
+ case B75: return(TIO_B75);
+ case B110: return(TIO_B110);
+ case B134: return(TIO_B134);
+ case B150: return(TIO_B150);
+ case B200: return(TIO_B200);
+ case B300: return(TIO_B300);
+ case B600: return(TIO_B600);
+ case B1200: return(TIO_B1200);
+ case B1800: return(TIO_B1800);
+ case B2400: return(TIO_B2400);
+ case B4800: return(TIO_B4800);
+ case B9600: return(TIO_B9600);
+ case B19200: return(TIO_B19200);
+ case B38400: return(TIO_B38400);
+ default: return(TIO_B0);
+ }
+}
+
+int
+hpuxtobsdbaud(hpux_speed)
+ int hpux_speed;
+{
+ static char hpuxtobsdbaudtab[32] = {
+ B0, B50, B75, B110, B134, B150, B200, B300,
+ B600, B0, B1200, B1800, B2400, B0, B4800, B0,
+ B9600, B19200, B38400, B0, B0, B0, B0, B0,
+ B0, B0, B0, B0, B0, B0, EXTA, EXTB
+ };
+
+ return(hpuxtobsdbaudtab[hpux_speed & TIO_CBAUD]);
+}
+
+#ifdef COMPAT_HPUX_6X
+
+int
+compat_hpux_6x_sys_gtty(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct compat_hpux_6x_sys_gtty_args *uap = v;
+
+ return (getsettty(p, SCARG(uap, fd), HPUXTIOCGETP, SCARG(uap, arg)));
+}
+
+int
+compat_hpux_6x_sys_stty(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct compat_hpux_6x_sys_stty_args *uap = v;
+
+ return (getsettty(p, SCARG(uap, fd), HPUXTIOCSETP, SCARG(uap, arg)));
+}
+
+/*
+ * Simplified version of ioctl() for use by
+ * gtty/stty and TIOCGETP/TIOCSETP.
+ */
+int
+getsettty(p, fdes, com, cmarg)
+ struct proc *p;
+ int fdes, com;
+ caddr_t cmarg;
+{
+ register struct filedesc *fdp = p->p_fd;
+ register struct file *fp;
+ struct hpux_sgttyb hsb;
+ struct sgttyb sb;
+ int error;
+
+ if (((unsigned)fdes) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[fdes]) == NULL)
+ return (EBADF);
+ if ((fp->f_flag & (FREAD|FWRITE)) == 0)
+ return (EBADF);
+ if (com == HPUXTIOCSETP) {
+ if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb))
+ return (error);
+ sb.sg_ispeed = hsb.sg_ispeed;
+ sb.sg_ospeed = hsb.sg_ospeed;
+ sb.sg_erase = hsb.sg_erase;
+ sb.sg_kill = hsb.sg_kill;
+ sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
+ if (hsb.sg_flags & V7_XTABS)
+ sb.sg_flags |= XTABS;
+ if (hsb.sg_flags & V7_HUPCL)
+ (void)(*fp->f_ops->fo_ioctl)
+ (fp, TIOCHPCL, (caddr_t)0, p);
+ com = TIOCSETP;
+ } else {
+ bzero((caddr_t)&hsb, sizeof hsb);
+ com = TIOCGETP;
+ }
+ error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb, p);
+ if (error == 0 && com == TIOCGETP) {
+ hsb.sg_ispeed = sb.sg_ispeed;
+ hsb.sg_ospeed = sb.sg_ospeed;
+ hsb.sg_erase = sb.sg_erase;
+ hsb.sg_kill = sb.sg_kill;
+ hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL);
+ if (sb.sg_flags & XTABS)
+ hsb.sg_flags |= V7_XTABS;
+ error = copyout((caddr_t)&hsb, cmarg, sizeof hsb);
+ }
+ return (error);
+}
+#endif