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