1*41486Smckusick /* 2*41486Smckusick * Copyright (c) 1988 University of Utah. 3*41486Smckusick * Copyright (c) 1990 The Regents of the University of California. 4*41486Smckusick * All rights reserved. 5*41486Smckusick * 6*41486Smckusick * This code is derived from software contributed to Berkeley by 7*41486Smckusick * the Systems Programming Group of the University of Utah Computer 8*41486Smckusick * Science Department. 9*41486Smckusick * 10*41486Smckusick * %sccs.include.redist.c% 11*41486Smckusick * 12*41486Smckusick * from: Utah $Hdr: hpux_tty.c 1.7 89/04/11$ 13*41486Smckusick * 14*41486Smckusick * @(#)hpux_tty.c 7.1 (Berkeley) 05/08/90 15*41486Smckusick */ 16*41486Smckusick 17*41486Smckusick /* 18*41486Smckusick * stty/gtty/termio emulation stuff 19*41486Smckusick */ 20*41486Smckusick #ifdef HPUXCOMPAT 21*41486Smckusick 22*41486Smckusick #include "param.h" 23*41486Smckusick #include "systm.h" 24*41486Smckusick #include "user.h" 25*41486Smckusick #include "ioctl.h" 26*41486Smckusick #include "tty.h" 27*41486Smckusick #include "proc.h" 28*41486Smckusick #include "file.h" 29*41486Smckusick #include "conf.h" 30*41486Smckusick #include "buf.h" 31*41486Smckusick #include "uio.h" 32*41486Smckusick #include "kernel.h" 33*41486Smckusick 34*41486Smckusick #include "hpux.h" 35*41486Smckusick #include "hpux_termio.h" 36*41486Smckusick 37*41486Smckusick char hpuxtobsdbaud[32] = { 38*41486Smckusick B0, B50, B75, B110, B134, B150, B200, B300, 39*41486Smckusick B600, B0, B1200, B1800, B2400, B0, B4800, B0, 40*41486Smckusick B9600, EXTA, EXTB, B0, B0, B0, B0, B0, 41*41486Smckusick B0, B0, B0, B0, B0, B0, B0, B0 42*41486Smckusick }; 43*41486Smckusick 44*41486Smckusick char bsdtohpuxbaud[16] = { 45*41486Smckusick TIO_B0, TIO_B50, TIO_B75, TIO_B110, 46*41486Smckusick TIO_B134, TIO_B150, TIO_B200, TIO_B300, 47*41486Smckusick TIO_B600, TIO_B1200, TIO_B1800, TIO_B2400, 48*41486Smckusick TIO_B4800, TIO_B9600, TIO_B19200, TIO_B38400 49*41486Smckusick }; 50*41486Smckusick 51*41486Smckusick /* 52*41486Smckusick * Map BSD style sgtty info to and from SYS5 style termio stuff. 53*41486Smckusick * Map BSD style sgtty info to and from V7 style sgtty stuff. 54*41486Smckusick */ 55*41486Smckusick hpuxtermio(fp, com, data) 56*41486Smckusick struct file *fp; 57*41486Smckusick caddr_t data; 58*41486Smckusick { 59*41486Smckusick struct sgttyb sg; 60*41486Smckusick struct bsdtchars { /* avoid problem with ttychars.h */ 61*41486Smckusick char bsdt_intrc; 62*41486Smckusick char bsdt_quitc; 63*41486Smckusick char bsdt_startc; 64*41486Smckusick char bsdt_stopc; 65*41486Smckusick char bsdt_eofc; 66*41486Smckusick char bsdt_brkc; 67*41486Smckusick } tc; 68*41486Smckusick struct bsdltchars { /* avoid problem with ttychars.h */ 69*41486Smckusick char bsdt_suspc; 70*41486Smckusick char bsdt_dsuspc; 71*41486Smckusick char bsdt_rprntc; 72*41486Smckusick char bsdt_flushc; 73*41486Smckusick char bsdt_werasc; 74*41486Smckusick char bsdt_lnextc; 75*41486Smckusick } ltc; 76*41486Smckusick int lmode, (*ioctlrout)(); 77*41486Smckusick register u_short flag; 78*41486Smckusick register struct hpuxtermio *tiop; 79*41486Smckusick 80*41486Smckusick ioctlrout = fp->f_ops->fo_ioctl; 81*41486Smckusick tiop = (struct hpuxtermio *)data; 82*41486Smckusick switch (com) { 83*41486Smckusick case HPUXTCGETA: 84*41486Smckusick /* get everything we might need */ 85*41486Smckusick bzero(data, sizeof(struct hpuxtermio)); 86*41486Smckusick if (u.u_error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg)) 87*41486Smckusick break; 88*41486Smckusick (void) ioctlrout(fp, TIOCGETC, (caddr_t)&tc); 89*41486Smckusick (void) ioctlrout(fp, TIOCLGET, (caddr_t)&lmode); 90*41486Smckusick 91*41486Smckusick /* set baud rate */ 92*41486Smckusick tiop->c_cflag = (u_short)bsdtohpuxbaud[sg.sg_ispeed&0xF]; 93*41486Smckusick 94*41486Smckusick /* set editing chars except for EOF/EOL (set below) */ 95*41486Smckusick tiop->c_cc[HPUXVINTR] = tc.bsdt_intrc; 96*41486Smckusick tiop->c_cc[HPUXVQUIT] = tc.bsdt_quitc; 97*41486Smckusick tiop->c_cc[HPUXVERASE] = sg.sg_erase; 98*41486Smckusick tiop->c_cc[HPUXVKILL] = sg.sg_kill; 99*41486Smckusick 100*41486Smckusick /* set flags */ 101*41486Smckusick flag = sg.sg_flags; 102*41486Smckusick if ((flag & TBDELAY) == XTABS) 103*41486Smckusick tiop->c_oflag |= TIO_TAB3; 104*41486Smckusick else if (flag & TBDELAY) 105*41486Smckusick tiop->c_oflag |= TIO_TAB1; 106*41486Smckusick if (flag & LCASE) { 107*41486Smckusick tiop->c_iflag |= TIO_IUCLC; 108*41486Smckusick tiop->c_oflag |= TIO_OLCUC; 109*41486Smckusick tiop->c_lflag |= TIO_XCASE; 110*41486Smckusick } 111*41486Smckusick if (flag & ECHO) 112*41486Smckusick tiop->c_lflag |= TIO_ECHO; 113*41486Smckusick if (flag & CRMOD) { 114*41486Smckusick tiop->c_iflag |= TIO_ICRNL; 115*41486Smckusick tiop->c_oflag |= TIO_ONLCR; 116*41486Smckusick if (flag & CR1) 117*41486Smckusick tiop->c_oflag |= TIO_CR1; 118*41486Smckusick if (flag & CR2) 119*41486Smckusick tiop->c_oflag |= TIO_CR2|TIO_ONOCR; 120*41486Smckusick } else { 121*41486Smckusick tiop->c_oflag |= TIO_ONLRET; 122*41486Smckusick if (flag & NL1) 123*41486Smckusick tiop->c_oflag |= TIO_CR1; 124*41486Smckusick if (flag & NL2) 125*41486Smckusick tiop->c_oflag |= TIO_CR2; 126*41486Smckusick } 127*41486Smckusick if (flag & RAW) { 128*41486Smckusick tiop->c_cflag |= TIO_CS8; 129*41486Smckusick tiop->c_iflag &= ~(TIO_ICRNL|TIO_IUCLC); 130*41486Smckusick tiop->c_cc[HPUXVMIN] = 6; 131*41486Smckusick tiop->c_cc[HPUXVTIME] = 1; 132*41486Smckusick } else { 133*41486Smckusick tiop->c_iflag |= TIO_BRKINT; 134*41486Smckusick if (tc.bsdt_startc == CSTART && tc.bsdt_stopc == CSTOP) 135*41486Smckusick tiop->c_iflag |= TIO_IXON; 136*41486Smckusick if (flag & TANDEM) 137*41486Smckusick tiop->c_iflag |= TIO_IXOFF; 138*41486Smckusick else if ((lmode & LDECCTQ) == 0) 139*41486Smckusick tiop->c_iflag |= TIO_IXANY; 140*41486Smckusick if ((lmode & LLITOUT) == 0) { 141*41486Smckusick tiop->c_iflag |= TIO_IGNPAR; 142*41486Smckusick tiop->c_oflag |= TIO_OPOST; 143*41486Smckusick } 144*41486Smckusick if (lmode & LPASS8) 145*41486Smckusick tiop->c_cflag |= TIO_CS8; 146*41486Smckusick else 147*41486Smckusick tiop->c_iflag |= TIO_ISTRIP; 148*41486Smckusick tiop->c_cflag |= TIO_CS7|TIO_PARENB; 149*41486Smckusick tiop->c_lflag |= TIO_ISIG; 150*41486Smckusick if (flag & CBREAK) { 151*41486Smckusick tiop->c_cc[HPUXVMIN] = 6; 152*41486Smckusick tiop->c_cc[HPUXVTIME] = 1; 153*41486Smckusick } else { 154*41486Smckusick tiop->c_lflag |= TIO_ICANON|TIO_ECHOK; 155*41486Smckusick if (lmode & LCRTERA) 156*41486Smckusick tiop->c_lflag |= TIO_ECHOE; 157*41486Smckusick tiop->c_cc[HPUXVEOF] = tc.bsdt_eofc; 158*41486Smckusick tiop->c_cc[HPUXVEOL] = tc.bsdt_brkc; 159*41486Smckusick } 160*41486Smckusick } 161*41486Smckusick tiop->c_cflag |= TIO_PARENB; 162*41486Smckusick if (flag & ODDP) { 163*41486Smckusick if (flag & EVENP) 164*41486Smckusick tiop->c_cflag &= ~TIO_PARENB; 165*41486Smckusick tiop->c_cflag |= TIO_PARODD; 166*41486Smckusick } 167*41486Smckusick if (tiop->c_cflag & TIO_PARENB) 168*41486Smckusick tiop->c_iflag |= TIO_INPCK; 169*41486Smckusick if (flag & VTDELAY) 170*41486Smckusick tiop->c_oflag |= TIO_FFDLY; 171*41486Smckusick if (flag & BSDELAY) 172*41486Smckusick tiop->c_oflag |= TIO_BSDLY; 173*41486Smckusick break; 174*41486Smckusick 175*41486Smckusick case HPUXTCSETA: 176*41486Smckusick case HPUXTCSETAW: 177*41486Smckusick case HPUXTCSETAF: 178*41486Smckusick /* get old lmode and determine if we are a tty */ 179*41486Smckusick if (u.u_error = ioctlrout(fp, TIOCLGET, (caddr_t)&lmode)) 180*41486Smckusick break; 181*41486Smckusick (void) ioctlrout(fp, TIOCGLTC, (caddr_t)<c); 182*41486Smckusick 183*41486Smckusick /* set baud rate */ 184*41486Smckusick sg.sg_ispeed = hpuxtobsdbaud[tiop->c_cflag&TIO_CBAUD]; 185*41486Smckusick sg.sg_ospeed = sg.sg_ispeed; 186*41486Smckusick 187*41486Smckusick /* set special chars to defaults for cooked mode */ 188*41486Smckusick sg.sg_erase = tiop->c_cc[HPUXVERASE]; 189*41486Smckusick sg.sg_kill = tiop->c_cc[HPUXVKILL]; 190*41486Smckusick tc.bsdt_intrc = tiop->c_cc[HPUXVINTR]; 191*41486Smckusick tc.bsdt_quitc = tiop->c_cc[HPUXVQUIT]; 192*41486Smckusick tc.bsdt_startc = CSTART; 193*41486Smckusick tc.bsdt_stopc = CSTOP; 194*41486Smckusick tc.bsdt_eofc = tiop->c_cc[HPUXVEOF]; 195*41486Smckusick tc.bsdt_brkc = tiop->c_cc[HPUXVEOL]; 196*41486Smckusick ltc.bsdt_suspc = CSUSP; 197*41486Smckusick ltc.bsdt_dsuspc = CDSUSP; 198*41486Smckusick ltc.bsdt_flushc = CFLUSH; 199*41486Smckusick ltc.bsdt_lnextc = CLNEXT; 200*41486Smckusick 201*41486Smckusick /* set flags */ 202*41486Smckusick flag = 0; 203*41486Smckusick if (tiop->c_oflag & TIO_BSDLY) 204*41486Smckusick flag |= BSDELAY; 205*41486Smckusick if (tiop->c_oflag & TIO_FFDLY) 206*41486Smckusick flag |= VTDELAY; 207*41486Smckusick if (tiop->c_oflag & TIO_TAB1) { 208*41486Smckusick if (tiop->c_oflag & TIO_TAB2) 209*41486Smckusick flag |= XTABS; 210*41486Smckusick else 211*41486Smckusick flag |= TAB1; 212*41486Smckusick } else if (tiop->c_oflag & TIO_TAB2) 213*41486Smckusick flag |= TAB2; 214*41486Smckusick if (tiop->c_oflag & TIO_CR1) { 215*41486Smckusick flag |= CR1; 216*41486Smckusick if (tiop->c_oflag & TIO_ONLRET) 217*41486Smckusick flag |= NL1; 218*41486Smckusick } 219*41486Smckusick if (tiop->c_oflag & TIO_CR2) { 220*41486Smckusick flag |= CR2; 221*41486Smckusick if (tiop->c_oflag & TIO_ONLRET) 222*41486Smckusick flag |= NL2; 223*41486Smckusick } 224*41486Smckusick if ((tiop->c_oflag & (TIO_NLDLY|TIO_ONLRET)) == TIO_NLDLY) 225*41486Smckusick flag |= NL2; 226*41486Smckusick if ((tiop->c_cflag & TIO_PARENB) == 0) 227*41486Smckusick flag |= ODDP|EVENP; 228*41486Smckusick else if (tiop->c_cflag & TIO_PARODD) 229*41486Smckusick flag |= ODDP; 230*41486Smckusick else 231*41486Smckusick flag |= EVENP; 232*41486Smckusick if ((tiop->c_iflag & TIO_ICRNL) || (tiop->c_oflag & TIO_ONLCR)) 233*41486Smckusick flag |= CRMOD; 234*41486Smckusick if (tiop->c_lflag & TIO_ECHO) 235*41486Smckusick flag |= ECHO; 236*41486Smckusick if (tiop->c_iflag & TIO_IUCLC) 237*41486Smckusick flag |= LCASE; 238*41486Smckusick if (tiop->c_iflag & TIO_IXOFF) 239*41486Smckusick flag |= TANDEM; 240*41486Smckusick if ((tiop->c_lflag & TIO_ICANON) == 0) { 241*41486Smckusick if (tiop->c_lflag & TIO_ISIG) 242*41486Smckusick flag |= CBREAK; 243*41486Smckusick else 244*41486Smckusick flag |= RAW; 245*41486Smckusick } 246*41486Smckusick if (flag & CBREAK) { 247*41486Smckusick ltc.bsdt_suspc = ltc.bsdt_dsuspc = -1; 248*41486Smckusick ltc.bsdt_flushc = ltc.bsdt_lnextc = -1; 249*41486Smckusick if ((tiop->c_iflag & TIO_IXON) == 0) 250*41486Smckusick tc.bsdt_startc = tc.bsdt_stopc = -1; 251*41486Smckusick } 252*41486Smckusick sg.sg_flags = flag; 253*41486Smckusick lmode &= ~(LCRTERA|LLITOUT|LDECCTQ|LPASS8); 254*41486Smckusick if (tiop->c_lflag & TIO_ECHOE) 255*41486Smckusick lmode |= LCRTERA; 256*41486Smckusick if ((tiop->c_oflag & TIO_OPOST) == 0) 257*41486Smckusick lmode |= LLITOUT; 258*41486Smckusick if ((tiop->c_iflag & TIO_IXANY) == 0) 259*41486Smckusick lmode |= LDECCTQ; 260*41486Smckusick if ((tiop->c_cflag & TIO_CS8) && 261*41486Smckusick (tiop->c_iflag & TIO_ISTRIP) == 0) 262*41486Smckusick lmode |= LPASS8; 263*41486Smckusick 264*41486Smckusick /* set the new stuff */ 265*41486Smckusick if (com == HPUXTCSETA) 266*41486Smckusick com = TIOCSETN; 267*41486Smckusick else 268*41486Smckusick com = TIOCSETP; 269*41486Smckusick (void) ioctlrout(fp, com, (caddr_t)&sg); 270*41486Smckusick (void) ioctlrout(fp, TIOCSETC, (caddr_t)&tc); 271*41486Smckusick (void) ioctlrout(fp, TIOCSLTC, (caddr_t)<c); 272*41486Smckusick (void) ioctlrout(fp, TIOCLSET, (caddr_t)&lmode); 273*41486Smckusick if (tiop->c_cflag & TIO_HUPCL) 274*41486Smckusick (void) ioctlrout(fp, TIOCHPCL, (caddr_t)0); 275*41486Smckusick break; 276*41486Smckusick 277*41486Smckusick case HPUXTIOCGETP: 278*41486Smckusick u.u_error = ioctlrout(fp, TIOCGETP, (caddr_t)&sg); 279*41486Smckusick if (u.u_error) 280*41486Smckusick break; 281*41486Smckusick flag = sg.sg_flags; 282*41486Smckusick sg.sg_flags &= ~(V7_HUPCL|V7_XTABS|V7_NOAL); 283*41486Smckusick if (flag & XTABS) 284*41486Smckusick sg.sg_flags |= V7_XTABS; 285*41486Smckusick bcopy((caddr_t)&sg, data, sizeof sg); 286*41486Smckusick break; 287*41486Smckusick 288*41486Smckusick case HPUXTIOCSETP: 289*41486Smckusick bcopy(data, (caddr_t)&sg, sizeof sg); 290*41486Smckusick flag = sg.sg_flags; 291*41486Smckusick sg.sg_flags &= ~(V7_HUPCL|V7_XTABS|V7_NOAL); 292*41486Smckusick if (flag & V7_XTABS) 293*41486Smckusick sg.sg_flags |= XTABS; 294*41486Smckusick u.u_error = ioctlrout(fp, TIOCSETP, (caddr_t)&sg); 295*41486Smckusick if (flag & V7_HUPCL) 296*41486Smckusick (void) ioctlrout(fp, TIOCHPCL, (caddr_t)0); 297*41486Smckusick break; 298*41486Smckusick 299*41486Smckusick default: 300*41486Smckusick break; 301*41486Smckusick } 302*41486Smckusick return(u.u_error); 303*41486Smckusick } 304*41486Smckusick 305*41486Smckusick /* #ifdef COMPAT */ 306*41486Smckusick ohpuxgtty() 307*41486Smckusick { 308*41486Smckusick struct a { 309*41486Smckusick int fdes; 310*41486Smckusick caddr_t cmarg; 311*41486Smckusick } *uap = (struct a *)u.u_ap; 312*41486Smckusick 313*41486Smckusick getsettty(uap->fdes, HPUXTIOCGETP, uap->cmarg); 314*41486Smckusick } 315*41486Smckusick 316*41486Smckusick ohpuxstty() 317*41486Smckusick { 318*41486Smckusick struct a { 319*41486Smckusick int fdes; 320*41486Smckusick caddr_t cmarg; 321*41486Smckusick } *uap = (struct a *)u.u_ap; 322*41486Smckusick 323*41486Smckusick getsettty(uap->fdes, HPUXTIOCSETP, uap->cmarg); 324*41486Smckusick } 325*41486Smckusick 326*41486Smckusick /* 327*41486Smckusick * Simplified version of ioctl() for use by 328*41486Smckusick * gtty/stty and TIOCGETP/TIOCSETP. 329*41486Smckusick */ 330*41486Smckusick getsettty(fdes, com, cmarg) 331*41486Smckusick int fdes, com; 332*41486Smckusick caddr_t cmarg; 333*41486Smckusick { 334*41486Smckusick register struct file *fp; 335*41486Smckusick struct hpuxsgttyb hsb; 336*41486Smckusick struct sgttyb sb; 337*41486Smckusick 338*41486Smckusick if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) { 339*41486Smckusick u.u_error = EBADF; 340*41486Smckusick return; 341*41486Smckusick } 342*41486Smckusick if ((fp->f_flag & (FREAD|FWRITE)) == 0) { 343*41486Smckusick u.u_error = EBADF; 344*41486Smckusick return; 345*41486Smckusick } 346*41486Smckusick if (com == HPUXTIOCSETP) { 347*41486Smckusick u.u_error = copyin(cmarg, (caddr_t)&hsb, sizeof hsb); 348*41486Smckusick if (u.u_error) 349*41486Smckusick return; 350*41486Smckusick sb.sg_ispeed = hsb.sg_ispeed; 351*41486Smckusick sb.sg_ospeed = hsb.sg_ospeed; 352*41486Smckusick sb.sg_erase = hsb.sg_erase; 353*41486Smckusick sb.sg_kill = hsb.sg_kill; 354*41486Smckusick sb.sg_flags = (short) hsb.sg_flags; 355*41486Smckusick com = TIOCSETP; 356*41486Smckusick } else { 357*41486Smckusick bzero((caddr_t)&hsb, sizeof hsb); 358*41486Smckusick com = TIOCGETP; 359*41486Smckusick } 360*41486Smckusick u.u_error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&sb); 361*41486Smckusick if (u.u_error == 0 && com == TIOCGETP) { 362*41486Smckusick hsb.sg_ispeed = sb.sg_ispeed; 363*41486Smckusick hsb.sg_ospeed = sb.sg_ospeed; 364*41486Smckusick hsb.sg_erase = sb.sg_erase; 365*41486Smckusick hsb.sg_kill = sb.sg_kill; 366*41486Smckusick hsb.sg_flags = (int) sb.sg_flags; 367*41486Smckusick u.u_error = copyout((caddr_t)&hsb, cmarg, sizeof hsb); 368*41486Smckusick } 369*41486Smckusick } 370*41486Smckusick /* #endif */ 371*41486Smckusick #endif 372