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*43453Shibler * @(#)hpux_tty.c 7.2 (Berkeley) 06/22/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 37*43453Shibler /* 38*43453Shibler * XXX should just include syscontext.h but RETURN definition clashes 39*43453Shibler * with defined constant in tty.h 40*43453Shibler */ 41*43453Shibler #undef RETURN 42*43453Shibler #define RETURN(value) { u.u_error = (value); return (u.u_error); } 43*43453Shibler 4441486Smckusick char hpuxtobsdbaud[32] = { 4541486Smckusick B0, B50, B75, B110, B134, B150, B200, B300, 4641486Smckusick B600, B0, B1200, B1800, B2400, B0, B4800, B0, 4741486Smckusick B9600, EXTA, EXTB, B0, B0, B0, B0, B0, 4841486Smckusick B0, B0, B0, B0, B0, B0, B0, B0 4941486Smckusick }; 5041486Smckusick 5141486Smckusick char bsdtohpuxbaud[16] = { 5241486Smckusick TIO_B0, TIO_B50, TIO_B75, TIO_B110, 5341486Smckusick TIO_B134, TIO_B150, TIO_B200, TIO_B300, 5441486Smckusick TIO_B600, TIO_B1200, TIO_B1800, TIO_B2400, 5541486Smckusick TIO_B4800, TIO_B9600, TIO_B19200, TIO_B38400 5641486Smckusick }; 5741486Smckusick 5841486Smckusick /* 5941486Smckusick * Map BSD style sgtty info to and from SYS5 style termio stuff. 6041486Smckusick * Map BSD style sgtty info to and from V7 style sgtty stuff. 6141486Smckusick */ 6241486Smckusick hpuxtermio(fp, com, data) 6341486Smckusick struct file *fp; 6441486Smckusick caddr_t data; 6541486Smckusick { 6641486Smckusick struct sgttyb sg; 6741486Smckusick struct bsdtchars { /* avoid problem with ttychars.h */ 6841486Smckusick char bsdt_intrc; 6941486Smckusick char bsdt_quitc; 7041486Smckusick char bsdt_startc; 7141486Smckusick char bsdt_stopc; 7241486Smckusick char bsdt_eofc; 7341486Smckusick char bsdt_brkc; 7441486Smckusick } tc; 7541486Smckusick struct bsdltchars { /* avoid problem with ttychars.h */ 7641486Smckusick char bsdt_suspc; 7741486Smckusick char bsdt_dsuspc; 7841486Smckusick char bsdt_rprntc; 7941486Smckusick char bsdt_flushc; 8041486Smckusick char bsdt_werasc; 8141486Smckusick char bsdt_lnextc; 8241486Smckusick } ltc; 83*43453Shibler int lmode, error, (*ioctlrout)(); 8441486Smckusick register u_short flag; 8541486Smckusick register struct hpuxtermio *tiop; 8641486Smckusick 8741486Smckusick ioctlrout = fp->f_ops->fo_ioctl; 8841486Smckusick tiop = (struct hpuxtermio *)data; 8941486Smckusick switch (com) { 9041486Smckusick case HPUXTCGETA: 9141486Smckusick /* get everything we might need */ 9241486Smckusick bzero(data, sizeof(struct hpuxtermio)); 93*43453Shibler if (error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg)) 9441486Smckusick break; 9541486Smckusick (void) ioctlrout(fp, TIOCGETC, (caddr_t)&tc); 9641486Smckusick (void) ioctlrout(fp, TIOCLGET, (caddr_t)&lmode); 9741486Smckusick 9841486Smckusick /* set baud rate */ 9941486Smckusick tiop->c_cflag = (u_short)bsdtohpuxbaud[sg.sg_ispeed&0xF]; 10041486Smckusick 10141486Smckusick /* set editing chars except for EOF/EOL (set below) */ 10241486Smckusick tiop->c_cc[HPUXVINTR] = tc.bsdt_intrc; 10341486Smckusick tiop->c_cc[HPUXVQUIT] = tc.bsdt_quitc; 10441486Smckusick tiop->c_cc[HPUXVERASE] = sg.sg_erase; 10541486Smckusick tiop->c_cc[HPUXVKILL] = sg.sg_kill; 10641486Smckusick 10741486Smckusick /* set flags */ 10841486Smckusick flag = sg.sg_flags; 10941486Smckusick if ((flag & TBDELAY) == XTABS) 11041486Smckusick tiop->c_oflag |= TIO_TAB3; 11141486Smckusick else if (flag & TBDELAY) 11241486Smckusick tiop->c_oflag |= TIO_TAB1; 11341486Smckusick if (flag & LCASE) { 11441486Smckusick tiop->c_iflag |= TIO_IUCLC; 11541486Smckusick tiop->c_oflag |= TIO_OLCUC; 11641486Smckusick tiop->c_lflag |= TIO_XCASE; 11741486Smckusick } 11841486Smckusick if (flag & ECHO) 11941486Smckusick tiop->c_lflag |= TIO_ECHO; 12041486Smckusick if (flag & CRMOD) { 12141486Smckusick tiop->c_iflag |= TIO_ICRNL; 12241486Smckusick tiop->c_oflag |= TIO_ONLCR; 12341486Smckusick if (flag & CR1) 12441486Smckusick tiop->c_oflag |= TIO_CR1; 12541486Smckusick if (flag & CR2) 12641486Smckusick tiop->c_oflag |= TIO_CR2|TIO_ONOCR; 12741486Smckusick } else { 12841486Smckusick tiop->c_oflag |= TIO_ONLRET; 12941486Smckusick if (flag & NL1) 13041486Smckusick tiop->c_oflag |= TIO_CR1; 13141486Smckusick if (flag & NL2) 13241486Smckusick tiop->c_oflag |= TIO_CR2; 13341486Smckusick } 13441486Smckusick if (flag & RAW) { 13541486Smckusick tiop->c_cflag |= TIO_CS8; 13641486Smckusick tiop->c_iflag &= ~(TIO_ICRNL|TIO_IUCLC); 13741486Smckusick tiop->c_cc[HPUXVMIN] = 6; 13841486Smckusick tiop->c_cc[HPUXVTIME] = 1; 13941486Smckusick } else { 14041486Smckusick tiop->c_iflag |= TIO_BRKINT; 14141486Smckusick if (tc.bsdt_startc == CSTART && tc.bsdt_stopc == CSTOP) 14241486Smckusick tiop->c_iflag |= TIO_IXON; 14341486Smckusick if (flag & TANDEM) 14441486Smckusick tiop->c_iflag |= TIO_IXOFF; 14541486Smckusick else if ((lmode & LDECCTQ) == 0) 14641486Smckusick tiop->c_iflag |= TIO_IXANY; 14741486Smckusick if ((lmode & LLITOUT) == 0) { 14841486Smckusick tiop->c_iflag |= TIO_IGNPAR; 14941486Smckusick tiop->c_oflag |= TIO_OPOST; 15041486Smckusick } 15141486Smckusick if (lmode & LPASS8) 15241486Smckusick tiop->c_cflag |= TIO_CS8; 15341486Smckusick else 15441486Smckusick tiop->c_iflag |= TIO_ISTRIP; 15541486Smckusick tiop->c_cflag |= TIO_CS7|TIO_PARENB; 15641486Smckusick tiop->c_lflag |= TIO_ISIG; 15741486Smckusick if (flag & CBREAK) { 15841486Smckusick tiop->c_cc[HPUXVMIN] = 6; 15941486Smckusick tiop->c_cc[HPUXVTIME] = 1; 16041486Smckusick } else { 16141486Smckusick tiop->c_lflag |= TIO_ICANON|TIO_ECHOK; 16241486Smckusick if (lmode & LCRTERA) 16341486Smckusick tiop->c_lflag |= TIO_ECHOE; 16441486Smckusick tiop->c_cc[HPUXVEOF] = tc.bsdt_eofc; 16541486Smckusick tiop->c_cc[HPUXVEOL] = tc.bsdt_brkc; 16641486Smckusick } 16741486Smckusick } 16841486Smckusick tiop->c_cflag |= TIO_PARENB; 16941486Smckusick if (flag & ODDP) { 17041486Smckusick if (flag & EVENP) 17141486Smckusick tiop->c_cflag &= ~TIO_PARENB; 17241486Smckusick tiop->c_cflag |= TIO_PARODD; 17341486Smckusick } 17441486Smckusick if (tiop->c_cflag & TIO_PARENB) 17541486Smckusick tiop->c_iflag |= TIO_INPCK; 17641486Smckusick if (flag & VTDELAY) 17741486Smckusick tiop->c_oflag |= TIO_FFDLY; 17841486Smckusick if (flag & BSDELAY) 17941486Smckusick tiop->c_oflag |= TIO_BSDLY; 18041486Smckusick break; 18141486Smckusick 18241486Smckusick case HPUXTCSETA: 18341486Smckusick case HPUXTCSETAW: 18441486Smckusick case HPUXTCSETAF: 18541486Smckusick /* get old lmode and determine if we are a tty */ 186*43453Shibler if (error = ioctlrout(fp, TIOCLGET, (caddr_t)&lmode)) 18741486Smckusick break; 18841486Smckusick (void) ioctlrout(fp, TIOCGLTC, (caddr_t)<c); 18941486Smckusick 19041486Smckusick /* set baud rate */ 19141486Smckusick sg.sg_ispeed = hpuxtobsdbaud[tiop->c_cflag&TIO_CBAUD]; 19241486Smckusick sg.sg_ospeed = sg.sg_ispeed; 19341486Smckusick 19441486Smckusick /* set special chars to defaults for cooked mode */ 19541486Smckusick sg.sg_erase = tiop->c_cc[HPUXVERASE]; 19641486Smckusick sg.sg_kill = tiop->c_cc[HPUXVKILL]; 19741486Smckusick tc.bsdt_intrc = tiop->c_cc[HPUXVINTR]; 19841486Smckusick tc.bsdt_quitc = tiop->c_cc[HPUXVQUIT]; 19941486Smckusick tc.bsdt_startc = CSTART; 20041486Smckusick tc.bsdt_stopc = CSTOP; 20141486Smckusick tc.bsdt_eofc = tiop->c_cc[HPUXVEOF]; 20241486Smckusick tc.bsdt_brkc = tiop->c_cc[HPUXVEOL]; 20341486Smckusick ltc.bsdt_suspc = CSUSP; 20441486Smckusick ltc.bsdt_dsuspc = CDSUSP; 205*43453Shibler ltc.bsdt_flushc = CDISCARD; 20641486Smckusick ltc.bsdt_lnextc = CLNEXT; 20741486Smckusick 20841486Smckusick /* set flags */ 20941486Smckusick flag = 0; 21041486Smckusick if (tiop->c_oflag & TIO_BSDLY) 21141486Smckusick flag |= BSDELAY; 21241486Smckusick if (tiop->c_oflag & TIO_FFDLY) 21341486Smckusick flag |= VTDELAY; 21441486Smckusick if (tiop->c_oflag & TIO_TAB1) { 21541486Smckusick if (tiop->c_oflag & TIO_TAB2) 21641486Smckusick flag |= XTABS; 21741486Smckusick else 21841486Smckusick flag |= TAB1; 21941486Smckusick } else if (tiop->c_oflag & TIO_TAB2) 22041486Smckusick flag |= TAB2; 22141486Smckusick if (tiop->c_oflag & TIO_CR1) { 22241486Smckusick flag |= CR1; 22341486Smckusick if (tiop->c_oflag & TIO_ONLRET) 22441486Smckusick flag |= NL1; 22541486Smckusick } 22641486Smckusick if (tiop->c_oflag & TIO_CR2) { 22741486Smckusick flag |= CR2; 22841486Smckusick if (tiop->c_oflag & TIO_ONLRET) 22941486Smckusick flag |= NL2; 23041486Smckusick } 23141486Smckusick if ((tiop->c_oflag & (TIO_NLDLY|TIO_ONLRET)) == TIO_NLDLY) 23241486Smckusick flag |= NL2; 23341486Smckusick if ((tiop->c_cflag & TIO_PARENB) == 0) 23441486Smckusick flag |= ODDP|EVENP; 23541486Smckusick else if (tiop->c_cflag & TIO_PARODD) 23641486Smckusick flag |= ODDP; 23741486Smckusick else 23841486Smckusick flag |= EVENP; 23941486Smckusick if ((tiop->c_iflag & TIO_ICRNL) || (tiop->c_oflag & TIO_ONLCR)) 24041486Smckusick flag |= CRMOD; 24141486Smckusick if (tiop->c_lflag & TIO_ECHO) 24241486Smckusick flag |= ECHO; 24341486Smckusick if (tiop->c_iflag & TIO_IUCLC) 24441486Smckusick flag |= LCASE; 24541486Smckusick if (tiop->c_iflag & TIO_IXOFF) 24641486Smckusick flag |= TANDEM; 24741486Smckusick if ((tiop->c_lflag & TIO_ICANON) == 0) { 24841486Smckusick if (tiop->c_lflag & TIO_ISIG) 24941486Smckusick flag |= CBREAK; 25041486Smckusick else 25141486Smckusick flag |= RAW; 25241486Smckusick } 25341486Smckusick if (flag & CBREAK) { 25441486Smckusick ltc.bsdt_suspc = ltc.bsdt_dsuspc = -1; 25541486Smckusick ltc.bsdt_flushc = ltc.bsdt_lnextc = -1; 25641486Smckusick if ((tiop->c_iflag & TIO_IXON) == 0) 25741486Smckusick tc.bsdt_startc = tc.bsdt_stopc = -1; 25841486Smckusick } 25941486Smckusick sg.sg_flags = flag; 26041486Smckusick lmode &= ~(LCRTERA|LLITOUT|LDECCTQ|LPASS8); 26141486Smckusick if (tiop->c_lflag & TIO_ECHOE) 26241486Smckusick lmode |= LCRTERA; 26341486Smckusick if ((tiop->c_oflag & TIO_OPOST) == 0) 26441486Smckusick lmode |= LLITOUT; 26541486Smckusick if ((tiop->c_iflag & TIO_IXANY) == 0) 26641486Smckusick lmode |= LDECCTQ; 26741486Smckusick if ((tiop->c_cflag & TIO_CS8) && 26841486Smckusick (tiop->c_iflag & TIO_ISTRIP) == 0) 26941486Smckusick lmode |= LPASS8; 27041486Smckusick 27141486Smckusick /* set the new stuff */ 27241486Smckusick if (com == HPUXTCSETA) 27341486Smckusick com = TIOCSETN; 27441486Smckusick else 27541486Smckusick com = TIOCSETP; 27641486Smckusick (void) ioctlrout(fp, com, (caddr_t)&sg); 27741486Smckusick (void) ioctlrout(fp, TIOCSETC, (caddr_t)&tc); 27841486Smckusick (void) ioctlrout(fp, TIOCSLTC, (caddr_t)<c); 27941486Smckusick (void) ioctlrout(fp, TIOCLSET, (caddr_t)&lmode); 28041486Smckusick if (tiop->c_cflag & TIO_HUPCL) 28141486Smckusick (void) ioctlrout(fp, TIOCHPCL, (caddr_t)0); 28241486Smckusick break; 28341486Smckusick 28441486Smckusick default: 285*43453Shibler error = EINVAL; 28641486Smckusick break; 28741486Smckusick } 288*43453Shibler return(error); 28941486Smckusick } 29041486Smckusick 29141486Smckusick /* #ifdef COMPAT */ 292*43453Shibler ohpuxgtty(p, uap, retval) 293*43453Shibler struct proc *p; 294*43453Shibler struct args { 29541486Smckusick int fdes; 29641486Smckusick caddr_t cmarg; 297*43453Shibler } *uap; 298*43453Shibler int *retval; 299*43453Shibler { 30041486Smckusick 301*43453Shibler RETURN (getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg)); 30241486Smckusick } 30341486Smckusick 304*43453Shibler ohpuxstty(p, uap, retval) 305*43453Shibler struct proc *p; 306*43453Shibler struct args { 30741486Smckusick int fdes; 30841486Smckusick caddr_t cmarg; 309*43453Shibler } *uap; 310*43453Shibler int *retval; 311*43453Shibler { 31241486Smckusick 313*43453Shibler RETURN (getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg)); 31441486Smckusick } 31541486Smckusick 31641486Smckusick /* 31741486Smckusick * Simplified version of ioctl() for use by 31841486Smckusick * gtty/stty and TIOCGETP/TIOCSETP. 31941486Smckusick */ 32041486Smckusick getsettty(fdes, com, cmarg) 32141486Smckusick int fdes, com; 32241486Smckusick caddr_t cmarg; 32341486Smckusick { 32441486Smckusick register struct file *fp; 32541486Smckusick struct hpuxsgttyb hsb; 32641486Smckusick struct sgttyb sb; 327*43453Shibler int error; 32841486Smckusick 329*43453Shibler if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) 330*43453Shibler return (EBADF); 331*43453Shibler if ((fp->f_flag & (FREAD|FWRITE)) == 0) 332*43453Shibler return (EBADF); 33341486Smckusick if (com == HPUXTIOCSETP) { 334*43453Shibler if (error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb)) 335*43453Shibler return (error); 33641486Smckusick sb.sg_ispeed = hsb.sg_ispeed; 33741486Smckusick sb.sg_ospeed = hsb.sg_ospeed; 33841486Smckusick sb.sg_erase = hsb.sg_erase; 33941486Smckusick sb.sg_kill = hsb.sg_kill; 340*43453Shibler sb.sg_flags = hsb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); 341*43453Shibler if (hsb.sg_flags & V7_XTABS) 342*43453Shibler sb.sg_flags |= XTABS; 343*43453Shibler if (hsb.sg_flags & V7_HUPCL) 344*43453Shibler (void)(*fp->f_ops->fo_ioctl)(fp, TIOCHPCL, (caddr_t)0); 34541486Smckusick com = TIOCSETP; 34641486Smckusick } else { 34741486Smckusick bzero((caddr_t)&hsb, sizeof hsb); 34841486Smckusick com = TIOCGETP; 34941486Smckusick } 350*43453Shibler error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb); 351*43453Shibler if (error == 0 && com == TIOCGETP) { 35241486Smckusick hsb.sg_ispeed = sb.sg_ispeed; 35341486Smckusick hsb.sg_ospeed = sb.sg_ospeed; 35441486Smckusick hsb.sg_erase = sb.sg_erase; 35541486Smckusick hsb.sg_kill = sb.sg_kill; 356*43453Shibler hsb.sg_flags = sb.sg_flags & ~(V7_HUPCL|V7_XTABS|V7_NOAL); 357*43453Shibler if (sb.sg_flags & XTABS) 358*43453Shibler hsb.sg_flags |= V7_XTABS; 359*43453Shibler error = copyout((caddr_t)&hsb, cmarg, sizeof hsb); 36041486Smckusick } 361*43453Shibler return (error); 36241486Smckusick } 36341486Smckusick /* #endif */ 36441486Smckusick #endif 365