Source-Changes-D archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: CVS commit: src/lib/libcurses
Hi,
The following commit breaks my /usr/bin/vi.
When /usr/bin/vi exits, /usr/bin/vi hangs.
I must kill it with kill(1) command.
I reverted src/lib/libcurses/refresh.c to r1.131 locally
and /usr/bin/vi works fine again.
Could you take a look at my problem?
If you need more information, I can rebuild libcurse with
r1.132 of src/lib/libcurses/refresh.c and collect information.
Thank you.
"Brett Lymn" <blymn%netbsd.org@localhost> writes:
> Module Name: src
> Committed By: blymn
> Date: Mon Jun 29 06:06:10 UTC 2026
>
> Modified Files:
> src/lib/libcurses: refresh.c
>
> Log Message:
> Part of fix for PR lib/58282
>
> Redo the logic for erasing lines when we have the capability, it was
> broken and caused blanks to be written when clearing the screen instead
> which caused thrashing and large outputs.
>
>
> To generate a diff of this commit:
> cvs rdiff -u -r1.131 -r1.132 src/lib/libcurses/refresh.c
>
> Please note that diffs are not public domain; they are subject to the
> copyright notices on the relevant files.
>
> Modified files:
>
> Index: src/lib/libcurses/refresh.c
> diff -u src/lib/libcurses/refresh.c:1.131 src/lib/libcurses/refresh.c:1.132
> --- src/lib/libcurses/refresh.c:1.131 Wed Apr 1 20:32:56 2026
> +++ src/lib/libcurses/refresh.c Mon Jun 29 06:06:10 2026
> @@ -1,4 +1,4 @@
> -/* $NetBSD: refresh.c,v 1.131 2026/04/01 20:32:56 hgutch Exp $ */
> +/* $NetBSD: refresh.c,v 1.132 2026/06/29 06:06:10 blymn Exp $ */
>
> /*
> * Copyright (c) 1981, 1993, 1994
> @@ -34,7 +34,7 @@
> #if 0
> static char sccsid[] = "@(#)refresh.c 8.7 (Berkeley) 8/13/94";
> #else
> -__RCSID("$NetBSD: refresh.c,v 1.131 2026/04/01 20:32:56 hgutch Exp $");
> +__RCSID("$NetBSD: refresh.c,v 1.132 2026/06/29 06:06:10 blymn Exp $");
> #endif
> #endif /* not lint */
>
> @@ -228,6 +228,10 @@ _wnoutrefresh(WINDOW *win, int begy, int
> screen->__virtscr->flags &= ~__LEAVEOK;
> screen->__virtscr->flags |= dwin->flags;
>
> + /* copy the background char and attributes from win to __virtscr */
> + screen->__virtscr->bch = win->bch;
> + screen->__virtscr->battr = win->battr;
> +
> if ((dwin->flags & __ISDERWIN) != 0)
> endy = begy + maxy;
> else
> @@ -328,6 +332,7 @@ _wnoutrefresh(WINDOW *win, int begy, int
> CA_CONTINUATION;
> }
> #endif /* HAVE_WCHAR */
> +
> if (win->flags & __ISDERWIN) {
> dwlp->line[dx_off].ch =
> wlp->line[wx].ch;
> @@ -372,6 +377,7 @@ _wnoutrefresh(WINDOW *win, int begy, int
> }
> }
> #endif /* HAVE_WCHAR */
> +
> __CTRACE(__CTRACE_REFRESH, " = '%s', 0x%x\n",
> unctrl(vlp->line[x_off].ch),
> vlp->line[x_off].attr);
> @@ -402,7 +408,7 @@ _wnoutrefresh(WINDOW *win, int begy, int
> *wlp->firstchp, *wlp->lastchp);
> if (win->flags & __ISDERWIN) {
> __CTRACE(__CTRACE_REFRESH,
> - "derwin: fistch = %d, lastch = %d\n",
> + "derwin: firstch = %d, lastch = %d\n",
> *dwlp->firstchp, *dwlp->lastchp);
> }
> #endif
> @@ -436,15 +442,14 @@ _wnoutrefresh(WINDOW *win, int begy, int
> }
>
> __CTRACE(__CTRACE_REFRESH,
> - "__virtscr: firstch = %d, lastch = %d\n",
> - *vlp->firstchp, *vlp->lastchp);
> + "__virtscr: firstch = %d, lastch = %d, flags 0x%x\n",
> + *vlp->firstchp, *vlp->lastchp, vlp->flags);
> /*
> - * Unset change pointers only if a window and we
> - * are not forcing a redraw. A pad can be displayed
> - * again without any of the contents changing.
> + * Unset change pointers only if a window
> + * A pad can be displayed again without any
> + * of the contents changing.
> */
> - if (!((win->flags & __ISPAD)) ||
> - ((wlp->flags & __ISFORCED) == __ISFORCED))
> + if (!(win->flags & __ISPAD))
> {
> /* Set change pointers on "win". */
> if (*wlp->firstchp >= win->ch_off)
> @@ -570,9 +575,9 @@ doupdate(void)
>
> if (!_cursesi_screen->curwin) {
> for (wy = 0; wy < win->maxy; wy++) {
> - wlp = win->alines[wy];
> + wlp = curscr->alines[wy];
> if (wlp->flags & __ISDIRTY)
> - wlp->hash = __hash_line(wlp->line, win->maxx);
> + wlp->hash = __hash_line(wlp->line, curscr->maxx);
> }
> }
>
> @@ -606,15 +611,30 @@ doupdate(void)
> _cursesi_screen->curwin);
> __CTRACE(__CTRACE_REFRESH, "doupdate: \tfirstch\tlastch\n");
>
> + /* curscr may have been cleared, rehash the dirty lines */
> + for (wy = 0; wy < win->maxy; wy++) {
> + wlp = curscr->alines[wy];
> + if (wlp->flags & __ISDIRTY)
> + wlp->hash = __hash_line(wlp->line, curscr->maxx);
> + }
> +
> + /* and the same with virtscr... */
> + for (wy = 0; wy < __virtscr->maxy; wy++) {
> + wlp = __virtscr->alines[wy];
> + if (wlp->flags & __ISDIRTY)
> + wlp->hash = __hash_line(wlp->line, __virtscr->maxx);
> + }
> +
> if (!_cursesi_screen->curwin) {
> /*
> * Invoke quickch() only if more than a quarter of the lines
> - * in the window are dirty.
> + * in the window are dirty and we didn't just clear.
> */
> for (wy = 0, dnum = 0; wy < win->maxy; wy++)
> if (win->alines[wy]->flags & __ISDIRTY)
> dnum++;
> - if (!__noqch && dnum > (int) win->maxy / 4)
> + if ((!__noqch) && (was_cleared == 0)
> + && (dnum > (int) win->maxy / 4))
> quickch();
> }
>
> @@ -1145,25 +1165,23 @@ makech(int wy)
> {
> WINDOW *win;
> static __LDATA blank;
> - __LDATA *nsp, *csp, *cp, *cep, *fsp;
> + __LDATA *nsp, *csp, *cp, *fsp;
> __LINE *wlp;
> int nlsp; /* offset to first space at eol. */
> - size_t mlsp;
> int lch, wx, owx, chw;
> const char *ce;
> - attr_t lspc; /* Last space colour */
> attr_t battr; /* background attribute bits */
> attr_t attr_mask; /* attributes mask */
>
> #ifdef __GNUC__
> - nlsp = lspc = 0; /* XXX gcc -Wuninitialized */
> + nlsp = 0; /* XXX gcc -Wuninitialized */
> #endif
> if (_cursesi_screen->curwin)
> win = curscr;
> else
> win = __virtscr;
>
> - blank.ch = win->bch;
> + blank.ch = (wchar_t) btowc((int) ' ');
> blank.attr = win->battr;
> blank.cflags = CA_BACKGROUND;
> #ifdef HAVE_WCHAR
> @@ -1202,6 +1220,8 @@ makech(int wy)
>
> /* Is the cursor still on the end of the last line? */
> if (wy > 0 && curscr->alines[wy - 1]->flags & __ISPASTEOL) {
> + /* XXX this looks wrong - bad things will happen if ly
> + is at maxy */
> domvcur(win, _cursesi_screen->ly, _cursesi_screen->lx,
> _cursesi_screen->ly + 1, 0);
> _cursesi_screen->ly++;
> @@ -1221,16 +1241,6 @@ makech(int wy)
> if (lch >= (int) win->maxx)
> lch = win->maxx - 1;
>
> - if (_cursesi_screen->curwin) {
> - csp = ␣
> - __CTRACE(__CTRACE_REFRESH, "makech: csp is blank\n");
> - } else {
> - csp = &curscr->alines[wy]->line[wx];
> - __CTRACE(__CTRACE_REFRESH,
> - "makech: csp is on curscr:(%d,%d)\n", wy, wx);
> - }
> -
> -
> while (win->alines[wy]->line[wx].cflags & CA_CONTINUATION) {
> wx--;
> if (wx <= 0) {
> @@ -1239,6 +1249,15 @@ makech(int wy)
> }
> }
>
> + if (_cursesi_screen->curwin) {
> + csp = ␣
> + __CTRACE(__CTRACE_REFRESH, "makech: csp is blank\n");
> + } else {
> + csp = &curscr->alines[wy]->line[wx];
> + __CTRACE(__CTRACE_REFRESH,
> + "makech: csp is on virtscr:(%d,%d)\n", wy, wx);
> + }
> +
> nsp = fsp = &win->alines[wy]->line[wx];
>
> #ifdef DEBUG
> @@ -1257,25 +1276,34 @@ makech(int wy)
> */
> if (clr_eol && !_cursesi_screen->curwin && (!(__using_color)
> || (__using_color && back_color_erase))) {
> +
> + if (__using_color && back_color_erase) {
> + assume_default_colors(
> + _cursesi_screen->colour_pairs[PAIR_NUMBER(win->battr)].fore,
> + _cursesi_screen->colour_pairs[PAIR_NUMBER(win->battr)].back);
> + }
> +
> nlsp = win->maxx - 1;
> cp = &win->alines[wy]->line[win->maxx - 1];
> #ifdef HAVE_WCHAR
> - while ((_cursesi_celleq(cp, &blank) == 1) &&
> -#else
> - while (cp->ch == blank.ch &&
> -#endif /* HAVE_WCHAR */
> - ((cp->attr & attr_mask) == battr)) {
> -#ifdef HAVE_WCHAR
> + while (((_cursesi_celleq(cp, &blank) == 1) &&
> + (cp->attr & attr_mask) == battr)) {
> nlsp -= cp->wcols;
> cp -= cp->wcols;
> +
> + if (nlsp <= 0)
> + break;
> + }
> #else
> + while (cp->ch == blank.ch &&
> + ((cp->attr & attr_mask) == battr)) {
> nlsp--;
> cp--;
> -#endif /* HAVE_WCHAR */
>
> if (nlsp <= 0)
> break;
> }
> +#endif /* HAVE_WCHAR */
>
>
> if (nlsp < 0)
> @@ -1296,11 +1324,12 @@ makech(int wy)
> csp->ch, csp->attr, csp->wcols, win->bch, win->battr,
> win->wcols, csp->nsp);
> #endif
> - if (!(wlp->flags & __ISFORCED) &&
> -#ifdef HAVE_WCHAR
> - ((nsp->cflags & CA_CONTINUATION) != CA_CONTINUATION) &&
> -#endif
> - _cursesi_celleq(nsp, csp))
> +
> + /*
> + * If the update is not being forced then skip over
> + * all the unchanged characters.
> + */
> + if (!(wlp->flags & __ISFORCED) && _cursesi_celleq(nsp, csp))
> {
> if (wx <= lch) {
> while (wx <= lch && _cursesi_celleq(nsp, csp)) {
> @@ -1324,35 +1353,30 @@ makech(int wy)
> domvcur(win, _cursesi_screen->ly, _cursesi_screen->lx, wy, wx);
>
> __CTRACE(__CTRACE_REFRESH, "makech: 1: wx = %d, ly= %d, "
> - "lx = %d, newy = %d, newx = %d, lch = %d\n",
> - wx, _cursesi_screen->ly, _cursesi_screen->lx, wy, wx, lch);
> + "lx = %d, newy = %d, newx = %d, lch = %d, nlsp = %d\n",
> + wx, _cursesi_screen->ly, _cursesi_screen->lx, wy, wx, lch,
> + nlsp);
> +
> _cursesi_screen->ly = wy;
> _cursesi_screen->lx = wx;
> owx = wx;
> - while (wx <= lch &&
> - ((wlp->flags & __ISFORCED) || !_cursesi_celleq(nsp, csp)))
> +
> + if (wx <= lch &&
> + ((wlp->flags & __ISFORCED) || !_cursesi_celleq(nsp, csp)))
> {
> - if ((ce != NULL) && (wx >= nlsp) &&
> - (nsp->ch == blank.ch) &&
> - (__do_color_init == 1 || nsp->attr == blank.attr))
> + /*
> + * Consider clearing the line, if:
> + * - we have a clear to eol capability
> + * - current x pos is past last non blank char
> + * - the win char is blank
> + * - either we are initing colour or the attributes
> + * match.
> + * - Or the character is marked background
> + */
> + if ((clr_eol != NULL) && (wx >= nlsp) &&
> + ((nsp->ch == blank.ch) &&
> + (__do_color_init == 1 || nsp->attr == blank.attr)))
> {
> - /* Check for clear to end-of-line. */
> - cep = &win->alines[wy]->line[win->maxx - 1];
> - while (cep->ch == blank.ch && cep->attr == battr)
> - if (cep-- <= csp)
> - break;
> -
> - mlsp = &win->alines[wy]->line[win->maxx - 1]
> - - win->alines[wy]->line
> - - win->begx * __LDATASIZE;
> -
> - __CTRACE(__CTRACE_REFRESH,
> - "makech: nlsp = %d, max = %zu, strlen(ce) = %zu\n",
> - nlsp, mlsp, strlen(ce));
> - __CTRACE(__CTRACE_REFRESH,
> - "makech: line = %p, cep = %p, begx = %u\n",
> - win->alines[wy]->line, cep, win->begx);
> -
> /*
> * work out how to clear the line. If:
> * - clear len is greater than clear_to_eol len
> @@ -1365,17 +1389,15 @@ makech(int wy)
> * then emit the ce string.
> */
> if (((wy == win->maxy - 1) ||
> - ((mlsp - wx) > strlen(ce))) &&
> + (((win->maxx - 1) - wx) > strlen(ce))) &&
> ((__using_color && back_color_erase) ||
> (! __using_color))) {
> if (wlp->line[wx].attr & win->screen->nca) {
> __unsetattr(0);
> } else if (__using_color &&
> - ((__do_color_init == 1) ||
> - ((lspc & __COLOR) !=
> - (curscr->wattr & __COLOR)))) {
> - __set_color(curscr, lspc &
> - __COLOR);
> + (__do_color_init == 1)) {
> + __set_color(curscr,
> + curscr->wattr & __COLOR);
> }
> tputs(ce, 0, __cputchar);
> _cursesi_screen->lx = wx + win->begx;
> @@ -1395,6 +1417,13 @@ makech(int wy)
> #endif /* HAVE_WCHAR */
> assert(csp != &blank);
> }
> +
> + /* We cleared the line, update the
> + * the hash
> + */
> + win->alines[wy]->hash = __hash_line(
> + win->alines[wy]->line, win->maxx);
> +
> return OK;
> }
> }
> @@ -1408,7 +1437,7 @@ makech(int wy)
> #endif /* HAVE_WCHAR */
> owx = wx;
> if (wx + chw >= (win->maxx) &&
> - wy == win->maxy - 1 && !_cursesi_screen->curwin)
> + wy >= (win->maxy - 1) && !_cursesi_screen->curwin)
> {
> if (win->flags & __ENDLINE)
> __unsetattr(1);
> @@ -1522,8 +1551,6 @@ domvcur(WINDOW *win, int oy, int ox, int
> __CTRACE(__CTRACE_REFRESH, "domvcur: (%d,%d)=>(%d,%d) win %p\n",
> oy, ox, ny, nx, win );
>
> - __unsetattr(1);
> -
> /* Don't move the cursor unless we need to. */
> if (oy == ny && ox == nx) {
> /* Check EOL. */
> @@ -1531,6 +1558,8 @@ domvcur(WINDOW *win, int oy, int ox, int
> return;
> }
>
> + __unsetattr(1);
> +
> /* Clear EOL flags. */
> win->alines[oy]->flags &= ~__ISPASTEOL;
> win->alines[ny]->flags &= ~__ISPASTEOL;
> @@ -1637,13 +1666,12 @@ quickch(void)
> for (bsize = bot - top; bsize >= THRESH; bsize--) {
> for (startw = top; startw <= bot - bsize; startw++)
> for (starts = top; starts <= bot - bsize; starts++) {
> -/* for (curw = startw, curs = starts;
> + for (curw = startw, curs = starts;
> curs < starts + bsize; curw++, curs++)
> if (__virtscr->alines[curw]->hash !=
> - curscr->alines[curs]->hash)
> - break;
> - if (curs != starts + bsize)
> - continue;*/
> + curscr->alines[curs]->hash) {
> + if (curs == starts + bsize)
> + goto done;
> for (curw = startw, curs = starts;
> curs < starts + bsize; curw++, curs++)
> if (!lineeq(__virtscr->alines[curw]->line,
> @@ -1651,6 +1679,7 @@ quickch(void)
> (size_t) __virtscr->maxx)) {
> found = 1;
> break;
> + }
> }
> if ((curs == starts + bsize) && (found == 1)) {
> goto done;
> @@ -1683,7 +1712,7 @@ done:
> __CTRACE(__CTRACE_REFRESH, "quickch: n = %d\n", n);
> for (i = 0; i < curscr->maxy; i++) {
> __CTRACE(__CTRACE_REFRESH, "C: %d:", i);
> - __CTRACE(__CTRACE_REFRESH, " 0x%x \n", curscr->alines[i]->hash);
> + __CTRACE(__CTRACE_REFRESH, " hash: 0x%x \n", curscr->alines[i]->hash);
> for (j = 0; j < curscr->maxx; j++)
> __CTRACE(__CTRACE_REFRESH, "%c",
> curscr->alines[i]->line[j].ch);
> @@ -1694,7 +1723,7 @@ done:
> curscr->alines[i]->line[j].attr);
> __CTRACE(__CTRACE_REFRESH, "\n");
> __CTRACE(__CTRACE_REFRESH, "W: %d:", i);
> - __CTRACE(__CTRACE_REFRESH, " 0x%x \n",
> + __CTRACE(__CTRACE_REFRESH, " hash: 0x%x \n",
> __virtscr->alines[i]->hash);
> __CTRACE(__CTRACE_REFRESH, " 0x%x ",
> __virtscr->alines[i]->flags);
> @@ -2075,9 +2104,6 @@ __unsetattr(int checkms)
> tputs(exit_alt_charset_mode, 0, __cputchar);
> curscr->wattr &= ~__ALTCHARSET;
> }
> - /* Don't leave the screen with colour set (check against ms). */
> - if (__using_color && isms)
> - __unset_color(curscr);
> }
>
> /* compare two line segments */
>
--
Ryo ONODERA // ryo%tetera.org@localhost
PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB FD1B F404 27FA C7D1 15F3
Home |
Main Index |
Thread Index |
Old Index