bug-readline
[Top][All Lists]
Advanced

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

Re: [Bug-readline] documentation of signal handling


From: frederik
Subject: Re: [Bug-readline] documentation of signal handling
Date: Tue, 26 Apr 2016 11:54:01 -0700
User-agent: Mutt/1.6.0 (2016-04-01)

Hi Chet,

Thanks for your reply.

> Thanks for the reminder.  The example needs to be updated for SIGWINCH,
> but simply exits -- as most programs do -- on SIGINT.  If you want to
> handle SIGINT, you're already doing it: you already have a functioning
> signal handler.  There are a couple of things you need to add to it to
> make it clean up the readline state if you're not exiting:
> 
> rl_free_line_state ();                /* clean up the line buffer */
> rl_callback_sigcleanup ();    /* dispose of internal readline state */
> 
> Since readline isn't active, you don't need to call rl_cleanup_after_signal().
> 
> That second function is new in readline-7.0; it fixes a bug in previous
> readline versions.

I don't think we'll have the luxury of using readline-7.0 yet in R,
but I'm not sure. I'd like a solution that works for the past few
versions at least.

I have a short example program that I attached. I haven't added
SIGWINCH handling yet. You can see that I use siglongjmp to get out of
the SIGINT handler - a tip I found on stackoverflow - and then I try a
few miscellaneous Readline cleanup functions. I'm trying to get
behavior like Bash - ^C should cancel anything I've entered on a line,
an give me a new prompt. (I notice that GDB has different, somewhat
annoying behavior, of keeping the input line on ^C)

The example that I wrote has a bug which both R and Python suffer
from. The problematic behavior is that when the user hits ^C during a
reverse-isearch, the last isearch proposal is kept as a "hidden" input.

For R, I reported this bug in
<https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16603>.

I'm a bit curious to know if this bug has always been present, or if
it appeared with Readline 6.3 or some other recent version.

Here is an example. I type "test^n^rea^c" and see this:

    $ ./test-callback 2>/dev/null
    rltest$ test
    input line: test
    (failed reverse-i-search)`ea': test
    rltest$

Note that the prompt appears and there is no text following the
prompt. Now, I hit enter and voila:

    $ ./test-callback 2>/dev/null
    rltest$ test
    input line: test
    (failed reverse-i-search)`ea': test
    rltest$ test
    input line: test

The text "test" suddenly appears after the prompt, and is accepted as
an input line. Somewhat dangerous if "test" meant "delete my files"! I
haven't had time to look at the Bash source for the correct way to
interface with Readline in this case. Do you happen to know what the
problem is here?

Thanks,

Frederick

On Tue, Apr 26, 2016 at 10:14:55AM -0400, Chet Ramey wrote:
> On 4/25/16 2:59 PM, address@hidden wrote:
> > Dear Readline people (and Chet Ramey),
> > 
> > I'm trying to help fix some bugs in the R interpreter, involving
> > signals not being received by GNU Readline.
> > 
> > R currently has problems which stem from ignoring SIGWINCH
> > <https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16604>, and
> > failing to correctly reset the Readline state upon receiving SIGINT
> > <https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16603>.
> 
> I believe that this is correct, in that these signals arrive when
> readline is not reading and processing a character, and therefore
> does not have its signal handlers installed.
> 
> > I understand from reading about a similar bug in Python
> > <https://bugs.python.org/issue23735> that the problem may stem from
> > signal handling changes made in Readline 6.3.
> > 
> > According to the Python bug (which quotes Chet), the solution is for
> > the application itself to trap SIGWINCH, and then set a flag to call
> > "rl_resize_terminal()" before the next "select()".
> 
> Yes, something like
> 
> static void
> sighandler (int sig)
> {
>   rl_resize_terminal ();
> }
> 
> (Technically this is unsafe; you should, as you note, set a flag and call
> rl_resize_terminal from your program's main loop if that flag is set.
> But you have the idea.)
> 
> > 
> > However, the need to do this is apparently not yet noted in the
> > Readline documentation, for instance the "Alternate interface example"
> > <http://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC43>
> > seems to lack the extra code for SIGWINCH (and, presumably, SIGINT).
> 
> Thanks for the reminder.  The example needs to be updated for SIGWINCH,
> but simply exits -- as most programs do -- on SIGINT.  If you want to
> handle SIGINT, you're already doing it: you already have a functioning
> signal handler.  There are a couple of things you need to add to it to
> make it clean up the readline state if you're not exiting:
> 
> rl_free_line_state ();                /* clean up the line buffer */
> rl_callback_sigcleanup ();    /* dispose of internal readline state */
> 
> Since readline isn't active, you don't need to call rl_cleanup_after_signal().
> 
> That second function is new in readline-7.0; it fixes a bug in previous
> readline versions.
> 
> > Delving a bit deeper, I'm wondering why it was necessary for Readline
> > to make application writers do all this extra work. For instance, why
> > not go back to installing signal handlers (via "rl_set_signals()") in
> > "rl_callback_handler_install()", and extend the callback interface
> > with a function - e.g. "rl_check_for_signal()" - that queries
> > _rl_caught_signal to see if a signal is pending? 
> 
> This is an interesting approach, but it's years too late, and would not
> have satisfied the requirements being presented at the time: the
> applications already had existing signal handling functions they needed
> to have called when signals arrived.
> 
> Chet
> -- 
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
>                ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, ITS, CWRU    address@hidden    http://cnswww.cns.cwru.edu/~chet/
> 

Attachment: test-callback.c
Description: Text Data


reply via email to

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