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