1 /*- 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)tty_compat.c 8.1 (Berkeley) 6/10/93 34 */ 35 36 /* 37 * mapping routines for old line discipline (yuck) 38 */ 39 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/ioctl.h> 44 #include <sys/proc.h> 45 #include <sys/tty.h> 46 #include <sys/termios.h> 47 #include <sys/file.h> 48 #include <sys/conf.h> 49 #include <sys/kernel.h> 50 #include <sys/syslog.h> 51 52 void ttcompatsetflags __P((struct tty *, struct termios *)); 53 void ttcompatsetlflags __P((struct tty *, struct termios *)); 54 55 int ttydebug = 0; 56 57 static struct speedtab compatspeeds[] = { 58 { 38400, 15 }, 59 { 19200, 14 }, 60 { 9600, 13 }, 61 { 4800, 12 }, 62 { 2400, 11 }, 63 { 1800, 10 }, 64 { 1200, 9 }, 65 { 600, 8 }, 66 { 300, 7 }, 67 { 200, 6 }, 68 { 150, 5 }, 69 { 134, 4 }, 70 { 110, 3 }, 71 { 75, 2 }, 72 { 50, 1 }, 73 { 0, 0 }, 74 { -1, -1 }, 75 }; 76 static int compatspcodes[16] = { 77 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 78 1800, 2400, 4800, 9600, 19200, 38400, 79 }; 80 81 /*ARGSUSED*/ 82 int 83 ttcompat(tp, com, data, flag) 84 register struct tty *tp; 85 int com; 86 caddr_t data; 87 int flag; 88 { 89 90 switch (com) { 91 case TIOCGETP: { 92 register struct sgttyb *sg = (struct sgttyb *)data; 93 register u_char *cc = tp->t_cc; 94 register speed; 95 96 speed = ttspeedtab(tp->t_ospeed, compatspeeds); 97 sg->sg_ospeed = (speed == -1) ? 15 : speed; 98 if (tp->t_ispeed == 0) 99 sg->sg_ispeed = sg->sg_ospeed; 100 else { 101 speed = ttspeedtab(tp->t_ispeed, compatspeeds); 102 sg->sg_ispeed = (speed == -1) ? 15 : speed; 103 } 104 sg->sg_erase = cc[VERASE]; 105 sg->sg_kill = cc[VKILL]; 106 sg->sg_flags = ttcompatgetflags(tp); 107 break; 108 } 109 110 case TIOCSETP: 111 case TIOCSETN: { 112 register struct sgttyb *sg = (struct sgttyb *)data; 113 struct termios term; 114 int speed; 115 116 term = tp->t_termios; 117 if ((speed = sg->sg_ispeed) > 15 || speed < 0) 118 term.c_ispeed = speed; 119 else 120 term.c_ispeed = compatspcodes[speed]; 121 if ((speed = sg->sg_ospeed) > 15 || speed < 0) 122 term.c_ospeed = speed; 123 else 124 term.c_ospeed = compatspcodes[speed]; 125 term.c_cc[VERASE] = sg->sg_erase; 126 term.c_cc[VKILL] = sg->sg_kill; 127 tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff; 128 ttcompatsetflags(tp, &term); 129 return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, 130 &term, flag)); 131 } 132 133 case TIOCGETC: { 134 struct tchars *tc = (struct tchars *)data; 135 register u_char *cc = tp->t_cc; 136 137 tc->t_intrc = cc[VINTR]; 138 tc->t_quitc = cc[VQUIT]; 139 tc->t_startc = cc[VSTART]; 140 tc->t_stopc = cc[VSTOP]; 141 tc->t_eofc = cc[VEOF]; 142 tc->t_brkc = cc[VEOL]; 143 break; 144 } 145 case TIOCSETC: { 146 struct tchars *tc = (struct tchars *)data; 147 register u_char *cc = tp->t_cc; 148 149 cc[VINTR] = tc->t_intrc; 150 cc[VQUIT] = tc->t_quitc; 151 cc[VSTART] = tc->t_startc; 152 cc[VSTOP] = tc->t_stopc; 153 cc[VEOF] = tc->t_eofc; 154 cc[VEOL] = tc->t_brkc; 155 if (tc->t_brkc == -1) 156 cc[VEOL2] = _POSIX_VDISABLE; 157 break; 158 } 159 case TIOCSLTC: { 160 struct ltchars *ltc = (struct ltchars *)data; 161 register u_char *cc = tp->t_cc; 162 163 cc[VSUSP] = ltc->t_suspc; 164 cc[VDSUSP] = ltc->t_dsuspc; 165 cc[VREPRINT] = ltc->t_rprntc; 166 cc[VDISCARD] = ltc->t_flushc; 167 cc[VWERASE] = ltc->t_werasc; 168 cc[VLNEXT] = ltc->t_lnextc; 169 break; 170 } 171 case TIOCGLTC: { 172 struct ltchars *ltc = (struct ltchars *)data; 173 register u_char *cc = tp->t_cc; 174 175 ltc->t_suspc = cc[VSUSP]; 176 ltc->t_dsuspc = cc[VDSUSP]; 177 ltc->t_rprntc = cc[VREPRINT]; 178 ltc->t_flushc = cc[VDISCARD]; 179 ltc->t_werasc = cc[VWERASE]; 180 ltc->t_lnextc = cc[VLNEXT]; 181 break; 182 } 183 case TIOCLBIS: 184 case TIOCLBIC: 185 case TIOCLSET: { 186 struct termios term; 187 188 term = tp->t_termios; 189 if (com == TIOCLSET) 190 tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 191 else { 192 tp->t_flags = 193 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 194 if (com == TIOCLBIS) 195 tp->t_flags |= *(int *)data<<16; 196 else 197 tp->t_flags &= ~(*(int *)data<<16); 198 } 199 ttcompatsetlflags(tp, &term); 200 return (ttioctl(tp, TIOCSETA, &term, flag)); 201 } 202 case TIOCLGET: 203 *(int *)data = ttcompatgetflags(tp)>>16; 204 if (ttydebug) 205 printf("CLGET: returning %x\n", *(int *)data); 206 break; 207 208 case OTIOCGETD: 209 *(int *)data = tp->t_line ? tp->t_line : 2; 210 break; 211 212 case OTIOCSETD: { 213 int ldisczero = 0; 214 215 return (ttioctl(tp, TIOCSETD, 216 *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag)); 217 } 218 219 case OTIOCCONS: 220 *(int *)data = 1; 221 return (ttioctl(tp, TIOCCONS, data, flag)); 222 223 default: 224 return (-1); 225 } 226 return (0); 227 } 228 229 int 230 ttcompatgetflags(tp) 231 register struct tty *tp; 232 { 233 register long iflag = tp->t_iflag; 234 register long lflag = tp->t_lflag; 235 register long oflag = tp->t_oflag; 236 register long cflag = tp->t_cflag; 237 register flags = 0; 238 239 if (iflag&IXOFF) 240 flags |= TANDEM; 241 if (iflag&ICRNL || oflag&ONLCR) 242 flags |= CRMOD; 243 if (cflag&PARENB) { 244 if (iflag&INPCK) { 245 if (cflag&PARODD) 246 flags |= ODDP; 247 else 248 flags |= EVENP; 249 } else 250 flags |= EVENP | ODDP; 251 } else { 252 if ((tp->t_flags&LITOUT) && !(oflag&OPOST)) 253 flags |= LITOUT; 254 if (tp->t_flags&PASS8) 255 flags |= PASS8; 256 } 257 258 if ((lflag&ICANON) == 0) { 259 /* fudge */ 260 if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB) 261 flags |= CBREAK; 262 else 263 flags |= RAW; 264 } 265 if (cflag&MDMBUF) 266 flags |= MDMBUF; 267 if ((cflag&HUPCL) == 0) 268 flags |= NOHANG; 269 if (oflag&OXTABS) 270 flags |= XTABS; 271 if (lflag&ECHOE) 272 flags |= CRTERA|CRTBS; 273 if (lflag&ECHOKE) 274 flags |= CRTKIL|CRTBS; 275 if (lflag&ECHOPRT) 276 flags |= PRTERA; 277 if (lflag&ECHOCTL) 278 flags |= CTLECH; 279 if ((iflag&IXANY) == 0) 280 flags |= DECCTQ; 281 flags |= lflag&(ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH); 282 if (ttydebug) 283 printf("getflags: %x\n", flags); 284 return (flags); 285 } 286 287 void 288 ttcompatsetflags(tp, t) 289 register struct tty *tp; 290 register struct termios *t; 291 { 292 register flags = tp->t_flags; 293 register long iflag = t->c_iflag; 294 register long oflag = t->c_oflag; 295 register long lflag = t->c_lflag; 296 register long cflag = t->c_cflag; 297 298 if (flags & RAW) { 299 iflag &= IXOFF; 300 oflag &= ~OPOST; 301 lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); 302 } else { 303 iflag |= BRKINT|IXON|IMAXBEL; 304 oflag |= OPOST; 305 lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */ 306 if (flags & XTABS) 307 oflag |= OXTABS; 308 else 309 oflag &= ~OXTABS; 310 if (flags & CBREAK) 311 lflag &= ~ICANON; 312 else 313 lflag |= ICANON; 314 if (flags&CRMOD) { 315 iflag |= ICRNL; 316 oflag |= ONLCR; 317 } else { 318 iflag &= ~ICRNL; 319 oflag &= ~ONLCR; 320 } 321 } 322 if (flags&ECHO) 323 lflag |= ECHO; 324 else 325 lflag &= ~ECHO; 326 327 if (flags&(RAW|LITOUT|PASS8)) { 328 cflag &= ~(CSIZE|PARENB); 329 cflag |= CS8; 330 if ((flags&(RAW|PASS8)) == 0) 331 iflag |= ISTRIP; 332 else 333 iflag &= ~ISTRIP; 334 } else { 335 cflag &= ~CSIZE; 336 cflag |= CS7|PARENB; 337 iflag |= ISTRIP; 338 } 339 if ((flags&(EVENP|ODDP)) == EVENP) { 340 iflag |= INPCK; 341 cflag &= ~PARODD; 342 } else if ((flags&(EVENP|ODDP)) == ODDP) { 343 iflag |= INPCK; 344 cflag |= PARODD; 345 } else 346 iflag &= ~INPCK; 347 if (flags&LITOUT) 348 oflag &= ~OPOST; /* move earlier ? */ 349 if (flags&TANDEM) 350 iflag |= IXOFF; 351 else 352 iflag &= ~IXOFF; 353 t->c_iflag = iflag; 354 t->c_oflag = oflag; 355 t->c_lflag = lflag; 356 t->c_cflag = cflag; 357 } 358 359 void 360 ttcompatsetlflags(tp, t) 361 register struct tty *tp; 362 register struct termios *t; 363 { 364 register flags = tp->t_flags; 365 register long iflag = t->c_iflag; 366 register long oflag = t->c_oflag; 367 register long lflag = t->c_lflag; 368 register long cflag = t->c_cflag; 369 370 if (flags&CRTERA) 371 lflag |= ECHOE; 372 else 373 lflag &= ~ECHOE; 374 if (flags&CRTKIL) 375 lflag |= ECHOKE; 376 else 377 lflag &= ~ECHOKE; 378 if (flags&PRTERA) 379 lflag |= ECHOPRT; 380 else 381 lflag &= ~ECHOPRT; 382 if (flags&CTLECH) 383 lflag |= ECHOCTL; 384 else 385 lflag &= ~ECHOCTL; 386 if ((flags&DECCTQ) == 0) 387 iflag |= IXANY; 388 else 389 iflag &= ~IXANY; 390 if (flags & MDMBUF) 391 cflag |= MDMBUF; 392 else 393 cflag &= ~MDMBUF; 394 if (flags&NOHANG) 395 cflag &= ~HUPCL; 396 else 397 cflag |= HUPCL; 398 lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH); 399 lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH); 400 if (flags&(LITOUT|PASS8)) { 401 iflag &= ~ISTRIP; 402 cflag &= ~(CSIZE|PARENB); 403 cflag |= CS8; 404 if (flags&LITOUT) 405 oflag &= ~OPOST; 406 if ((flags&(PASS8|RAW)) == 0) 407 iflag |= ISTRIP; 408 } else if ((flags&RAW) == 0) { 409 cflag &= ~CSIZE; 410 cflag |= CS7|PARENB; 411 oflag |= OPOST; 412 } 413 t->c_iflag = iflag; 414 t->c_oflag = oflag; 415 t->c_lflag = lflag; 416 t->c_cflag = cflag; 417 } 418 #endif /* COMPAT_43 || COMPAT_SUNOS */ 419