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