Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!spool.mu.edu!howland.reston.ans.net!torn!nott!bnrgate!bnr.co.uk!uknet!pipex!sunic!news.funet.fi!fuug!kiae!bitcom!kiae!relcom!newsserv From: "Andrew A. Chernov, Black Mage" <ache@astral.msk.su> Newsgroups: comp.os.386bsd.bugs Subject: Revised patch to tty_compat.c: fix bug with cs8 and many other Date: Mon, 10 May 93 19:06:02 +0400 Distribution: world Organization: Ha-olahm Yetzirah Message-ID: <rMQzcxhuB0@astral.msk.su> Sender: news-service@newcom.kiae.su Reply-To: ache@astral.msk.su Lines: 227 Hi. 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. +This patch version have fixed false INPCK set, +fix come from Guido van Rooij <guido@gvr.win.tue.nl>, +thanx to him. Advantages: 1) Can preserve CS8 mode 2) Can preserve ISTRIP mode in CS8 mode 3) Can preserve parity modes and INPCK 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. *** tty_compat.c.orig Thu Nov 26 22:38:06 1992 --- tty_compat.c Mon May 10 18:46:42 1993 *************** ttcompat(tp, com, data, flag) *** 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; } *************** ttcompat(tp, com, data, flag) *** 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; --- 194,202 ---- 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; *************** ttcompatgetflags(tp) *** 233,239 **** flags |= TANDEM; if (iflag&ICRNL || oflag&ONLCR) flags |= CRMOD; ! if (cflag&PARENB) { if (iflag&INPCK) { if (cflag&PARODD) flags |= ODDP; --- 235,246 ---- flags |= TANDEM; if (iflag&ICRNL || oflag&ONLCR) flags |= CRMOD; ! if ((cflag&CSIZE) == CS8) { ! flags |= PASS8; ! if (iflag&ISTRIP) ! flags |= ANYP; ! } ! else if (cflag&PARENB) { if (iflag&INPCK) { if (cflag&PARODD) flags |= ODDP; *************** ttcompatgetflags(tp) *** 242,259 **** } else flags |= EVENP | ODDP; } ! if (!(oflag&OPOST) && (!(cflag&PARENB) || (cflag&CSIZE) == CS8)) ! flags |= LITOUT; ! 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; } if (oflag&OXTABS) flags |= XTABS; if (lflag&ECHOE) --- 249,264 ---- } else flags |= EVENP | ODDP; } ! 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; } + if (!(flags&RAW) && !(oflag&OPOST) && (!(cflag&PARENB) || (cflag&CSIZE) == CS8)) + flags |= LITOUT; if (oflag&OXTABS) flags |= XTABS; if (lflag&ECHOE) *************** ttcompatsetflags(tp, t) *** 283,289 **** register long cflag = t->c_cflag; if (flags & RAW) { ! iflag &= IXOFF; oflag &= ~OPOST; lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); } else { --- 288,294 ---- register long cflag = t->c_cflag; if (flags & RAW) { ! iflag &= (IXOFF|IXANY); oflag &= ~OPOST; lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); } else { *************** ttcompatsetflags(tp, t) *** 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; } --- 316,331 ---- 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; } *************** ttcompatsetlflags(tp, t) *** 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; --- 381,402 ---- 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 FIDOnet: 2:5020/23.34 | "Brujuleada entre los lejos RELCOM Development Team, Moscow, Russia | "De lo imposible?!" (Calderon)