Thread View: comp.bugs.sys5
1 messages
1 total messages
Started by Guy Harris
Mon, 08 Apr 1991 22:36
Bug in S5R4 handling of VLNEXT when ICANON not set
Author: Guy Harris
Date: Mon, 08 Apr 1991 22:36
Date: Mon, 08 Apr 1991 22:36
168 lines
5231 bytes
5231 bytes
The SunOS 4.x "ldterm" streams module - and, according to a person I
asked at Sun, the S5R4 version, derived from the SunOS version - doesn't
correctly handle the "literal-next" character when ICANON isn't set; it
does cause the character typed after it to be treated as ordinary input
(rather than, say, an interrupt/quit/suspend character), but the VLNEXT
character itself appears as input.
The fix is to the routine "do_noncanon_input()", or the moral equivalent
in the S5R4 "ldterm"; here's a patch to the SunOS 4.1 version - S5R4's
mileage may differ. The bug has been reported to AT&T, but if you want
to fix it before they do....
*** /home/unix_src/sunos/sunos.4.1/src/sys/os/tty_ldterm.c Sun Nov 25 13:37:31 1990
--- ./tty_ldterm.c Wed Mar 27 18:21:14 1991
***************
*** 1860,1913 ****
{
queue_t *wrq = WR(q);
int ebsize;
! register mblk_t *bp, *prevbp;
! mblk_t *savebp;
! register unsigned char *rptr;
for (bp = mp, prevbp = NULL; bp != NULL;
! prevbp = bp, bp = bp->b_cont) {
! while (bp->b_rptr == bp->b_wptr) {
/*
! * Zero-length block. Throw it away.
*/
! if (prevbp == NULL)
! mp = bp->b_cont;
! else
! prevbp->b_cont = bp->b_cont;
! savebp = bp;
! bp = bp->b_cont;
! savebp->b_cont = NULL;
! freeb(savebp);
! if (bp == NULL)
! return; /* entire message gone */
! }
! if (tp->t_modes.c_lflag & (ECHO|ECHONL)) {
! /*
! * Echo the data in this message.
! */
! if (tp->t_modes.c_lflag & ECHO) {
! ebsize = bp->b_wptr - bp->b_rptr;
! if (ebsize > EBSIZE)
! ebsize = EBSIZE;
! rptr = bp->b_rptr;
! while (rptr < bp->b_wptr)
! (void) echo_char(*rptr++, wrq,
! ebsize, tp);
! } else {
/*
! * Echo NL, even though ECHO is not
! * set.
*/
! rptr = bp->b_rptr;
! while (rptr < bp->b_wptr) {
! if (*rptr++ == '\n')
output_echo_char('\n',
wrq, 1, tp);
}
}
}
}
! putnext(q, mp);
/*
* Send whatever we echoed downstream.
--- 1860,1956 ----
{
queue_t *wrq = WR(q);
int ebsize;
! register mblk_t *bp, *prevbp, *nextbp;
! register unsigned char *rptr, *wptr;
! register unsigned char c;
for (bp = mp, prevbp = NULL; bp != NULL;
! prevbp = bp, bp = nextbp) {
! if (tp->t_modes.c_lflag & (ECHO|ECHONL|IEXTEN)) {
/*
! * Either we must echo the characters, or we must
! * echo NL, or we must check for VLNEXT.
! * Process characters one at a time.
*/
! ebsize = bp->b_wptr - bp->b_rptr;
! if (ebsize > EBSIZE)
! ebsize = EBSIZE;
! rptr = bp->b_rptr;
! wptr = bp->b_rptr;
! while (rptr < bp->b_wptr) {
! c = *rptr++;
/*
! * If this character is the literal next
! * character, echo it as '^' and backspace
! * over it if echoing is enabled, indicate
! * that the next character is to be treated
! * literally, and remove the LNEXT from the
! * input stream.
! *
! * If the *previous* character was the
! * literal next character, don't check
! * whether this is a literal next or not.
*/
! if ((tp->t_modes.c_lflag & IEXTEN)
! && !(tp->t_state & TS_SLNCH)
! && c != VDISABLE
! && c == tp->t_modes.c_cc[VLNEXT]) {
! if (tp->t_modes.c_lflag & ECHO)
! output_echo_string(
! (unsigned char *)"^\b",
! 2, wrq, ebsize, tp);
! tp->t_state |= TS_SLNCH;
! continue; /* and ignore it */
! }
!
! /*
! * Not a "literal next" character, so
! * it should show up as input.
! * If it was literal-nexted, turn off the
! * literal-next flag.
! */
! tp->t_state &= ~TS_SLNCH;
! *wptr++ = c;
! if (tp->t_modes.c_lflag & ECHO) {
! /*
! * Echo the character.
! */
! (void) echo_char(c, wrq, ebsize, tp);
! } else if (tp->t_modes.c_lflag & ECHONL) {
! /*
! * Echo NL, even though ECHO is not
! * set.
! */
! if (c == '\n')
output_echo_char('\n',
wrq, 1, tp);
}
}
+ bp->b_wptr = wptr;
+ } else {
+ /*
+ * If there are any characters in this buffer,
+ * and the first of them was literal-nexted,
+ * turn off the literal-next flag.
+ */
+ if (bp->b_rptr != bp->b_wptr)
+ tp->t_state &= ~TS_SLNCH;
}
+ nextbp = bp->b_cont; /* next block */
+ if (bp->b_rptr == bp->b_wptr) {
+ /*
+ * Zero-length block. Throw it away.
+ */
+ if (prevbp == NULL)
+ mp = nextbp;
+ else
+ prevbp->b_cont = nextbp;
+ bp->b_cont = NULL;
+ freeb(bp);
+ }
}
! if (mp != NULL)
! putnext(q, mp);
/*
* Send whatever we echoed downstream.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads