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