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