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