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