I just realized that since Readline 6 defers forwarding signals to the client application until it is in normal execution, using `siglongjmp` to clear a line on SIGINT with the basic `readline()` interface, as Bash does, should be safe.
Sorry about that. On Fri, Apr 29, 2016 at 07:53:53PM -0700, [email protected] wrote: > 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, [email protected] 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 [email protected] http://cnswww.cns.cwru.edu/~chet/ > > > _______________________________________________ Bug-readline mailing list [email protected] https://lists.gnu.org/mailman/listinfo/bug-readline
