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 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)tty_compat.c 8.1 (Berkeley) 6/10/93 30 */ 31 32#include <sys/cdefs.h>
| 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 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)tty_compat.c 8.1 (Berkeley) 6/10/93 30 */ 31 32#include <sys/cdefs.h>
|
37/* 38 * mapping routines for old line discipline (yuck) 39 */ 40#if defined(COMPAT_43) 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/ioctl_compat.h> 45#include <sys/tty.h> 46#include <sys/kernel.h> 47#include <sys/sysctl.h> 48 49static int ttcompatgetflags(struct tty *tp); 50static void ttcompatsetflags(struct tty *tp, struct termios *t); 51static void ttcompatsetlflags(struct tty *tp, struct termios *t); 52static int ttcompatspeedtab(int speed, struct speedtab *table); 53 54static int ttydebug = 0; 55SYSCTL_INT(_debug, OID_AUTO, ttydebug, CTLFLAG_RW, &ttydebug, 0, ""); 56 57static struct speedtab compatspeeds[] = { 58#define MAX_SPEED 17 59 { 115200, 17 }, 60 { 57600, 16 }, 61 { 38400, 15 }, 62 { 19200, 14 }, 63 { 9600, 13 }, 64 { 4800, 12 }, 65 { 2400, 11 }, 66 { 1800, 10 }, 67 { 1200, 9 }, 68 { 600, 8 }, 69 { 300, 7 }, 70 { 200, 6 }, 71 { 150, 5 }, 72 { 134, 4 }, 73 { 110, 3 }, 74 { 75, 2 }, 75 { 50, 1 }, 76 { 0, 0 }, 77 { -1, -1 }, 78}; 79static int compatspcodes[] = { 80 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 81 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 82}; 83 84static int 85ttcompatspeedtab(int speed, struct speedtab *table) 86{ 87 if (speed == 0) 88 return (0); /* hangup */ 89 for ( ; table->sp_speed > 0; table++) 90 if (table->sp_speed <= speed) /* nearest one, rounded down */ 91 return (table->sp_code); 92 return (1); /* 50, min and not hangup */ 93} 94 95int 96ttsetcompat(struct tty *tp, u_long *com, caddr_t data, struct termios *term) 97{ 98 switch (*com) { 99 case TIOCSETP: 100 case TIOCSETN: { 101 struct sgttyb *sg = (struct sgttyb *)data; 102 int speed; 103 104 if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0) 105 return(EINVAL); 106 else if (speed != ttcompatspeedtab(tp->t_ispeed, compatspeeds)) 107 term->c_ispeed = compatspcodes[speed]; 108 else 109 term->c_ispeed = tp->t_ispeed; 110 if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0) 111 return(EINVAL); 112 else if (speed != ttcompatspeedtab(tp->t_ospeed, compatspeeds)) 113 term->c_ospeed = compatspcodes[speed]; 114 else 115 term->c_ospeed = tp->t_ospeed; 116 term->c_cc[VERASE] = sg->sg_erase; 117 term->c_cc[VKILL] = sg->sg_kill; 118 tp->t_flags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff); 119 ttcompatsetflags(tp, term); 120 *com = (*com == TIOCSETP) ? TIOCSETAF : TIOCSETA; 121 break; 122 } 123 case TIOCSETC: { 124 struct tchars *tc = (struct tchars *)data; 125 cc_t *cc; 126 127 cc = term->c_cc; 128 cc[VINTR] = tc->t_intrc; 129 cc[VQUIT] = tc->t_quitc; 130 cc[VSTART] = tc->t_startc; 131 cc[VSTOP] = tc->t_stopc; 132 cc[VEOF] = tc->t_eofc; 133 cc[VEOL] = tc->t_brkc; 134 if (tc->t_brkc == (char)_POSIX_VDISABLE) 135 cc[VEOL2] = _POSIX_VDISABLE; 136 *com = TIOCSETA; 137 break; 138 } 139 case TIOCSLTC: { 140 struct ltchars *ltc = (struct ltchars *)data; 141 cc_t *cc; 142 143 cc = term->c_cc; 144 cc[VSUSP] = ltc->t_suspc; 145 cc[VDSUSP] = ltc->t_dsuspc; 146 cc[VREPRINT] = ltc->t_rprntc; 147 cc[VDISCARD] = ltc->t_flushc; 148 cc[VWERASE] = ltc->t_werasc; 149 cc[VLNEXT] = ltc->t_lnextc; 150 *com = TIOCSETA; 151 break; 152 } 153 case TIOCLBIS: 154 case TIOCLBIC: 155 case TIOCLSET: 156 if (*com == TIOCLSET) 157 tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 158 else { 159 tp->t_flags = 160 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 161 if (*com == TIOCLBIS) 162 tp->t_flags |= *(int *)data<<16; 163 else 164 tp->t_flags &= ~(*(int *)data<<16); 165 } 166 ttcompatsetlflags(tp, term); 167 *com = TIOCSETA; 168 break; 169 } 170 return 0; 171} 172 173/*ARGSUSED*/ 174int 175ttcompat(struct tty *tp, u_long com, caddr_t data, int flag) 176{ 177 switch (com) { 178 case TIOCSETP: 179 case TIOCSETN: 180 case TIOCSETC: 181 case TIOCSLTC: 182 case TIOCLBIS: 183 case TIOCLBIC: 184 case TIOCLSET: { 185 struct termios term; 186 int error; 187 188 term = tp->t_termios; 189 if ((error = ttsetcompat(tp, &com, data, &term)) != 0) 190 return error; 191 return ttioctl(tp, com, &term, flag); 192 } 193 case TIOCGETP: { 194 struct sgttyb *sg = (struct sgttyb *)data; 195 cc_t *cc = tp->t_cc; 196 197 sg->sg_ospeed = ttcompatspeedtab(tp->t_ospeed, compatspeeds); 198 if (tp->t_ispeed == 0) 199 sg->sg_ispeed = sg->sg_ospeed; 200 else 201 sg->sg_ispeed = ttcompatspeedtab(tp->t_ispeed, compatspeeds); 202 sg->sg_erase = cc[VERASE]; 203 sg->sg_kill = cc[VKILL]; 204 sg->sg_flags = tp->t_flags = ttcompatgetflags(tp); 205 break; 206 } 207 case TIOCGETC: { 208 struct tchars *tc = (struct tchars *)data; 209 cc_t *cc = tp->t_cc; 210 211 tc->t_intrc = cc[VINTR]; 212 tc->t_quitc = cc[VQUIT]; 213 tc->t_startc = cc[VSTART]; 214 tc->t_stopc = cc[VSTOP]; 215 tc->t_eofc = cc[VEOF]; 216 tc->t_brkc = cc[VEOL]; 217 break; 218 } 219 case TIOCGLTC: { 220 struct ltchars *ltc = (struct ltchars *)data; 221 cc_t *cc = tp->t_cc; 222 223 ltc->t_suspc = cc[VSUSP]; 224 ltc->t_dsuspc = cc[VDSUSP]; 225 ltc->t_rprntc = cc[VREPRINT]; 226 ltc->t_flushc = cc[VDISCARD]; 227 ltc->t_werasc = cc[VWERASE]; 228 ltc->t_lnextc = cc[VLNEXT]; 229 break; 230 } 231 case TIOCLGET: 232 tp->t_flags = 233 (ttcompatgetflags(tp) & 0xffff0000UL) 234 | (tp->t_flags & 0xffff); 235 *(int *)data = tp->t_flags>>16; 236 if (ttydebug) 237 printf("CLGET: returning %x\n", *(int *)data); 238 break; 239 240 case OTIOCGETD: 241 *(int *)data = tp->t_line ? tp->t_line : 2; 242 break; 243 244 case OTIOCSETD: { 245 int ldisczero = 0; 246 247 return (ttioctl(tp, TIOCSETD, 248 *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag)); 249 } 250 251 case OTIOCCONS: 252 *(int *)data = 1; 253 return (ttioctl(tp, TIOCCONS, data, flag)); 254 255 default: 256 return (ENOIOCTL); 257 } 258 return (0); 259} 260 261static int 262ttcompatgetflags(struct tty *tp) 263{ 264 tcflag_t iflag = tp->t_iflag; 265 tcflag_t lflag = tp->t_lflag; 266 tcflag_t oflag = tp->t_oflag; 267 tcflag_t cflag = tp->t_cflag; 268 int flags = 0; 269 270 if (iflag&IXOFF) 271 flags |= TANDEM; 272 if (iflag&ICRNL || oflag&ONLCR) 273 flags |= CRMOD; 274 if ((cflag&CSIZE) == CS8) { 275 flags |= PASS8; 276 if (iflag&ISTRIP) 277 flags |= ANYP; 278 } 279 else if (cflag&PARENB) { 280 if (iflag&INPCK) { 281 if (cflag&PARODD) 282 flags |= ODDP; 283 else 284 flags |= EVENP; 285 } else 286 flags |= EVENP | ODDP; 287 } 288 289 if ((lflag&ICANON) == 0) { 290 /* fudge */ 291 if (iflag&(INPCK|ISTRIP|IXON) || lflag&(IEXTEN|ISIG) 292 || (cflag&(CSIZE|PARENB)) != CS8) 293 flags |= CBREAK; 294 else 295 flags |= RAW; 296 } 297 if (!(flags&RAW) && !(oflag&OPOST) && (cflag&(CSIZE|PARENB)) == CS8) 298 flags |= LITOUT; 299 if (cflag&MDMBUF) 300 flags |= MDMBUF; 301 if ((cflag&HUPCL) == 0) 302 flags |= NOHANG; 303 if (oflag&OXTABS) 304 flags |= XTABS; 305 if (lflag&ECHOE) 306 flags |= CRTERA|CRTBS; 307 if (lflag&ECHOKE) 308 flags |= CRTKIL|CRTBS; 309 if (lflag&ECHOPRT) 310 flags |= PRTERA; 311 if (lflag&ECHOCTL) 312 flags |= CTLECH; 313 if ((iflag&IXANY) == 0) 314 flags |= DECCTQ; 315 flags |= lflag&(ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH); 316 if (ttydebug) 317 printf("getflags: %x\n", flags); 318 return (flags); 319} 320 321static void 322ttcompatsetflags(struct tty *tp, struct termios *t) 323{ 324 int flags = tp->t_flags; 325 tcflag_t iflag = t->c_iflag; 326 tcflag_t oflag = t->c_oflag; 327 tcflag_t lflag = t->c_lflag; 328 tcflag_t cflag = t->c_cflag; 329 330 if (flags & RAW) { 331 iflag = IGNBRK; 332 lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); 333 } else { 334 iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR); 335 iflag |= BRKINT|IXON|IMAXBEL; 336 lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */ 337 if (flags & XTABS) 338 oflag |= OXTABS; 339 else 340 oflag &= ~OXTABS; 341 if (flags & CBREAK) 342 lflag &= ~ICANON; 343 else 344 lflag |= ICANON; 345 if (flags&CRMOD) { 346 iflag |= ICRNL; 347 oflag |= ONLCR; 348 } else { 349 iflag &= ~ICRNL; 350 oflag &= ~ONLCR; 351 } 352 } 353 if (flags&ECHO) 354 lflag |= ECHO; 355 else 356 lflag &= ~ECHO; 357 358 cflag &= ~(CSIZE|PARENB); 359 if (flags&(RAW|LITOUT|PASS8)) { 360 cflag |= CS8; 361 if (!(flags&(RAW|PASS8)) 362 || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) 363 iflag |= ISTRIP; 364 else 365 iflag &= ~ISTRIP; 366 if (flags&(RAW|LITOUT)) 367 oflag &= ~OPOST; 368 else 369 oflag |= OPOST; 370 } else { 371 cflag |= CS7|PARENB; 372 iflag |= ISTRIP; 373 oflag |= OPOST; 374 } 375 /* XXX don't set INPCK if RAW or PASS8? */ 376 if ((flags&(EVENP|ODDP)) == EVENP) { 377 iflag |= INPCK; 378 cflag &= ~PARODD; 379 } else if ((flags&(EVENP|ODDP)) == ODDP) { 380 iflag |= INPCK; 381 cflag |= PARODD; 382 } else 383 iflag &= ~INPCK; 384 if (flags&TANDEM) 385 iflag |= IXOFF; 386 else 387 iflag &= ~IXOFF; 388 if ((flags&DECCTQ) == 0) 389 iflag |= IXANY; 390 else 391 iflag &= ~IXANY; 392 t->c_iflag = iflag; 393 t->c_oflag = oflag; 394 t->c_lflag = lflag; 395 t->c_cflag = cflag; 396} 397 398static void 399ttcompatsetlflags(struct tty *tp, struct termios *t) 400{ 401 int flags = tp->t_flags; 402 tcflag_t iflag = t->c_iflag; 403 tcflag_t oflag = t->c_oflag; 404 tcflag_t lflag = t->c_lflag; 405 tcflag_t cflag = t->c_cflag; 406 407 iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR); 408 if (flags&CRTERA) 409 lflag |= ECHOE; 410 else 411 lflag &= ~ECHOE; 412 if (flags&CRTKIL) 413 lflag |= ECHOKE; 414 else 415 lflag &= ~ECHOKE; 416 if (flags&PRTERA) 417 lflag |= ECHOPRT; 418 else 419 lflag &= ~ECHOPRT; 420 if (flags&CTLECH) 421 lflag |= ECHOCTL; 422 else 423 lflag &= ~ECHOCTL; 424 if (flags&TANDEM) 425 iflag |= IXOFF; 426 else 427 iflag &= ~IXOFF; 428 if ((flags&DECCTQ) == 0) 429 iflag |= IXANY; 430 else 431 iflag &= ~IXANY; 432 if (flags & MDMBUF) 433 cflag |= MDMBUF; 434 else 435 cflag &= ~MDMBUF; 436 if (flags&NOHANG) 437 cflag &= ~HUPCL; 438 else 439 cflag |= HUPCL; 440 lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH); 441 lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH); 442 443 /* 444 * The next if-else statement is copied from above so don't bother 445 * checking it separately. We could avoid fiddlling with the 446 * character size if the mode is already RAW or if neither the 447 * LITOUT bit or the PASS8 bit is being changed, but the delta of 448 * the change is not available here and skipping the RAW case would 449 * make the code different from above. 450 */ 451 cflag &= ~(CSIZE|PARENB); 452 if (flags&(RAW|LITOUT|PASS8)) { 453 cflag |= CS8; 454 if (!(flags&(RAW|PASS8)) 455 || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) 456 iflag |= ISTRIP; 457 else 458 iflag &= ~ISTRIP; 459 if (flags&(RAW|LITOUT)) 460 oflag &= ~OPOST; 461 else 462 oflag |= OPOST; 463 } else { 464 cflag |= CS7|PARENB; 465 iflag |= ISTRIP; 466 oflag |= OPOST; 467 } 468 t->c_iflag = iflag; 469 t->c_oflag = oflag; 470 t->c_lflag = lflag; 471 t->c_cflag = cflag; 472} 473#endif /* COMPAT_43 */
| 38/* 39 * mapping routines for old line discipline (yuck) 40 */ 41#if defined(COMPAT_43) 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/ioctl_compat.h> 46#include <sys/tty.h> 47#include <sys/kernel.h> 48#include <sys/sysctl.h> 49 50static int ttcompatgetflags(struct tty *tp); 51static void ttcompatsetflags(struct tty *tp, struct termios *t); 52static void ttcompatsetlflags(struct tty *tp, struct termios *t); 53static int ttcompatspeedtab(int speed, struct speedtab *table); 54 55static int ttydebug = 0; 56SYSCTL_INT(_debug, OID_AUTO, ttydebug, CTLFLAG_RW, &ttydebug, 0, ""); 57 58static struct speedtab compatspeeds[] = { 59#define MAX_SPEED 17 60 { 115200, 17 }, 61 { 57600, 16 }, 62 { 38400, 15 }, 63 { 19200, 14 }, 64 { 9600, 13 }, 65 { 4800, 12 }, 66 { 2400, 11 }, 67 { 1800, 10 }, 68 { 1200, 9 }, 69 { 600, 8 }, 70 { 300, 7 }, 71 { 200, 6 }, 72 { 150, 5 }, 73 { 134, 4 }, 74 { 110, 3 }, 75 { 75, 2 }, 76 { 50, 1 }, 77 { 0, 0 }, 78 { -1, -1 }, 79}; 80static int compatspcodes[] = { 81 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 82 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 83}; 84 85static int 86ttcompatspeedtab(int speed, struct speedtab *table) 87{ 88 if (speed == 0) 89 return (0); /* hangup */ 90 for ( ; table->sp_speed > 0; table++) 91 if (table->sp_speed <= speed) /* nearest one, rounded down */ 92 return (table->sp_code); 93 return (1); /* 50, min and not hangup */ 94} 95 96int 97ttsetcompat(struct tty *tp, u_long *com, caddr_t data, struct termios *term) 98{ 99 switch (*com) { 100 case TIOCSETP: 101 case TIOCSETN: { 102 struct sgttyb *sg = (struct sgttyb *)data; 103 int speed; 104 105 if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0) 106 return(EINVAL); 107 else if (speed != ttcompatspeedtab(tp->t_ispeed, compatspeeds)) 108 term->c_ispeed = compatspcodes[speed]; 109 else 110 term->c_ispeed = tp->t_ispeed; 111 if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0) 112 return(EINVAL); 113 else if (speed != ttcompatspeedtab(tp->t_ospeed, compatspeeds)) 114 term->c_ospeed = compatspcodes[speed]; 115 else 116 term->c_ospeed = tp->t_ospeed; 117 term->c_cc[VERASE] = sg->sg_erase; 118 term->c_cc[VKILL] = sg->sg_kill; 119 tp->t_flags = (tp->t_flags&0xffff0000) | (sg->sg_flags&0xffff); 120 ttcompatsetflags(tp, term); 121 *com = (*com == TIOCSETP) ? TIOCSETAF : TIOCSETA; 122 break; 123 } 124 case TIOCSETC: { 125 struct tchars *tc = (struct tchars *)data; 126 cc_t *cc; 127 128 cc = term->c_cc; 129 cc[VINTR] = tc->t_intrc; 130 cc[VQUIT] = tc->t_quitc; 131 cc[VSTART] = tc->t_startc; 132 cc[VSTOP] = tc->t_stopc; 133 cc[VEOF] = tc->t_eofc; 134 cc[VEOL] = tc->t_brkc; 135 if (tc->t_brkc == (char)_POSIX_VDISABLE) 136 cc[VEOL2] = _POSIX_VDISABLE; 137 *com = TIOCSETA; 138 break; 139 } 140 case TIOCSLTC: { 141 struct ltchars *ltc = (struct ltchars *)data; 142 cc_t *cc; 143 144 cc = term->c_cc; 145 cc[VSUSP] = ltc->t_suspc; 146 cc[VDSUSP] = ltc->t_dsuspc; 147 cc[VREPRINT] = ltc->t_rprntc; 148 cc[VDISCARD] = ltc->t_flushc; 149 cc[VWERASE] = ltc->t_werasc; 150 cc[VLNEXT] = ltc->t_lnextc; 151 *com = TIOCSETA; 152 break; 153 } 154 case TIOCLBIS: 155 case TIOCLBIC: 156 case TIOCLSET: 157 if (*com == TIOCLSET) 158 tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 159 else { 160 tp->t_flags = 161 (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 162 if (*com == TIOCLBIS) 163 tp->t_flags |= *(int *)data<<16; 164 else 165 tp->t_flags &= ~(*(int *)data<<16); 166 } 167 ttcompatsetlflags(tp, term); 168 *com = TIOCSETA; 169 break; 170 } 171 return 0; 172} 173 174/*ARGSUSED*/ 175int 176ttcompat(struct tty *tp, u_long com, caddr_t data, int flag) 177{ 178 switch (com) { 179 case TIOCSETP: 180 case TIOCSETN: 181 case TIOCSETC: 182 case TIOCSLTC: 183 case TIOCLBIS: 184 case TIOCLBIC: 185 case TIOCLSET: { 186 struct termios term; 187 int error; 188 189 term = tp->t_termios; 190 if ((error = ttsetcompat(tp, &com, data, &term)) != 0) 191 return error; 192 return ttioctl(tp, com, &term, flag); 193 } 194 case TIOCGETP: { 195 struct sgttyb *sg = (struct sgttyb *)data; 196 cc_t *cc = tp->t_cc; 197 198 sg->sg_ospeed = ttcompatspeedtab(tp->t_ospeed, compatspeeds); 199 if (tp->t_ispeed == 0) 200 sg->sg_ispeed = sg->sg_ospeed; 201 else 202 sg->sg_ispeed = ttcompatspeedtab(tp->t_ispeed, compatspeeds); 203 sg->sg_erase = cc[VERASE]; 204 sg->sg_kill = cc[VKILL]; 205 sg->sg_flags = tp->t_flags = ttcompatgetflags(tp); 206 break; 207 } 208 case TIOCGETC: { 209 struct tchars *tc = (struct tchars *)data; 210 cc_t *cc = tp->t_cc; 211 212 tc->t_intrc = cc[VINTR]; 213 tc->t_quitc = cc[VQUIT]; 214 tc->t_startc = cc[VSTART]; 215 tc->t_stopc = cc[VSTOP]; 216 tc->t_eofc = cc[VEOF]; 217 tc->t_brkc = cc[VEOL]; 218 break; 219 } 220 case TIOCGLTC: { 221 struct ltchars *ltc = (struct ltchars *)data; 222 cc_t *cc = tp->t_cc; 223 224 ltc->t_suspc = cc[VSUSP]; 225 ltc->t_dsuspc = cc[VDSUSP]; 226 ltc->t_rprntc = cc[VREPRINT]; 227 ltc->t_flushc = cc[VDISCARD]; 228 ltc->t_werasc = cc[VWERASE]; 229 ltc->t_lnextc = cc[VLNEXT]; 230 break; 231 } 232 case TIOCLGET: 233 tp->t_flags = 234 (ttcompatgetflags(tp) & 0xffff0000UL) 235 | (tp->t_flags & 0xffff); 236 *(int *)data = tp->t_flags>>16; 237 if (ttydebug) 238 printf("CLGET: returning %x\n", *(int *)data); 239 break; 240 241 case OTIOCGETD: 242 *(int *)data = tp->t_line ? tp->t_line : 2; 243 break; 244 245 case OTIOCSETD: { 246 int ldisczero = 0; 247 248 return (ttioctl(tp, TIOCSETD, 249 *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag)); 250 } 251 252 case OTIOCCONS: 253 *(int *)data = 1; 254 return (ttioctl(tp, TIOCCONS, data, flag)); 255 256 default: 257 return (ENOIOCTL); 258 } 259 return (0); 260} 261 262static int 263ttcompatgetflags(struct tty *tp) 264{ 265 tcflag_t iflag = tp->t_iflag; 266 tcflag_t lflag = tp->t_lflag; 267 tcflag_t oflag = tp->t_oflag; 268 tcflag_t cflag = tp->t_cflag; 269 int flags = 0; 270 271 if (iflag&IXOFF) 272 flags |= TANDEM; 273 if (iflag&ICRNL || oflag&ONLCR) 274 flags |= CRMOD; 275 if ((cflag&CSIZE) == CS8) { 276 flags |= PASS8; 277 if (iflag&ISTRIP) 278 flags |= ANYP; 279 } 280 else if (cflag&PARENB) { 281 if (iflag&INPCK) { 282 if (cflag&PARODD) 283 flags |= ODDP; 284 else 285 flags |= EVENP; 286 } else 287 flags |= EVENP | ODDP; 288 } 289 290 if ((lflag&ICANON) == 0) { 291 /* fudge */ 292 if (iflag&(INPCK|ISTRIP|IXON) || lflag&(IEXTEN|ISIG) 293 || (cflag&(CSIZE|PARENB)) != CS8) 294 flags |= CBREAK; 295 else 296 flags |= RAW; 297 } 298 if (!(flags&RAW) && !(oflag&OPOST) && (cflag&(CSIZE|PARENB)) == CS8) 299 flags |= LITOUT; 300 if (cflag&MDMBUF) 301 flags |= MDMBUF; 302 if ((cflag&HUPCL) == 0) 303 flags |= NOHANG; 304 if (oflag&OXTABS) 305 flags |= XTABS; 306 if (lflag&ECHOE) 307 flags |= CRTERA|CRTBS; 308 if (lflag&ECHOKE) 309 flags |= CRTKIL|CRTBS; 310 if (lflag&ECHOPRT) 311 flags |= PRTERA; 312 if (lflag&ECHOCTL) 313 flags |= CTLECH; 314 if ((iflag&IXANY) == 0) 315 flags |= DECCTQ; 316 flags |= lflag&(ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH); 317 if (ttydebug) 318 printf("getflags: %x\n", flags); 319 return (flags); 320} 321 322static void 323ttcompatsetflags(struct tty *tp, struct termios *t) 324{ 325 int flags = tp->t_flags; 326 tcflag_t iflag = t->c_iflag; 327 tcflag_t oflag = t->c_oflag; 328 tcflag_t lflag = t->c_lflag; 329 tcflag_t cflag = t->c_cflag; 330 331 if (flags & RAW) { 332 iflag = IGNBRK; 333 lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); 334 } else { 335 iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR); 336 iflag |= BRKINT|IXON|IMAXBEL; 337 lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */ 338 if (flags & XTABS) 339 oflag |= OXTABS; 340 else 341 oflag &= ~OXTABS; 342 if (flags & CBREAK) 343 lflag &= ~ICANON; 344 else 345 lflag |= ICANON; 346 if (flags&CRMOD) { 347 iflag |= ICRNL; 348 oflag |= ONLCR; 349 } else { 350 iflag &= ~ICRNL; 351 oflag &= ~ONLCR; 352 } 353 } 354 if (flags&ECHO) 355 lflag |= ECHO; 356 else 357 lflag &= ~ECHO; 358 359 cflag &= ~(CSIZE|PARENB); 360 if (flags&(RAW|LITOUT|PASS8)) { 361 cflag |= CS8; 362 if (!(flags&(RAW|PASS8)) 363 || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) 364 iflag |= ISTRIP; 365 else 366 iflag &= ~ISTRIP; 367 if (flags&(RAW|LITOUT)) 368 oflag &= ~OPOST; 369 else 370 oflag |= OPOST; 371 } else { 372 cflag |= CS7|PARENB; 373 iflag |= ISTRIP; 374 oflag |= OPOST; 375 } 376 /* XXX don't set INPCK if RAW or PASS8? */ 377 if ((flags&(EVENP|ODDP)) == EVENP) { 378 iflag |= INPCK; 379 cflag &= ~PARODD; 380 } else if ((flags&(EVENP|ODDP)) == ODDP) { 381 iflag |= INPCK; 382 cflag |= PARODD; 383 } else 384 iflag &= ~INPCK; 385 if (flags&TANDEM) 386 iflag |= IXOFF; 387 else 388 iflag &= ~IXOFF; 389 if ((flags&DECCTQ) == 0) 390 iflag |= IXANY; 391 else 392 iflag &= ~IXANY; 393 t->c_iflag = iflag; 394 t->c_oflag = oflag; 395 t->c_lflag = lflag; 396 t->c_cflag = cflag; 397} 398 399static void 400ttcompatsetlflags(struct tty *tp, struct termios *t) 401{ 402 int flags = tp->t_flags; 403 tcflag_t iflag = t->c_iflag; 404 tcflag_t oflag = t->c_oflag; 405 tcflag_t lflag = t->c_lflag; 406 tcflag_t cflag = t->c_cflag; 407 408 iflag &= ~(PARMRK|IGNPAR|IGNCR|INLCR); 409 if (flags&CRTERA) 410 lflag |= ECHOE; 411 else 412 lflag &= ~ECHOE; 413 if (flags&CRTKIL) 414 lflag |= ECHOKE; 415 else 416 lflag &= ~ECHOKE; 417 if (flags&PRTERA) 418 lflag |= ECHOPRT; 419 else 420 lflag &= ~ECHOPRT; 421 if (flags&CTLECH) 422 lflag |= ECHOCTL; 423 else 424 lflag &= ~ECHOCTL; 425 if (flags&TANDEM) 426 iflag |= IXOFF; 427 else 428 iflag &= ~IXOFF; 429 if ((flags&DECCTQ) == 0) 430 iflag |= IXANY; 431 else 432 iflag &= ~IXANY; 433 if (flags & MDMBUF) 434 cflag |= MDMBUF; 435 else 436 cflag &= ~MDMBUF; 437 if (flags&NOHANG) 438 cflag &= ~HUPCL; 439 else 440 cflag |= HUPCL; 441 lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH); 442 lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH); 443 444 /* 445 * The next if-else statement is copied from above so don't bother 446 * checking it separately. We could avoid fiddlling with the 447 * character size if the mode is already RAW or if neither the 448 * LITOUT bit or the PASS8 bit is being changed, but the delta of 449 * the change is not available here and skipping the RAW case would 450 * make the code different from above. 451 */ 452 cflag &= ~(CSIZE|PARENB); 453 if (flags&(RAW|LITOUT|PASS8)) { 454 cflag |= CS8; 455 if (!(flags&(RAW|PASS8)) 456 || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) 457 iflag |= ISTRIP; 458 else 459 iflag &= ~ISTRIP; 460 if (flags&(RAW|LITOUT)) 461 oflag &= ~OPOST; 462 else 463 oflag |= OPOST; 464 } else { 465 cflag |= CS7|PARENB; 466 iflag |= ISTRIP; 467 oflag |= OPOST; 468 } 469 t->c_iflag = iflag; 470 t->c_oflag = oflag; 471 t->c_lflag = lflag; 472 t->c_cflag = cflag; 473} 474#endif /* COMPAT_43 */
|