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