[net.bugs.4bsd] more leaves terminal in underline mode

stevesu@azure.UUCP (Steve Summit) (01/04/84)

If more notices itself printing underline-backspace-character, it
cleverly puts the terminal in underline mode, if it can, and just
sends "character."  That's great, because you'll get the same
underlining on your non-overstrike crt that you would on a
printing terminal.  The trouble is, more doesn't take the
terminal out of underline mode unless it notices itself printing
a regular character.  If the last character on the screen is
underlined, the "--More--" prompt gets underlined, and if you say
"q", the terminal stays in underline mode.  The same thing
happens when the last character in the file is underlined and
more terminates normally.

The fix is simple:  if the terminal has been put into underline
mode, it must be taken out after a screenfull is printed, and when
more exits.

A diff -c5 follows.  The sccsid line on my copy reads
"@(#)more.c	4.4 (Berkeley) 81/04/23".  This is from a 4.1
system.  The problem remains on 4.2, and the context should be
more or less the same.  If you've got more on your 2.8/2.9
system, you've probably got it, too.

BTW, while looking at the 4.2 source code, I noticed that:

	they'd checked some potentially null pointers before
	dereferencing them, but compared them to 0 instead of
	NULL, and

	they'd REMOVED the "#ifdef v6" around a line that says

	    file->_flag &= ~_IOEOF; /* why doesn't fseek do this ??!!??! */

What gives?

                                         Steve Summit
                                         tektronix!tekmdp!stevesu

$ diff -c5 more.new.c more.c
*** more.new.c	Tue Jan  3 13:39:22 1984
--- more.c	Tue Nov 24 11:43:11 1981
***************
*** 378,389
  ** Print out the contents of the file f, one screenful at a time.
  */
  
  #define STOP -10
  
- int pstate = 0;				/* current terminal UL state (off) */
- 
  screen (f, num_lines)
  register FILE *f;
  register int num_lines;
  {
      register int c;

--- 378,387 -----
  ** Print out the contents of the file f, one screenful at a time.
  */
  
  #define STOP -10
  
  screen (f, num_lines)
  register FILE *f;
  register int num_lines;
  {
      register int c;
***************
*** 421,434
  		putchar('\n');
  	    if (nchars == STOP)
  		break;
  	    num_lines--;
  	}
- 	if (pstate) {
- 	    tputs(ULexit, 1, putch);
- 	    pstate = 0;
- 	}
  	fflush(stdout);
  	if ((c = Getc(f)) == EOF)
  	{
  	    if (clreol)
  		clreos ();

--- 419,428 -----
  		putchar('\n');
  	    if (nchars == STOP)
  		break;
  	    num_lines--;
  	}
  	fflush(stdout);
  	if ((c = Getc(f)) == EOF)
  	{
  	    if (clreol)
  		clreos ();
***************
*** 811,820
  register char *s;

  register int n;
  {
      char c;				/* next ouput character */
      register int state;			/* next output char's UL state */
  
      while (--n >= 0)
  	if (!ul_opt)
  	    putchar (*s++);
  	else {

--- 805,815 -----
  register char *s;
  register int n;
  {
      char c;				/* next ouput character */
      register int state;			/* next output char's UL state */
+     static int pstate = 0;		/* current terminal UL state (off) */
  
      while (--n >= 0)
  	if (!ul_opt)
  	    putchar (*s++);
  	else {
***************
*** 1589,1603
  	stty(2, &otty);
  }
  
  reset_tty ()
  {
-     if (pstate) {
- 	tputs(ULexit, 1, putch);
- 	fflush(stdout);
- 	pstate = 0;
-     }
      otty.sg_flags |= ECHO;
      otty.sg_flags &= ~MBIT;
      stty(2, &otty);
  }
  

--- 1584,1593 -----
  	stty(2, &otty);
  }
  
  reset_tty ()
  {
      otty.sg_flags |= ECHO;
      otty.sg_flags &= ~MBIT;
      stty(2, &otty);
  }