bug-ncurses
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Fix 'flash' for Bash


From: Thomas Dickey
Subject: Re: [PATCH] Fix 'flash' for Bash
Date: Sat, 14 Sep 2024 19:10:28 -0400

On Wed, Sep 11, 2024 at 06:53:05PM +0200, Harm te Hennepe wrote:
> At the moment the time-delay of 100ms for 'flash' (as specified in my
> terminfo entry) doesn't work correctly with Bash/Readline (`set
> bell-style visible`). It makes use of `tputs`.
> 
> A strace shows that the time-delay isn't happening at the right moment:
> ```
> strace: Process 3872344 attached
> read(0, "\10", 1)                       = 1
> clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},
> 0x7ffca150b340) = 0
> write(2, "\33[?5h\33[?5l", 10)          = 10
> ```
> 
> In v6_2_20201128 a `fflush(stdout)` was added for applications using
> low-level calls [1]
> 
> Unfortunately, Bash uses stderr /and/ sets it to buffered. I suggest
> fflush'ing stderr as well. With the patch below applied, the flash
> works as expected again:
> ```
> strace: Process 3876152 attached
> read(0, "\10", 1)                       = 1
> write(2, "\33[?5h", 5)                  = 5
> clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=100000000},
> 0x7ffdf8a19110) = 0
> write(2, "\33[?5l", 5)                  = 5
> ```
> 
> I guess a better solution would be to have a `tputs2`, which also
> accepts a callback for flushing the stream.
> But, as this has already been broken since at least 2006 (I started a
> VM with an Ubuntu 6.06 live cd), and probably never worked, I think
> the incentive for implementing that would be low.

agreed.  The answer to anything like that is to use terminfo.
 
> On a sidenote, as `SP_PARM->_ofd > 0`, shouldn't [2] be 
> `fflush(SP_PARM->_ofd)`?

SP_PARM->_ofd is an int, while fflush() needs a FILE*

SP_PARM->_ofp is related, but that's oversimplified.
That's set via newterm, which calls setupterm -- for non-termcap applications,
and in that route sets _ofd, while initializing I/O.

bash is using the termcap interface, which doesn't do anything useful for
I/O initialization, so ncurses has to assume (from post-5.9 changes) that
the termcap functions are using stdout.

        20120825
                + change output buffering scheme, using buffer maintained by 
ncurses
                  rather than stdio, to avoid problems with SIGTSTP handling 
(report
                  by Brian Bloniarz).

But that's only an assumption, since tputs passes a function pointer,
rather than a stream pointer:

       int tputs(const char *str, int affcnt, int (*putc)(int));

So... ncurses doesn't really know that bash has decided to pass everything
through a buffered stderr.  I see that's using _rl_output_character_function,
which in turn uses _rl_out_stream, etc., and _that_ has used stderr since
the current repository was created in 1996 from bash 1.14.7 -- perhaps
there was a changelog note explaining why that was done, but I don't see
it in the current sources (nor in the 1.14.7 sources). I suspect no one
can provide that information.

But flushing stderr is harmless, since it will have no effect on virtually
all other users.

I did this for stdout:

        20201128
                + add another fflush(stdout) in _nc_flush() to handle 
time-delays in
                  the middle of strings such as flash when the application uses
                  low-level calls rather than curses (cf: 20161217).

termcap applications won't set SP_PARM (I'm reminded of some really bizarre
code that pretends to be a termcap application, but we can ignore that at
the moment), so bash would be using the second fflush(stderr).  The first
might help with that other application :-)
 
> [1] 
> https://github.com/ThomasDickey/ncurses-snapshots/blob/21c551ae1d2aa970ceae868fffd80922f6263565/NEWS#L53
> [2] 
> https://github.com/ThomasDickey/ncurses-snapshots/blob/a480458efb0662531287f0c75116c0e91fe235cb/ncurses/tinfo/lib_tputs.c#L154
> 
> diff --git a/ncurses/tinfo/lib_tputs.c b/ncurses/tinfo/lib_tputs.c
> index f834532..10ccb3f 100644
> --- a/ncurses/tinfo/lib_tputs.c
> +++ b/ncurses/tinfo/lib_tputs.c
> @@ -150,12 +150,14 @@ NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_DCL0)
>                 }
>             }
>         } else if (SP_PARM->out_buffer == 0) {
> -           TR(TRACE_CHARPUT, ("flushing stdout"));
> +           TR(TRACE_CHARPUT, ("flushing stdout/stderr"));
>             fflush(stdout);
> +           fflush(stderr);
>         }
>      } else {
> -       TR(TRACE_CHARPUT, ("flushing stdout"));
> +       TR(TRACE_CHARPUT, ("flushing stdout/stderr"));
>         fflush(stdout);
> +       fflush(stderr);
>      }
>      if (SP_PARM != 0)
>         SP_PARM->out_inuse = 0;
> 
> 

-- 
Thomas E. Dickey <dickey@invisible-island.net>
https://invisible-island.net

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]