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: Fri, 29 Apr 2016 19:53:53 -0700
User-agent: Mutt/1.6.0 (2016-04-01)

Hi Chet,

Thank you for the advice. I think it would just be good to update the
callback interface example in Readline to have this code, so that we
can see how it is done in context. I think it would be good to have
some short example programs for both the basic 'readline()' interface
and for the callback interface, which

1. handle SIGWINCH correctly
2. handle SIGINT in the same way as Bash, by clearing the line

Do you have any idea when you'll have time to finalize these?

I still have a lot of confusion, for instance I noticed a recent
message on this list where you say:

> This is probably the result of the same signal handling issues as with
> SIGWINCH that we discussed a little more than a year ago.  Readline
> catches the signal, sets a flag, and, when it's safe, resends it to the
> calling application.  It expects that if the calling application catches
> SIGINT, it will take care of cleaning up the readline state.  Sometimes
> applications don't want to kill the current line on SIGINT.

As I understand it, if the application ignores SIGINT with SIG_IGN,
then Readline will ignore it too. But if the application traps SIGINT,
then Readline will catch it and pass it on to the application. When
Readline next gets control it will call rl_free_line_state(), which
deletes the undo list, clears the message area, and cancels any
keyboard macros. You said "Sometimes applications don't want to kill
the current line on SIGINT" but (1) do you know of any examples? (2)
Why would such an application want Readline to delete the undo list,
clear the message area, and cancel any keyboard macros, if it is not
going to clear the line? I think application writers expect the line
to be cleared, for example see:

http://stackoverflow.com/questions/16828378/readline-get-a-new-prompt-on-sigint

Now, in the above Stackoverflow discussion, the poster is using the
basic 'readline()' interfac. He solves the problem by using a
'siglongjmp' to get out of the SIGINT handler. Apparently user
"jancheta" thinks that by using 'siglongjmp' instead of 'longjmp', the
code will be safe from race conditions: "But because the longjmp would
be in a signal handler, you need to use sigsetjmp/siglongjmp". I don't
understand how this could be - if the signal arrives in the middle of
a malloc(), then won't we still be corrupting some global state?

(Please let me know if I'm mistaken about this. Does glibc block
SIGINT around functions like malloc()?)

So apparently in addition to the isearch-SIGINT bug which affects the
callback interface (creating a dangerous situation which causes
undesired lines to be entered at the prompt!) there is also a problem
in that users of the basic readline() interface don't even know how to
safely achieve the familiar behavior of clearing a line on ^C.

If you want every user to duplicate Readline's SIGWINCH handler, I
think that's far from ideal, but I can survive. What we need more
urgently is working examples to standardize the usage of this library,
so that people can create patches to their code to get the same
behavior as Bash. Preferably the examples should work with all recent
releases of Readline, which as I understand may require some #ifdef's
in the callback interface usage. Is this doable?

Thank you,

Frederick

On Thu, Apr 28, 2016 at 03:36:43PM -0400, Chet Ramey wrote:
> On 4/26/16 2:54 PM, address@hidden wrote:
> 
> > 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.
> 
> It's always been present.
> 
> You can fix your problem in readline-6.3 and earlier by making your code
> look like this:
> 
>     if(sigsetjmp(env, 1)) {
>         rl_free_line_state ();
>         rl_cleanup_after_signal ();
> 
> RL_UNSETSTATE(RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_VIMOTION|RL_STATE_NUMERICARG|RL_STATE_MULTIKEY);
>       rl_done = 1;
>         rl_callback_handler_remove ();
>         printf("\n");
>     }
> 
> If you want a little more control, you can replace rl_done = 1 with
> 
> rl_line_buffer[rl_point = rl_end = rl_mark = 0] = 0;
> 
> That part clears out the line buffer.  The call to UNSETSTATE cleans up the
> readline state it uses to keep track of where it is between calls to
> rl_callback_read_char().  Without that, readline's state tells it it's
> still in the middle of the incremental search.
> 
> #ifdef to taste if some of the RL_STATE values aren't defined in the
> readline version you're interested in.
> 
> Bash is not a good example to look at for this code, since it doesn't use
> the callback interface.
> 
> 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/
> 



reply via email to

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