tty_compat.c revision 1817
1230557Sjimharris/*- 2230557Sjimharris * Copyright (c) 1982, 1986, 1991, 1993 3230557Sjimharris * The Regents of the University of California. All rights reserved. 4230557Sjimharris * 5230557Sjimharris * Redistribution and use in source and binary forms, with or without 6230557Sjimharris * modification, are permitted provided that the following conditions 7230557Sjimharris * are met: 8230557Sjimharris * 1. Redistributions of source code must retain the above copyright 9230557Sjimharris * notice, this list of conditions and the following disclaimer. 10230557Sjimharris * 2. Redistributions in binary form must reproduce the above copyright 11230557Sjimharris * notice, this list of conditions and the following disclaimer in the 12230557Sjimharris * documentation and/or other materials provided with the distribution. 13230557Sjimharris * 3. All advertising materials mentioning features or use of this software 14230557Sjimharris * must display the following acknowledgement: 15230557Sjimharris * This product includes software developed by the University of 16230557Sjimharris * California, Berkeley and its contributors. 17230557Sjimharris * 4. Neither the name of the University nor the names of its contributors 18230557Sjimharris * may be used to endorse or promote products derived from this software 19230557Sjimharris * without specific prior written permission. 20230557Sjimharris * 21230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22230557Sjimharris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23230557Sjimharris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24230557Sjimharris * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25230557Sjimharris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26230557Sjimharris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27230557Sjimharris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28230557Sjimharris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29230557Sjimharris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30230557Sjimharris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31230557Sjimharris * SUCH DAMAGE. 32230557Sjimharris * 33230557Sjimharris * @(#)tty_compat.c 8.1 (Berkeley) 6/10/93 34230557Sjimharris * $Id$ 35230557Sjimharris */ 36230557Sjimharris 37230557Sjimharris/* 38230557Sjimharris * mapping routines for old line discipline (yuck) 39230557Sjimharris */ 40230557Sjimharris#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 41230557Sjimharris 42230557Sjimharris#include <sys/param.h> 43230557Sjimharris#include <sys/systm.h> 44230557Sjimharris#include <sys/ioctl.h> 45230557Sjimharris#include <sys/proc.h> 46230557Sjimharris#include <sys/tty.h> 47230557Sjimharris#include <sys/termios.h> 48230557Sjimharris#include <sys/file.h> 49230557Sjimharris#include <sys/conf.h> 50230557Sjimharris#include <sys/kernel.h> 51230557Sjimharris#include <sys/syslog.h> 52230557Sjimharris 53230557Sjimharrisvoid ttcompatsetflags __P((struct tty *, struct termios *)); 54230557Sjimharrisvoid ttcompatsetlflags __P((struct tty *, struct termios *)); 55230557Sjimharris 56230557Sjimharrisint ttydebug = 0; 57230557Sjimharris 58230557Sjimharrisstatic struct speedtab compatspeeds[] = { 59230557Sjimharris { 38400, 15 }, 60230557Sjimharris { 19200, 14 }, 61230557Sjimharris { 9600, 13 }, 62230557Sjimharris { 4800, 12 }, 63230557Sjimharris { 2400, 11 }, 64230557Sjimharris { 1800, 10 }, 65230557Sjimharris { 1200, 9 }, 66230557Sjimharris { 600, 8 }, 67230557Sjimharris { 300, 7 }, 68230557Sjimharris { 200, 6 }, 69230557Sjimharris { 150, 5 }, 70230557Sjimharris { 134, 4 }, 71230557Sjimharris { 110, 3 }, 72230557Sjimharris { 75, 2 }, 73230557Sjimharris { 50, 1 }, 74230557Sjimharris { 0, 0 }, 75230557Sjimharris { -1, -1 }, 76230557Sjimharris}; 77230557Sjimharrisstatic int compatspcodes[16] = { 78230557Sjimharris 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 79230557Sjimharris 1800, 2400, 4800, 9600, 19200, 38400, 80230557Sjimharris}; 81230557Sjimharris 82230557Sjimharris/*ARGSUSED*/ 83230557Sjimharrisint 84230557Sjimharristtcompat(tp, com, data, flag) 85230557Sjimharris register struct tty *tp; 86230557Sjimharris int com; 87230557Sjimharris caddr_t data; 88230557Sjimharris int flag; 89230557Sjimharris{ 90230557Sjimharris 91230557Sjimharris switch (com) { 92230557Sjimharris case TIOCGETP: { 93230557Sjimharris register struct sgttyb *sg = (struct sgttyb *)data; 94230557Sjimharris register u_char *cc = tp->t_cc; 95230557Sjimharris register speed; 96230557Sjimharris 97230557Sjimharris speed = ttspeedtab(tp->t_ospeed, compatspeeds); 98230557Sjimharris sg->sg_ospeed = (speed == -1) ? 15 : speed; 99230557Sjimharris if (tp->t_ispeed == 0) 100230557Sjimharris sg->sg_ispeed = sg->sg_ospeed; 101230557Sjimharris else { 102230557Sjimharris speed = ttspeedtab(tp->t_ispeed, compatspeeds); 103230557Sjimharris sg->sg_ispeed = (speed == -1) ? 15 : speed; 104230557Sjimharris } 105230557Sjimharris sg->sg_erase = cc[VERASE]; 106230557Sjimharris sg->sg_kill = cc[VKILL]; 107230557Sjimharris sg->sg_flags = ttcompatgetflags(tp); 108230557Sjimharris break; 109230557Sjimharris } 110230557Sjimharris 111230557Sjimharris case TIOCSETP: 112230557Sjimharris case TIOCSETN: { 113230557Sjimharris register struct sgttyb *sg = (struct sgttyb *)data; 114230557Sjimharris struct termios term; 115230557Sjimharris int speed; 116230557Sjimharris 117230557Sjimharris term = tp->t_termios; 118230557Sjimharris if ((speed = sg->sg_ispeed) > 15 || speed < 0) 119230557Sjimharris term.c_ispeed = speed; 120230557Sjimharris else 121230557Sjimharris term.c_ispeed = compatspcodes[speed]; 122230557Sjimharris if ((speed = sg->sg_ospeed) > 15 || speed < 0) 123230557Sjimharris term.c_ospeed = speed; 124230557Sjimharris else 125230557Sjimharris term.c_ospeed = compatspcodes[speed]; 126230557Sjimharris term.c_cc[VERASE] = sg->sg_erase; 127230557Sjimharris term.c_cc[VKILL] = sg->sg_kill; 128230557Sjimharris tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff; 129230557Sjimharris ttcompatsetflags(tp, &term); 130230557Sjimharris return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, 131230557Sjimharris &term, flag)); 132230557Sjimharris } 133230557Sjimharris 134230557Sjimharris case TIOCGETC: { 135230557Sjimharris struct tchars *tc = (struct tchars *)data; 136230557Sjimharris register u_char *cc = tp->t_cc; 137230557Sjimharris 138230557Sjimharris tc->t_intrc = cc[VINTR]; 139230557Sjimharris tc->t_quitc = cc[VQUIT]; 140230557Sjimharris tc->t_startc = cc[VSTART]; 141230557Sjimharris tc->t_stopc = cc[VSTOP]; 142230557Sjimharris tc->t_eofc = cc[VEOF]; 143230557Sjimharris tc->t_brkc = cc[VEOL]; 144230557Sjimharris break; 145230557Sjimharris } 146230557Sjimharris case TIOCSETC: { 147230557Sjimharris struct tchars *tc = (struct tchars *)data; 148230557Sjimharris register u_char *cc = tp->t_cc; 149230557Sjimharris 150230557Sjimharris cc[VINTR] = tc->t_intrc; 151230557Sjimharris cc[VQUIT] = tc->t_quitc; 152230557Sjimharris cc[VSTART] = tc->t_startc; 153230557Sjimharris cc[VSTOP] = tc->t_stopc; 154230557Sjimharris cc[VEOF] = tc->t_eofc; 155230557Sjimharris cc[VEOL] = tc->t_brkc; 156230557Sjimharris if (tc->t_brkc == -1) 157230557Sjimharris cc[VEOL2] = _POSIX_VDISABLE; 158230557Sjimharris break; 159230557Sjimharris } 160230557Sjimharris case TIOCSLTC: { 161230557Sjimharris struct ltchars *ltc = (struct ltchars *)data; 162230557Sjimharris register u_char *cc = tp->t_cc; 163230557Sjimharris 164230557Sjimharris cc[VSUSP] = ltc->t_suspc; 165230557Sjimharris cc[VDSUSP] = ltc->t_dsuspc; 166230557Sjimharris cc[VREPRINT] = ltc->t_rprntc; 167230557Sjimharris cc[VDISCARD] = ltc->t_flushc; 168230557Sjimharris cc[VWERASE] = ltc->t_werasc; 169230557Sjimharris cc[VLNEXT] = ltc->t_lnextc; 170230557Sjimharris break; 171230557Sjimharris } 172230557Sjimharris case TIOCGLTC: { 173230557Sjimharris struct ltchars *ltc = (struct ltchars *)data; 174230557Sjimharris register u_char *cc = tp->t_cc; 175230557Sjimharris 176230557Sjimharris ltc->t_suspc = cc[VSUSP]; 177230557Sjimharris ltc->t_dsuspc = cc[VDSUSP]; 178230557Sjimharris ltc->t_rprntc = cc[VREPRINT]; 179230557Sjimharris ltc->t_flushc = cc[VDISCARD]; 180230557Sjimharris ltc->t_werasc = cc[VWERASE]; 181230557Sjimharris ltc->t_lnextc = cc[VLNEXT]; 182230557Sjimharris break; 183230557Sjimharris } 184230557Sjimharris case TIOCLBIS: 185230557Sjimharris case TIOCLBIC: 186230557Sjimharris case TIOCLSET: { 187230557Sjimharris struct termios term; 188230557Sjimharris 189230557Sjimharris term = tp->t_termios; 190230557Sjimharris if (com == TIOCLSET) 191230557Sjimharris tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 192230557Sjimharris else { 193230557Sjimharris tp->t_flags = 194230557Sjimharris (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 195230557Sjimharris if (com == TIOCLBIS) 196230557Sjimharris tp->t_flags |= *(int *)data<<16; 197230557Sjimharris else 198230557Sjimharris tp->t_flags &= ~(*(int *)data<<16); 199230557Sjimharris } 200230557Sjimharris ttcompatsetlflags(tp, &term); 201230557Sjimharris return (ttioctl(tp, TIOCSETA, &term, flag)); 202230557Sjimharris } 203230557Sjimharris case TIOCLGET: 204230557Sjimharris *(int *)data = ttcompatgetflags(tp)>>16; 205230557Sjimharris if (ttydebug) 206230557Sjimharris printf("CLGET: returning %x\n", *(int *)data); 207230557Sjimharris break; 208230557Sjimharris 209230557Sjimharris case OTIOCGETD: 210230557Sjimharris *(int *)data = tp->t_line ? tp->t_line : 2; 211230557Sjimharris break; 212230557Sjimharris 213230557Sjimharris case OTIOCSETD: { 214230557Sjimharris int ldisczero = 0; 215230557Sjimharris 216230557Sjimharris return (ttioctl(tp, TIOCSETD, 217230557Sjimharris *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag)); 218230557Sjimharris } 219230557Sjimharris 220230557Sjimharris case OTIOCCONS: 221230557Sjimharris *(int *)data = 1; 222230557Sjimharris return (ttioctl(tp, TIOCCONS, data, flag)); 223230557Sjimharris 224230557Sjimharris default: 225230557Sjimharris return (-1); 226230557Sjimharris } 227230557Sjimharris return (0); 228230557Sjimharris} 229230557Sjimharris 230230557Sjimharrisint 231230557Sjimharristtcompatgetflags(tp) 232230557Sjimharris register struct tty *tp; 233230557Sjimharris{ 234230557Sjimharris register long iflag = tp->t_iflag; 235230557Sjimharris register long lflag = tp->t_lflag; 236230557Sjimharris register long oflag = tp->t_oflag; 237230557Sjimharris register long cflag = tp->t_cflag; 238230557Sjimharris register flags = 0; 239230557Sjimharris 240230557Sjimharris if (iflag&IXOFF) 241230557Sjimharris flags |= TANDEM; 242230557Sjimharris if (iflag&ICRNL || oflag&ONLCR) 243230557Sjimharris flags |= CRMOD; 244230557Sjimharris if (cflag&PARENB) { 245230557Sjimharris if (iflag&INPCK) { 246230557Sjimharris if (cflag&PARODD) 247230557Sjimharris 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); 283if (ttydebug) 284 printf("getflags: %x\n", flags); 285 return (flags); 286} 287 288void 289ttcompatsetflags(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 360void 361ttcompatsetlflags(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