On Thu, Jan 21, 2021 at 11:06:05AM -0700, Todd C. Miller wrote:
> This is a backport of the ncurses 5.9 20120707 patch.
> https://github.com/mirror/ncurses/commit/471bc007361fd4bc8d2fae060c7d5b09828ed541
>
> Previously, getch() would return ERR if SIGWINCH was received but
> the window didn't actually change size. This can happen, for
> example, when the xterm font is changed.
>
> Fixes another canfield issue found by pjanzen@ where changing the
> font causes canfield to exit due to getch() returning an error.
>
> - todd
>
Yes please!, I've also run into this issue on OpenBSD with the "catpoint"
presentation program. I've been meaning to send the exact same backport patch.
The upstream snapshot version of ncurses compiles fine on OpenBSD and I've
managed to link against it statically for testing purposes:
https://github.com/ThomasDickey/ncurses-snapshots/commits/master
Maybe it is worthwhile to adopt the files to the structure in
/usr/src/lib/libcurses ? The current version lags almost 10 years behind and
probably misses more subtle fixes like this.
> Index: lib/libcurses/curs_getch.3
> ===================================================================
> RCS file: /cvs/src/lib/libcurses/curs_getch.3,v
> retrieving revision 1.4
> diff -u -p -u -r1.4 curs_getch.3
> --- lib/libcurses/curs_getch.3 13 Feb 2019 07:18:57 -0000 1.4
> +++ lib/libcurses/curs_getch.3 21 Jan 2021 15:12:58 -0000
> @@ -236,14 +236,14 @@ See \fBresizeterm\fR(3) for more details
> All routines return the integer \fBERR\fR upon failure and an integer value
> other than \fBERR\fR (\fBOK\fR in the case of ungetch()) upon successful
> completion.
> -.RS
> +.RS 3
> .TP 5
> \fBungetch\fP
> -returns an error
> +returns ERR
> if there is no more room in the FIFO.
> -.TP 5
> +.TP
> \fBwgetch\fP
> -returns an error
> +returns ERR
> if the window pointer is null, or
> if its timeout expires without having any data.
> .RE
> Index: lib/libcurses/curses.priv.h
> ===================================================================
> RCS file: /cvs/src/lib/libcurses/curses.priv.h,v
> retrieving revision 1.34
> diff -u -p -u -r1.34 curses.priv.h
> --- lib/libcurses/curses.priv.h 6 Sep 2010 17:26:17 -0000 1.34
> +++ lib/libcurses/curses.priv.h 21 Jan 2021 15:34:57 -0000
> @@ -895,6 +895,7 @@ struct screen {
> */
> #if USE_SIZECHANGE
> int (*_resize)(int,int);
> + int (*_ungetch)(SCREEN *, int);
> #endif
>
> /*
> Index: lib/libcurses/resizeterm.3
> ===================================================================
> RCS file: /cvs/src/lib/libcurses/resizeterm.3,v
> retrieving revision 1.5
> diff -u -p -u -r1.5 resizeterm.3
> --- lib/libcurses/resizeterm.3 12 Jan 2010 23:21:59 -0000 1.5
> +++ lib/libcurses/resizeterm.3 21 Jan 2021 15:13:09 -0000
> @@ -88,8 +88,6 @@ this overrides the library's use of the
> the operating system.
> Thus, even if a SIGWINCH is received,
> no screen size change may be recorded.
> -In that case, no \fBKEY_RESIZE\fP is queued for the next call to \fBgetch\fP;
> -an \fBERR\fP will be returned instead.
> .SH SEE ALSO
> \fBwresize\fR(3).
> .SH AUTHOR
> Index: lib/libcurses/base/lib_set_term.c
> ===================================================================
> RCS file: /cvs/src/lib/libcurses/base/lib_set_term.c,v
> retrieving revision 1.13
> diff -u -p -u -r1.13 lib_set_term.c
> --- lib/libcurses/base/lib_set_term.c 12 Jan 2010 23:22:06 -0000 1.13
> +++ lib/libcurses/base/lib_set_term.c 21 Jan 2021 15:39:59 -0000
> @@ -549,6 +549,7 @@ _nc_setupscreen(int slines GCC_UNUSED,
> #endif
> #if USE_SIZECHANGE
> SP->_resize = resizeterm;
> + SP->_ungetch = _nc_ungetch;
> #endif
>
> newscr->_clear = TRUE;
> Index: lib/libcurses/base/resizeterm.c
> ===================================================================
> RCS file: /cvs/src/lib/libcurses/base/resizeterm.c,v
> retrieving revision 1.3
> diff -u -p -u -r1.3 resizeterm.c
> --- lib/libcurses/base/resizeterm.c 12 Jan 2010 23:22:06 -0000 1.3
> +++ lib/libcurses/base/resizeterm.c 21 Jan 2021 15:40:07 -0000
> @@ -420,7 +420,6 @@ resizeterm(int ToLines, int ToCols)
> result = resize_term(ToLines, ToCols);
>
> #if USE_SIGWINCH
> - _nc_ungetch(SP, KEY_RESIZE); /* so application can know this
> */
> clearok(curscr, TRUE); /* screen contents are unknown */
>
> /* ripped-off lines are a special case: if we did not lengthen
> @@ -451,6 +450,9 @@ resizeterm(int ToLines, int ToCols)
> }
> #endif
> }
> +#if USE_SIGWINCH
> + _nc_ungetch(SP, KEY_RESIZE); /* so application can know this */
> +#endif
> }
>
> returnCode(result);
> Index: lib/libcurses/tinfo/lib_setup.c
> ===================================================================
> RCS file: /cvs/src/lib/libcurses/tinfo/lib_setup.c,v
> retrieving revision 1.12
> diff -u -p -u -r1.12 lib_setup.c
> --- lib/libcurses/tinfo/lib_setup.c 12 Jan 2010 23:22:06 -0000 1.12
> +++ lib/libcurses/tinfo/lib_setup.c 21 Jan 2021 15:39:10 -0000
> @@ -321,8 +321,11 @@ _nc_update_screensize(SCREEN *sp)
> */
> if (sp != 0
> && sp->_resize != 0) {
> - if ((new_lines != old_lines) || (new_cols != old_cols))
> + if ((new_lines != old_lines) || (new_cols != old_cols)) {
> sp->_resize(new_lines, new_cols);
> + } else if (sp->_sig_winch && (sp->_ungetch != 0)) {
> + sp->_ungetch(SP, KEY_RESIZE); /* so application can know this
> */
> + }
> sp->_sig_winch = FALSE;
> }
> }
>
--
Kind regards,
Hiltjo