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