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
