[net.bugs.4bsd] Another bug with 4.2 BSD Curses

laman@sdcsvax.UUCP (07/17/84)

Thanks to Mike Lilley, an obscure 4.2 BSD curses bug has been found.
This bug is caused when nl() is called AFTER initscr() [ I know that that is
all the time. ].  But if CRMOD is off (Not very common...) initscr()
sets NONL to be true (1).  Now the nl() function is executed.  The terminal
modes are changed turning on CRMOD, but NONL is NOT reset to reflect
this change (i.e. NONL should now be false (0))).  In a nut shell, the problem
is that nl() changes the tty modes and the boolean, NONL, is NOT changed to
affect this.  The situation that causes this to show up is not very common.

The following program will give output telling you what you should get on
your screen.  My fix follows the program.

NOTE: This program must be run with the CRMOD bit OFF!  The following shell
command sequence will do the trick.

	stty nl ; a.out ; stty -nl

/* Beginning of program.  Cut here.......... */
#include	<curses.h>

main() {
	initscr();
	nl();
	/*
	 * If you have the bug, the second line will not be at the beginning
	 * of the second line... It will start underneath the end of the
	 * first line.
	 */
	mvaddstr(0, 0,
	    "Beginning of line #1\nThis should be at beginning of line #2!!!");
	move(LINES-1, 0);
	refresh();
	nonl();
	endwin();
}
/* End of Program.  Cut here....... */

The fix:  The fix is quite simple.  Change the nl() and nonl() macros in
	  curses.h from:

#define nl()	 (_tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty))
#define nonl()	 (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, stty(_tty_ch, &_tty))

	  to:

#define nl()	 (_tty.sg_flags |= CRMOD,_pfast = _rawmode,NONL = 0,stty(_tty_ch, &_tty))
#define nonl()	 (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, NONL = 1,stty(_tty_ch, &_tty))


		Mike Laman, NCR Torrey Pines
		UUCP: {ucbvax,philabs,sdccsu3,sdcsla}!sdcsvax!laman