141486Smckusick /* 241486Smckusick * Copyright (c) 1988 University of Utah. 341486Smckusick * Copyright (c) 1990 The Regents of the University of California. 441486Smckusick * All rights reserved. 541486Smckusick * 641486Smckusick * This code is derived from software contributed to Berkeley by 741486Smckusick * the Systems Programming Group of the University of Utah Computer 841486Smckusick * Science Department. 941486Smckusick * 1041486Smckusick * %sccs.include.redist.c% 1141486Smckusick * 1241486Smckusick * from: Utah $Hdr: hpux_tty.c 1.7 89/04/11$ 1341486Smckusick * 14*43711Smckusick * @(#)hpux_tty.c 7.3 (Berkeley) 06/24/90 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1841486Smckusick * stty/gtty/termio emulation stuff 1941486Smckusick */ 2041486Smckusick #ifdef HPUXCOMPAT 2141486Smckusick 2241486Smckusick #include "param.h" 2341486Smckusick #include "systm.h" 2441486Smckusick #include "user.h" 2541486Smckusick #include "ioctl.h" 2641486Smckusick #include "tty.h" 2741486Smckusick #include "proc.h" 2841486Smckusick #include "file.h" 2941486Smckusick #include "conf.h" 3041486Smckusick #include "buf.h" 3141486Smckusick #include "uio.h" 3241486Smckusick #include "kernel.h" 3341486Smckusick 3441486Smckusick #include "hpux.h" 3541486Smckusick #include "hpux_termio.h" 3641486Smckusick 3741486Smckusick char hpuxtobsdbaud[32] = { 3841486Smckusick B0, B50, B75, B110, B134, B150, B200, B300, 3941486Smckusick B600, B0, B1200, B1800, B2400, B0, B4800, B0, 4041486Smckusick B9600, EXTA, EXTB, B0, B0, B0, B0, B0, 4141486Smckusick B0, B0, B0, B0, B0, B0, B0, B0 4241486Smckusick }; 4341486Smckusick 4441486Smckusick char bsdtohpuxbaud[16] = { 4541486Smckusick TIO_B0, TIO_B50, TIO_B75, TIO_B110, 4641486Smckusick TIO_B134, TIO_B150, TIO_B200, TIO_B300, 4741486Smckusick TIO_B600, TIO_B1200, TIO_B1800, TIO_B2400, 4841486Smckusick TIO_B4800, TIO_B9600, TIO_B19200, TIO_B38400 4941486Smckusick }; 5041486Smckusick 5141486Smckusick /* 5241486Smckusick * Map BSD style sgtty info to and from SYS5 style termio stuff. 5341486Smckusick * Map BSD style sgtty info to and from V7 style sgtty stuff. 5441486Smckusick */ 5541486Smckusick hpuxtermio(fp, com, data) 5641486Smckusick struct file *fp; 5741486Smckusick caddr_t data; 5841486Smckusick { 5941486Smckusick struct sgttyb sg; 6041486Smckusick struct bsdtchars { /* avoid problem with ttychars.h */ 6141486Smckusick char bsdt_intrc; 6241486Smckusick char bsdt_quitc; 6341486Smckusick char bsdt_startc; 6441486Smckusick char bsdt_stopc; 6541486Smckusick char bsdt_eofc; 6641486Smckusick char bsdt_brkc; 6741486Smckusick } tc; 6841486Smckusick struct bsdltchars { /* avoid problem with ttychars.h */ 6941486Smckusick char bsdt_suspc; 7041486Smckusick char bsdt_dsuspc; 7141486Smckusick char bsdt_rprntc; 7241486Smckusick char bsdt_flushc; 7341486Smckusick char bsdt_werasc; 7441486Smckusick char bsdt_lnextc; 7541486Smckusick } ltc; 7643453Shibler int lmode, error, (*ioctlrout)(); 7741486Smckusick register u_short flag; 7841486Smckusick register struct hpuxtermio *tiop; 7941486Smckusick 8041486Smckusick ioctlrout = fp->f_ops->fo_ioctl; 8141486Smckusick tiop = (struct hpuxtermio *)data; 8241486Smckusick switch (com) { 8341486Smckusick case HPUXTCGETA: 8441486Smckusick /* get everything we might need */ 8541486Smckusick bzero(data, sizeof(struct hpuxtermio)); 8643453Shibler if (error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg)) 8741486Smckusick break; 8841486Smckusick (void) ioctlrout(fp, TIOCGETC, (caddr_t)&tc); 8941486Smckusick (void) ioctlrout(fp, TIOCLGET, (caddr_t)&lmode); 9041486Smckusick 9141486Smckusick /* set baud rate */ 9241486Smckusick tiop->c_cflag = (u_short)bsdtohpuxbaud[sg.sg_ispeed&0xF]; 9341486Smckusick 9441486Smckusick /* set editing chars except for EOF/EOL (set below) */ 9541486Smckusick tiop->c_cc[HPUXVINTR] = tc.bsdt_intrc; 9641486Smckusick tiop->c_cc[HPUXVQUIT] = tc.bsdt_quitc; 9741486Smckusick tiop->c_cc[HPUXVERASE] = sg.sg_erase; 9841486Smckusick tiop->c_cc[HPUXVKILL] = sg.sg_kill; 9941486Smckusick 10041486Smckusick /* set flags */ 10141486Smckusick flag = sg.sg_flags; 10241486Smckusick if ((flag & TBDELAY) == XTABS) 10341486Smckusick tiop->c_oflag |= TIO_TAB3; 10441486Smckusick else if (flag & TBDELAY) 10541486Smckusick tiop->c_oflag |= TIO_TAB1; 10641486Smckusick if (flag & LCASE) { 10741486Smckusick tiop->c_iflag |= TIO_IUCLC; 10841486Smckusick tiop->c_oflag |= TIO_OLCUC; 10941486Smckusick tiop->c_lflag |= TIO_XCASE; 11041486Smckusick } 11141486Smckusick if (flag & ECHO) 11241486Smckusick tiop->c_lflag |= TIO_ECHO; 11341486Smckusick if (flag & CRMOD) { 11441486Smckusick tiop->c_iflag |= TIO_ICRNL; 11541486Smckusick tiop->c_oflag |= TIO_ONLCR; 11641486Smckusick if (flag & CR1) 11741486Smckusick tiop->c_oflag |= TIO_CR1; 11841486Smckusick if (flag & CR2) 11941486Smckusick tiop->c_oflag |= TIO_CR2|TIO_ONOCR; 12041486Smckusick } else { 12141486Smckusick tiop->c_oflag |= TIO_ONLRET; 12241486Smckusick if (flag & NL1) 12341486Smckusick tiop->c_oflag |= TIO_CR1; 12441486Smckusick if (flag & NL2) 12541486Smckusick tiop->c_oflag |= TIO_CR2; 12641486Smckusick } 12741486Smckusick if (flag & RAW) { 12841486Smckusick tiop->c_cflag |= TIO_CS8; 12941486Smckusick tiop->c_iflag &= ~(TIO_ICRNL|TIO_IUCLC); 13041486Smckusick tiop->c_cc[HPUXVMIN] = 6; 13141486Smckusick tiop->c_cc[HPUXVTIME] = 1; 13241486Smckusick } else { 13341486Smckusick tiop->c_iflag |= TIO_BRKINT; 13441486Smckusick if (tc.bsdt_startc == CSTART && tc.bsdt_stopc == CSTOP) 13541486Smckusick tiop->c_iflag |= TIO_IXON; 13641486Smckusick if (flag & TANDEM) 13741486Smckusick tiop->c_iflag |= TIO_IXOFF; 13841486Smckusick else if ((lmode & LDECCTQ) == 0) 13941486Smckusick tiop->c_iflag |= TIO_IXANY; 14041486Smckusick if ((lmode & LLITOUT) == 0) { 14141486Smckusick tiop->c_iflag |= TIO_IGNPAR; 14241486Smckusick tiop->c_oflag |= TIO_OPOST; 14341486Smckusick } 14441486Smckusick if (lmode & LPASS8) 14541486Smckusick tiop->c_cflag |= TIO_CS8; 14641486Smckusick else 14741486Smckusick tiop->c_iflag |= TIO_ISTRIP; 14841486Smckusick tiop->c_cflag |= TIO_CS7|TIO_PARENB; 14941486Smckusick tiop->c_lflag |= TIO_ISIG; 15041486Smckusick if (flag & CBREAK) { 15141486Smckusick tiop->c_cc[HPUXVMIN] = 6; 15241486Smckusick tiop->c_cc[HPUXVTIME] = 1; 15341486Smckusick } else { 15441486Smckusick tiop->c_lflag |= TIO_ICANON|TIO_ECHOK; 15541486Smckusick if (lmode & LCRTERA) 15641486Smckusick tiop->c_lflag |= TIO_ECHOE; 15741486Smckusick tiop->c_cc[HPUXVEOF] = tc.bsdt_eofc; 15841486Smckusick tiop->c_cc[HPUXVEOL] = tc.bsdt_brkc; 15941486Smckusick } 16041486Smckusick } 16141486Smckusick tiop->c_cflag |= TIO_PARENB; 16241486Smckusick if (flag & ODDP) { 16341486Smckusick if (flag & EVENP) 16441486Smckusick tiop->c_cflag &= ~TIO_PARENB; 16541486Smckusick tiop->c_cflag |= TIO_PARODD; 16641486Smckusick } 16741486Smckusick if (tiop->c_cflag & TIO_PARENB) 16841486Smckusick tiop->c_iflag |= TIO_INPCK; 16941486Smckusick if (flag & VTDELAY) 17041486Smckusick tiop->c_oflag |= TIO_FFDLY; 17141486Smckusick if (flag & BSDELAY) 17241486Smckusick tiop->c_oflag |= TIO_BSDLY; 17341486Smckusick break; 17441486Smckusick 17541486Smckusick case HPUXTCSETA: 17641486Smckusick case HPUXTCSETAW: 17741486Smckusick case HPUXTCSETAF: 17841486Smckusick /* get old lmode and determine if we are a tty */ 17943453Shibler if (error = ioctlrout(fp, TIOCLGET, (caddr_t)&lmode)) 18041486Smckusick break; 18141486Smckusick (void) ioctlrout(fp, TIOCGLTC, (caddr_t)<c); 18241486Smckusick 18341486Smckusick /* set baud rate */ 18441486Smckusick sg.sg_ispeed = hpuxtobsdbaud[tiop->c_cflag&TIO_CBAUD]; 18541486Smckusick sg.sg_ospeed = sg.sg_ispeed; 18641486Smckusick 18741486Smckusick /* set special chars to defaults for cooked mode */ 18841486Smckusick sg.sg_erase = tiop->c_cc[HPUXVERASE]; 18941486Smckusick sg.sg_kill = tiop->c_cc[HPUXVKILL]; 19041486Smckusick tc.bsdt_intrc = tiop->c_cc[HPUXVINTR]; 19141486Smckusick tc.bsdt_quitc = tiop->c_cc[HPUXVQUIT]; 19241486Smckusick tc.bsdt_startc = CSTART; 19341486Smckusick tc.bsdt_stopc = CSTOP; 19441486Smckusick tc.bsdt_eofc = tiop->c_cc[HPUXVEOF]; 19541486Smckusick tc.bsdt_brkc = tiop->c_cc[HPUXVEOL]; 19641486Smckusick ltc.bsdt_suspc = CSUSP; 19741486Smckusick ltc.bsdt_dsuspc = CDSUSP; 19843453Shibler ltc.bsdt_flushc = CDISCARD; 19941486Smckusick ltc.bsdt_lnextc = CLNEXT; 20041486Smckusick 20141486Smckusick /* set flags */ 20241486Smckusick flag = 0; 20341486Smckusick if (tiop->c_oflag & TIO_BSDLY) 20441486Smckusick flag |= BSDELAY; 20541486Smckusick if (tiop->c_oflag & TIO_FFDLY) 20641486Smckusick flag |= VTDELAY; 20741486Smckusick if (tiop->c_oflag & TIO_TAB1) { 20841486Smckusick if (tiop->c_oflag & TIO_TAB2) 20941486Smckusick flag |= XTABS; 21041486Smckusick else 21141486Smckusick flag |= TAB1; 21241486Smckusick } else if (tiop->c_oflag & TIO_TAB2) 21341486Smckusick flag |= TAB2; 21441486Smckusick if (tiop->c_oflag & TIO_CR1) { 21541486Smckusick flag |= CR1; 21641486Smckusick if (tiop->c_oflag & TIO_ONLRET) 21741486Smckusick flag |= NL1; 21841486Smckusick } 21941486Smckusick if (tiop->c_oflag & TIO_CR2) { 22041486Smckusick flag |= CR2; 22141486Smckusick if (tiop->c_oflag & TIO_ONLRET) 22241486Smckusick flag |= NL2; 22341486Smckusick } 22441486Smckusick if ((tiop->c_oflag & (TIO_NLDLY|TIO_ONLRET)) == TIO_NLDLY) 22541486Smckusick flag |= NL2; 22641486Smckusick if ((tiop->c_cflag & TIO_PARENB) == 0) 22741486Smckusick flag |= ODDP|EVENP; 22841486Smckusick else if (tiop->c_cflag & TIO_PARODD) 22941486Smckusick flag |= ODDP; 23041486Smckusick else 23141486Smckusick flag |= EVENP; 23241486Smckusick if ((tiop->c_iflag & TIO_ICRNL) || (tiop->c_oflag & TIO_ONLCR)) 23341486Smckusick flag |= CRMOD; 23441486Smckusick if (tiop->c_lflag & TIO_ECHO) 23541486Smckusick flag |= ECHO; 23641486Smckusick if (tiop->c_iflag & TIO_IUCLC) 23741486Smckusick flag |= LCASE; 23841486Smckusick if (tiop->c_iflag & TIO_IXOFF) 23941486Smckusick flag |= TANDEM; 24041486Smckusick if ((tiop->c_lflag & TIO_ICANON) == 0) { 24141486Smckusick if (tiop->c_lflag & TIO_ISIG) 24241486Smckusick flag |= CBREAK; 24341486Smckusick else 24441486Smckusick flag |= RAW; 24541486Smckusick } 24641486Smckusick if (flag & CBREAK) { 24741486Smckusick ltc.bsdt_suspc = ltc.bsdt_dsuspc = -1; 24841486Smckusick ltc.bsdt_flushc = ltc.bsdt_lnextc = -1; 24941486Smckusick if ((tiop->c_iflag & TIO_IXON) == 0) 25041486Smckusick tc.bsdt_startc = tc.bsdt_stopc = -1; 25141486Smckusick } 25241486Smckusick sg.sg_flags = flag; 25341486Smckusick lmode &= ~(LCRTERA|LLITOUT|LDECCTQ|LPASS8); 25441486Smckusick if (tiop->c_lflag & TIO_ECHOE) 25541486Smckusick lmode |= LCRTERA; 25641486Smckusick if ((tiop->c_oflag & TIO_OPOST) == 0) 25741486Smckusick lmode |= LLITOUT; 25841486Smckusick if ((tiop->c_iflag & TIO_IXANY) == 0) 25941486Smckusick lmode |= LDECCTQ; 26041486Smckusick if ((tiop->c_cflag & TIO_CS8) && 26141486Smckusick (tiop->c_iflag & TIO_ISTRIP) == 0) 26241486Smckusick lmode |= LPASS8; 26341486Smckusick 26441486Smckusick /* set the new stuff */ 26541486Smckusick if (com == HPUXTCSETA) 26641486Smckusick com = TIOCSETN; 26741486Smckusick else 26841486Smckusick com = TIOCSETP; 26941486Smckusick (void) ioctlrout(fp, com, (caddr_t)&sg); 27041486Smckusick (void) ioctlrout(fp, TIOCSETC, (caddr_t)&tc); 27141486Smckusick (void) ioctlrout(fp, TIOCSLTC, (caddr_t)<c); 27241486Smckusick (void) ioctlrout(fp, TIOCLSET, (caddr_t)&lmode); 27341486Smckusick if (tiop->c_cflag & TIO_HUPCL) 27441486Smckusick (void) ioctlrout(fp, TIOCHPCL, (caddr_t)0); 27541486Smckusick break; 27641486Smckusick 27741486Smckusick default: 27843453Shibler error = EINVAL; 27941486Smckusick break; 28041486Smckusick } 28143453Shibler return(error); 28241486Smckusick } 28341486Smckusick 28441486Smckusick /* #ifdef COMPAT */ 28543453Shibler ohpuxgtty(p, uap, retval) 28643453Shibler struct proc *p; 28743453Shibler struct args { 28841486Smckusick int fdes; 28941486Smckusick caddr_t cmarg; 29043453Shibler } *uap; 29143453Shibler int *retval; 29243453Shibler { 29341486Smckusick 294*43711Smckusick return (getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg)); 29541486Smckusick } 29641486Smckusick 29743453Shibler ohpuxstty(p, uap, retval) 29843453Shibler struct proc *p; 29943453Shibler struct args { 30041486Smckusick int fdes; 30141486Smckusick caddr_t cmarg; 30243453Shibler } *uap; 30343453Shibler int *retval; 30443453Shibler { 30541486Smckusick 306*43711Smckusick return (getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg)); 30741486Smckusick } 30841486Smckusick 30941486Smckusick /* 31041486Smckusick * Simplified version of ioctl() for use by 31141486Smckusick * gtty/stty and TIOCGETP/TIOCSETP. 31241486Smckusick */ 31341486Smckusick getsettty(fdes, com, cmarg) 31441486Smckusick int fdes, com; 31541486Smckusick caddr_t cmarg; 31641486Smckusick { 31741486Smckusick register struct file *fp; 31841486Smckusick struct hpuxsgttyb hsb; 31941486Smckusick struct sgttyb sb; 32043453Shibler int error; 32141486Smckusick 32243453Shibler if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) 32343453Shibler return (EBADF); 32443453Shibler if ((fp->f_flag & (FREAD|FWRITE)) == 0) 32543453Shibler return (EBADF); 32641486Smckusick if (com == HPUXTIOCSETP) { 32743453Shibler if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb)) 32843453Shibler return (error); 32941486Smckusick sb.sg_ispeed = hsb.sg_ispeed; 33041486Smckusick sb.sg_ospeed = hsb.sg_ospeed; 33141486Smckusick sb.sg_erase = hsb.sg_erase; 33241486Smckusick sb.sg_kill = hsb.sg_kill; 33343453Shibler sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); 33443453Shibler if (hsb.sg_flags & V7_XTABS) 33543453Shibler sb.sg_flags |= XTABS; 33643453Shibler if (hsb.sg_flags & V7_HUPCL) 33743453Shibler (void)(*fp->f_ops->fo_ioctl)(fp, TIOCHPCL, (caddr_t)0); 33841486Smckusick com = TIOCSETP; 33941486Smckusick } else { 34041486Smckusick bzero((caddr_t)&hsb, sizeof hsb); 34141486Smckusick com = TIOCGETP; 34241486Smckusick } 34343453Shibler error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb); 34443453Shibler if (error == 0 && com == TIOCGETP) { 34541486Smckusick hsb.sg_ispeed = sb.sg_ispeed; 34641486Smckusick hsb.sg_ospeed = sb.sg_ospeed; 34741486Smckusick hsb.sg_erase = sb.sg_erase; 34841486Smckusick hsb.sg_kill = sb.sg_kill; 34943453Shibler hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); 35043453Shibler if (sb.sg_flags & XTABS) 35143453Shibler hsb.sg_flags |= V7_XTABS; 35243453Shibler error = copyout((caddr_t)&hsb, cmarg, sizeof hsb); 35341486Smckusick } 35443453Shibler return (error); 35541486Smckusick } 35641486Smckusick /* #endif */ 35741486Smckusick #endif 358