1 /*- 2 * Copyright (c) 1982, 1986, 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)tty_compat.c 7.10 (Berkeley) 05/09/91 8 */ 9 10 /* 11 * mapping routines for old line discipline (yuck) 12 */ 13 #ifdef COMPAT_43 14 15 #include "param.h" 16 #include "systm.h" 17 #include "ioctl.h" 18 #include "tty.h" 19 #include "termios.h" 20 #include "proc.h" 21 #include "file.h" 22 #include "conf.h" 23 #include "dkstat.h" 24 #include "kernel.h" 25 #include "syslog.h" 26 27 int ttydebug = 0; 28 29 static struct speedtab compatspeeds[] = { 30 38400, 15, 31 19200, 14, 32 9600, 13, 33 4800, 12, 34 2400, 11, 35 1800, 10, 36 1200, 9, 37 600, 8, 38 300, 7, 39 200, 6, 40 150, 5, 41 134, 4, 42 110, 3, 43 75, 2, 44 50, 1, 45 0, 0, 46 -1, -1, 47 }; 48 static int compatspcodes[16] = { 49 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 50 1800, 2400, 4800, 9600, 19200, 38400, 51 }; 52 53 /*ARGSUSED*/ 54 ttcompat(tp, com, data, flag) 55 register struct tty *tp; 56 caddr_t data; 57 { 58 59 switch (com) { 60 case TIOCGETP: { 61 register struct sgttyb *sg = (struct sgttyb *)data; 62 register u_char *cc = tp->t_cc; 63 register speed; 64 65 speed = ttspeedtab(tp->t_ospeed, compatspeeds); 66 sg->sg_ospeed = (speed == -1) ? 15 : speed; 67 if (tp->t_ispeed == 0) 68 sg->sg_ispeed = sg->sg_ospeed; 69 else { 70 speed = ttspeedtab(tp->t_ispeed, compatspeeds); 71 sg->sg_ispeed = (speed == -1) ? 15 : speed; 72 } 73 sg->sg_erase = cc[VERASE]; 74 sg->sg_kill = cc[VKILL]; 75 sg->sg_flags = ttcompatgetflags(tp); 76 break; 77 } 78 79 case TIOCSETP: 80 case TIOCSETN: { 81 register struct sgttyb *sg = (struct sgttyb *)data; 82 struct termios term; 83 int speed; 84 85 term = tp->t_termios; 86 if ((speed = sg->sg_ispeed) > 15 || speed < 0) 87 term.c_ispeed = speed; 88 else 89 term.c_ispeed = compatspcodes[speed]; 90 if ((speed = sg->sg_ospeed) > 15 || speed < 0) 91 term.c_ospeed = speed; 92 else 93 term.c_ospeed = compatspcodes[speed]; 94 term.c_cc[VERASE] = sg->sg_erase; 95 term.c_cc[VKILL] = sg->sg_kill; 96 tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff; 97 ttcompatsetflags(tp, &term); 98 return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, 99 &term, flag)); 100 } 101 102 case TIOCGETC: { 103 struct tchars *tc = (struct tchars *)data; 104 register u_char *cc = tp->t_cc; 105 106 tc->t_intrc = cc[VINTR]; 107 tc->t_quitc = cc[VQUIT]; 108 tc->t_startc = cc[VSTART]; 109 tc->t_stopc = cc[VSTOP]; 110 tc->t_eofc = cc[VEOF]; 111 tc->t_brkc = cc[VEOL]; 112 break; 113 } 114 case TIOCSETC: { 115 struct tchars *tc = (struct tchars *)data; 116 register u_char *cc = tp->t_cc; 117 118 cc[VINTR] = tc->t_intrc; 119 cc[VQUIT] = tc->t_quitc; 120 cc[VSTART] = tc->t_startc; 121 cc[VSTOP] = tc->t_stopc; 122 cc[VEOF] = tc->t_eofc; 123 cc[VEOL] = tc->t_brkc; 124 if (tc->t_brkc == -1) 125 cc[VEOL2] = _POSIX_VDISABLE; 126 break; 127 } 128 case TIOCSLTC: { 129 struct ltchars *ltc = (struct ltchars *)data; 130 register u_char *cc = tp->t_cc; 131 132 cc[VSUSP] = ltc->t_suspc; 133 cc[VDSUSP] = ltc->t_dsuspc; 134 cc[VREPRINT] = ltc->t_rprntc; 135 cc[VDISCARD] = ltc->t_flushc; 136 cc[VWERASE] = ltc->t_werasc; 137 cc[VLNEXT] = ltc->t_lnextc; 138 break; 139 } 140 case TIOCGLTC: { 141 struct ltchars *ltc = (struct ltchars *)data; 142 register u_char *cc = tp->t_cc; 143 144 ltc->t_suspc = cc[VSUSP]; 145 ltc->t_dsuspc = cc[VDSUSP]; 146 ltc->t_rprntc = cc[VREPRINT]; 147 ltc->t_flushc = cc[VDISCARD]; 148 ltc->t_werasc = cc[VWERASE]; 149 ltc->t_lnextc = cc[VLNEXT]; 150 break; 151 } 152 case TIOCLBIS: 153 case TIOCLBIC: 154 case TIOCLSET: { 155 struct termios term; 156 157 term = tp->t_termios; 158 if (com == TIOCLSET) 159 tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 160 else { 161 tp->t_flags = 162 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 163 if (com == TIOCLBIS) 164 tp->t_flags |= *(int *)data<<16; 165 else 166 tp->t_flags &= ~(*(int *)data<<16); 167 } 168 ttcompatsetlflags(tp, &term); 169 return (ttioctl(tp, TIOCSETA, &term, flag)); 170 } 171 case TIOCLGET: 172 *(int *)data = ttcompatgetflags(tp)>>16; 173 if (ttydebug) 174 printf("CLGET: returning %x\n", *(int *)data); 175 break; 176 177 case OTIOCGETD: 178 *(int *)data = tp->t_line ? tp->t_line : 2; 179 break; 180 181 case OTIOCSETD: { 182 int ldisczero = 0; 183 184 return (ttioctl(tp, TIOCSETD, 185 *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag)); 186 } 187 188 case OTIOCCONS: 189 *(int *)data = 1; 190 return (ttioctl(tp, TIOCCONS, data, flag)); 191 192 default: 193 return (-1); 194 } 195 return (0); 196 } 197 198 ttcompatgetflags(tp) 199 register struct tty *tp; 200 { 201 register long iflag = tp->t_iflag; 202 register long lflag = tp->t_lflag; 203 register long oflag = tp->t_oflag; 204 register long cflag = tp->t_cflag; 205 register flags = 0; 206 207 if (iflag&IXOFF) 208 flags |= TANDEM; 209 if (iflag&ICRNL || oflag&ONLCR) 210 flags |= CRMOD; 211 if (cflag&PARENB) { 212 if (iflag&INPCK) { 213 if (cflag&PARODD) 214 flags |= ODDP; 215 else 216 flags |= EVENP; 217 } else 218 flags |= EVENP | ODDP; 219 } else { 220 if ((tp->t_flags&LITOUT) && !(oflag&OPOST)) 221 flags |= LITOUT; 222 if (tp->t_flags&PASS8) 223 flags |= PASS8; 224 } 225 226 if ((lflag&ICANON) == 0) { 227 /* fudge */ 228 if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB) 229 flags |= CBREAK; 230 else 231 flags |= RAW; 232 } 233 if (oflag&OXTABS) 234 flags |= XTABS; 235 if (lflag&ECHOE) 236 flags |= CRTERA|CRTBS; 237 if (lflag&ECHOKE) 238 flags |= CRTKIL|CRTBS; 239 if (lflag&ECHOPRT) 240 flags |= PRTERA; 241 if (lflag&ECHOCTL) 242 flags |= CTLECH; 243 if ((iflag&IXANY) == 0) 244 flags |= DECCTQ; 245 flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 246 if (ttydebug) 247 printf("getflags: %x\n", flags); 248 return (flags); 249 } 250 251 ttcompatsetflags(tp, t) 252 register struct tty *tp; 253 register struct termios *t; 254 { 255 register flags = tp->t_flags; 256 register long iflag = t->c_iflag; 257 register long oflag = t->c_oflag; 258 register long lflag = t->c_lflag; 259 register long cflag = t->c_cflag; 260 261 if (flags & RAW) { 262 iflag &= IXOFF; 263 oflag &= ~OPOST; 264 lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); 265 } else { 266 iflag |= BRKINT|IXON|IMAXBEL; 267 oflag |= OPOST; 268 lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */ 269 if (flags & XTABS) 270 oflag |= OXTABS; 271 else 272 oflag &= ~OXTABS; 273 if (flags & CBREAK) 274 lflag &= ~ICANON; 275 else 276 lflag |= ICANON; 277 if (flags&CRMOD) { 278 iflag |= ICRNL; 279 oflag |= ONLCR; 280 } else { 281 iflag &= ~ICRNL; 282 oflag &= ~ONLCR; 283 } 284 } 285 if (flags&ECHO) 286 lflag |= ECHO; 287 else 288 lflag &= ~ECHO; 289 290 if (flags&(RAW|LITOUT|PASS8)) { 291 cflag &= ~(CSIZE|PARENB); 292 cflag |= CS8; 293 if ((flags&(RAW|PASS8)) == 0) 294 iflag |= ISTRIP; 295 else 296 iflag &= ~ISTRIP; 297 } else { 298 cflag &= ~CSIZE; 299 cflag |= CS7|PARENB; 300 iflag |= ISTRIP; 301 } 302 if ((flags&(EVENP|ODDP)) == EVENP) { 303 iflag |= INPCK; 304 cflag &= ~PARODD; 305 } else if ((flags&(EVENP|ODDP)) == ODDP) { 306 iflag |= INPCK; 307 cflag |= PARODD; 308 } else 309 iflag &= ~INPCK; 310 if (flags&LITOUT) 311 oflag &= ~OPOST; /* move earlier ? */ 312 if (flags&TANDEM) 313 iflag |= IXOFF; 314 else 315 iflag &= ~IXOFF; 316 t->c_iflag = iflag; 317 t->c_oflag = oflag; 318 t->c_lflag = lflag; 319 t->c_cflag = cflag; 320 } 321 322 ttcompatsetlflags(tp, t) 323 register struct tty *tp; 324 register struct termios *t; 325 { 326 register flags = tp->t_flags; 327 register long iflag = t->c_iflag; 328 register long oflag = t->c_oflag; 329 register long lflag = t->c_lflag; 330 register long cflag = t->c_cflag; 331 332 if (flags&CRTERA) 333 lflag |= ECHOE; 334 else 335 lflag &= ~ECHOE; 336 if (flags&CRTKIL) 337 lflag |= ECHOKE; 338 else 339 lflag &= ~ECHOKE; 340 if (flags&PRTERA) 341 lflag |= ECHOPRT; 342 else 343 lflag &= ~ECHOPRT; 344 if (flags&CTLECH) 345 lflag |= ECHOCTL; 346 else 347 lflag &= ~ECHOCTL; 348 if ((flags&DECCTQ) == 0) 349 lflag |= IXANY; 350 else 351 lflag &= ~IXANY; 352 lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 353 lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 354 if (flags&(LITOUT|PASS8)) { 355 iflag &= ~ISTRIP; 356 cflag &= ~(CSIZE|PARENB); 357 cflag |= CS8; 358 if (flags&LITOUT) 359 oflag &= ~OPOST; 360 if ((flags&(PASS8|RAW)) == 0) 361 iflag |= ISTRIP; 362 } else if ((flags&RAW) == 0) { 363 cflag &= ~CSIZE; 364 cflag |= CS7|PARENB; 365 oflag |= OPOST; 366 } 367 t->c_iflag = iflag; 368 t->c_oflag = oflag; 369 t->c_lflag = lflag; 370 t->c_cflag = cflag; 371 } 372 #endif /* COMPAT_43 */ 373