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)