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