Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!bunyip.cc.uq.oz.au!harbinger.cc.monash.edu.au!yeshua.marcam.com!news.kei.com!eff!news.umbc.edu!haven.umd.edu!umd5.umd.edu!mark From: mark@roissy.umd.edu (Mark Sienkiewicz) Newsgroups: comp.os.386bsd.bugs Subject: REAL Fix: more/vi on serial port Date: 12 Apr 1994 15:00:37 GMT Organization: Zeno, IPST, University of Maryland Lines: 122 Message-ID: <2oed2l$jrq@hecate.umd.edu> NNTP-Posting-Host: roissy.umd.edu A while back I posted a hack that fixes the "more/vi screws up on serial port" bug. It was a quick and dirty fix that I wrote while I went looking for the right fix. It turns out that it wasn't that hard to find. The problem is in sys/kern/tty_compat.c, where it is trying to take old style ioctls() [ V6, V7, 4.1, 4.2 ] and make termios style parameters out of them. It would work if you enable parity checking, but if you tried to use no parity, it would set your serial port to have only * seven * bits in a byte. This is a problem because a 7 bit data path is not really transmitting 1 start bit, 7 data bits, and 1 stop bit. It is transmitting 1 start, 8 data, and 1 stop, then ignoring the most significant bit because the data path may have used it for parity. I believe this is the correct fix for two reasons: - it does what I expected it to do (unlike the unfixed version) - it more correctly mimics the behaviour of the older systems, in that those older systems always used 8 bit bytes - I would be pleased to know of *any* example of somebody trying to use a 1 start, 7 data, 1 stop bit configuration. :) Some might argue that it should be fixed in the serial port device driver, but I think that any such fix would break true-posix attempts to *really* use 7 bit bytes. *** tty_compat.c.old Fri Feb 11 10:04:01 1994 --- tty_compat.c Fri Feb 11 10:24:19 1994 *************** *** 333,348 **** 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; } if ((flags&(EVENP|ODDP)) == EVENP) { iflag |= INPCK; cflag &= ~PARODD; } else if ((flags&(EVENP|ODDP)) == ODDP) { iflag |= INPCK; --- 333,358 ---- cflag |= CS8; if (!(flags&(RAW|PASS8)) || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) iflag |= ISTRIP; else iflag &= ~ISTRIP; } else { ! /* ! * if we have parity, we want to set the port to 7 bits + parity ! * but if we have no parity, we do *not* want to set the ! * port to [ start bit, 7 data bits, stop bit ] because this ! * breaks everything (and is not compatible with _anything_). ! * Since V6, Unix systems used 8 data bits, and optionally ! * checked or not checked the parity. ! */ ! if ((flags&(EVENP|ODDP)) && (flags&ANYP) != ANYP) { ! cflag |= CS7 | PARENB; ! iflag |= ISTRIP; ! } else { ! cflag |= CS8; ! } } if ((flags&(EVENP|ODDP)) == EVENP) { iflag |= INPCK; cflag &= ~PARODD; } else if ((flags&(EVENP|ODDP)) == ODDP) { iflag |= INPCK; *************** *** 403,418 **** 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; t->c_lflag = lflag; t->c_cflag = cflag; } --- 413,434 ---- oflag |= OPOST; if (!(flags&(RAW|PASS8)) || (flags&(RAW|PASS8|ANYP)) == (PASS8|ANYP)) iflag |= ISTRIP; else iflag &= ~ISTRIP; } else if ((flags&RAW) == 0) { ! /* ! * see comment in ttcompatsetflags() near CS7 ! */ ! if ((flags&(EVENP|ODDP)) && (flags&ANYP) != ANYP) { ! cflag |= CS7 | PARENB; ! iflag |= ISTRIP; ! } else { ! cflag |= CS8; ! } ! oflag |= OPOST; } t->c_iflag = iflag; t->c_oflag = oflag; t->c_lflag = lflag; t->c_cflag = cflag; }