Return to BSD News archive
Path: sserve!manuel.anu.edu.au!munnari.oz.au!news.hawaii.edu!ames!sun-barr!cs.utexas.edu!uunet!mcsun!fuug!kiae!demos!newsserv From: "Andrew A. Chernov, Black Mage" <ache@astral.msk.su> Resent-From: "Andrew A. Chernov, Black Mage" <ache@astral.msk.su> Newsgroups: comp.unix.bsd Subject: [386bsd] 3rd patch for tty COMPAT_43 modes (great win!) Date: Wed, 09 Dec 92 23:11:17 +0300 Distribution: world Organization: Ha-oh-lahm Yetzirah Message-ID: <RHbBb9hSE0@astral.msk.su> Sender: news-service@newcom.kiae.su Reply-To: ache@astral.msk.su Lines: 243 Hi, folks. Main problem are, that in switching to RAW or CBREAK modes and back tty driver lost some flags and some flags are incorrect. The most significant bug is lost CS8 character size. I produce two patches to fix it, but problem are deeper. In 3rd patch I decide return back to original driver concept, use tp->t_flag field and completely rewrite old patches. Now, if program call gtty, modes stored into tp->t_flag, for later stty call. Advantages: 1) Can preserve CS8 mode 2) Can preserve ISTRIP mode in CS8 mode 3) Can preserve parity modes in CS7 mode 4) LITOUT mode doesn't stuck. 5) Can preserve IXANY mode Disadvantages: 1) Using POSIX tty ioctls mixed with old-style ioctl cause wrong results (present in original driver). 2) Can't handle output parity without corresponding input parity, if even or odd parity set (impossible in old-style ioctls). 3) Using TIOCLGET after stty and may produce wrong results. IMHO, it doesn't matter, because all programs I seen first get all modes, then set. In original driver using TIOCLGET before gtty may produce wrong results. WARNING: apply this patch ONLY if two previous my patches installed. Because my patches goes so far I just produce united (1-3) patch in separate message. *** tty_compat.c.was2 Wed Dec 2 23:05:17 1992 --- tty_compat.c Wed Dec 9 05:45:34 1992 *************** *** 98,104 **** } sg->sg_erase = cc[VERASE]; sg->sg_kill = cc[VKILL]; ! sg->sg_flags = ttcompatgetflags(tp); break; } --- 98,104 ---- } sg->sg_erase = cc[VERASE]; sg->sg_kill = cc[VKILL]; ! sg->sg_flags = tp->t_flags = ttcompatgetflags(tp); break; } *************** *** 119,125 **** term.c_ospeed = compatspcodes[speed]; term.c_cc[VERASE] = sg->sg_erase; term.c_cc[VKILL] = sg->sg_kill; ! tp->t_flags = ttcompatgetflags(tp)&0xffff0000 | sg->sg_flags&0xffff; ttcompatsetflags(tp, &term); return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, &term, flag)); --- 119,125 ---- term.c_ospeed = compatspcodes[speed]; term.c_cc[VERASE] = sg->sg_erase; term.c_cc[VKILL] = sg->sg_kill; ! tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff; ttcompatsetflags(tp, &term); return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, &term, flag)); *************** *** 182,190 **** term = tp->t_termios; if (com == TIOCLSET) ! tp->t_flags = (ttcompatgetflags(tp)&0xffff) | *(int *)data<<16; else { ! tp->t_flags = ttcompatgetflags(tp); if (com == TIOCLBIS) tp->t_flags |= *(int *)data<<16; else --- 182,191 ---- term = tp->t_termios; if (com == TIOCLSET) ! tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; else { ! tp->t_flags = ! (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); if (com == TIOCLBIS) tp->t_flags |= *(int *)data<<16; else *************** *** 194,200 **** return (ttioctl(tp, TIOCSETA, &term, flag)); } case TIOCLGET: ! *(int *)data = ttcompatgetflags(tp)>>16; if (ttydebug) printf("CLGET: returning %x\n", *(int *)data); break; --- 195,203 ---- return (ttioctl(tp, TIOCSETA, &term, flag)); } case TIOCLGET: ! tp->t_flags = ! (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); ! *(int *)data = tp->t_flags>>16; if (ttydebug) printf("CLGET: returning %x\n", *(int *)data); break; *************** *** 233,253 **** flags |= TANDEM; if (iflag&ICRNL || oflag&ONLCR) flags |= CRMOD; ! if (cflag&PARENB) { ! if (iflag&INPCK) { if (cflag&PARODD) flags |= ODDP; else flags |= EVENP; - } else - flags |= EVENP | ODDP; } - if ((cflag&CSIZE) == CS8 && !(iflag&ISTRIP)) - flags |= PASS8; if ((lflag&ICANON) == 0) { /* fudge */ ! if (oflag&OPOST || iflag&ISTRIP || iflag&IXON || lflag&ISIG || lflag&IEXTEN || (cflag&PARENB) && (cflag&CSIZE) != CS8) flags |= CBREAK; else flags |= RAW; --- 236,256 ---- flags |= TANDEM; if (iflag&ICRNL || oflag&ONLCR) flags |= CRMOD; ! if ((cflag&CSIZE) == CS8) { ! flags |= PASS8; ! if (iflag&ISTRIP) ! flags |= ANYP; ! } ! else if (iflag&INPCK || cflag&PARENB) { if (cflag&PARODD) flags |= ODDP; else flags |= EVENP; } if ((lflag&ICANON) == 0) { /* fudge */ ! if (oflag&OPOST || iflag&ISTRIP || iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB || iflag&INPCK || (cflag&CSIZE) != CS8) flags |= CBREAK; else flags |= RAW; *************** *** 311,327 **** else lflag &= ~ECHO; - if (flags&(RAW|LITOUT|PASS8)) { cflag &= ~(CSIZE|PARENB); cflag |= CS8; ! if ((flags&(RAW|PASS8)) == 0) iflag |= ISTRIP; else iflag &= ~ISTRIP; } else { - cflag &= ~CSIZE; cflag |= CS7; ! if (flags&(ODDP|EVENP)) cflag |= PARENB; iflag |= ISTRIP; } --- 314,329 ---- else lflag &= ~ECHO; cflag &= ~(CSIZE|PARENB); + if (flags&(RAW|LITOUT|PASS8)) { cflag |= CS8; ! if (!(flags&(RAW|PASS8)) || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) iflag |= ISTRIP; else iflag &= ~ISTRIP; } else { cflag |= CS7; ! if ((flags&(EVENP|ODDP)) && (flags&ANYP) != ANYP) cflag |= PARENB; iflag |= ISTRIP; } *************** *** 377,396 **** lflag &= ~IXANY; lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); - if (flags&(LITOUT|PASS8)) { - iflag &= ~ISTRIP; cflag &= ~(CSIZE|PARENB); cflag |= CS8; ! if (flags&LITOUT) oflag &= ~OPOST; ! if ((flags&(PASS8|RAW)) == 0) iflag |= ISTRIP; } else if ((flags&RAW) == 0) { - cflag &= ~CSIZE; cflag |= CS7; ! if (flags&(ODDP|EVENP)) cflag |= PARENB; ! oflag |= OPOST; } t->c_iflag = iflag; t->c_oflag = oflag; --- 379,400 ---- lflag &= ~IXANY; lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); cflag &= ~(CSIZE|PARENB); + if (flags&(LITOUT|PASS8)) { cflag |= CS8; ! if (flags&(LITOUT|RAW)) oflag &= ~OPOST; ! else ! oflag |= OPOST; ! if (!(flags&(RAW|PASS8)) || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) iflag |= ISTRIP; + else + iflag &= ~ISTRIP; } else if ((flags&RAW) == 0) { cflag |= CS7; ! if ((flags&(EVENP|ODDP)) && (flags&ANYP) != ANYP) cflag |= PARENB; ! oflag |= ISTRIP|OPOST; } t->c_iflag = iflag; t->c_oflag = oflag; -- In-This-Life: Andrew A. Chernov | "Hay mas dicha, mas contento Internet: ache@astral.msk.su | "Que adorar una hermosura Organization: The RELCOM Corp., | "Brujuleada entre los lejos Moscow, Russia | "De lo imposible?!" (Calderon)