bug-apl
[Top][All Lists]
Advanced

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

Re: [Bug-apl] Another attention signal issue


From: Juergen Sauermann
Subject: Re: [Bug-apl] Another attention signal issue
Date: Tue, 22 Jul 2014 21:04:34 +0200
User-agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130330 Thunderbird/17.0.5

Hi David,

thank you very much. I read the paragraph below several times. Unfortunately
the behavior of readline is somewhat different. The problem seemed to be that
signal handling is "too transparent" in that it ignores settings made in the signal
handler.

But I am on the way towards a solution. The first ingredient was Blakes recommendation
to bind ^C. That was correct, except that it didn't work. It worked for ^A, ^B, etc but
not for ^C. The missing piece was to entirely hide ^C's special role from readline
before calling readline(). After that ^C could be bound like any other ^something.

I am currently running a number of tests with this and I am hoping that I can commit
the solution tomorrow. That should include your ^C comments and also Blake's printout
issues.

/// Jürgen


On 07/22/2014 08:03 PM, David Lamkins wrote:
J'uergen,

I noticed this paragraph in the readline documentation:

"   Readline contains an internal signal handler that is installed for a
number of signals (`SIGINT', `SIGQUIT', `SIGTERM', `SIGALRM',
`SIGTSTP', `SIGTTIN', and `SIGTTOU').  When one of these signals is
received, the signal handler will reset the terminal attributes to
those that were in effect before `readline()' was called, reset the
signal handling to what it was before `readline()' was called, and
resend the signal to the calling application.  If and when the calling
application's signal handler returns, Readline will reinitialize the
terminal and continue to accept input.  When a `SIGINT' is received,
the Readline signal handler performs some additional work, which will
cause any partially-entered line to be aborted (see the description of
`rl_free_line_state()' below)."

The way I read this, readline() should be transparent w.r.t. ^C. Readline resignals your app, then resets *itself* when control returns from your app's signal handler.

I believe that it's a mistake (or at best, needless) to call rl_delete_text() from Input::got_control_C(), but that's not the crux of the problem.

The real problem seems to be that readline() isn't seeing rl_done. In the context of the above-quoted paragraph, though, this may be explained by: " If and when the calling application's signal handler returns, Readline will reinitialize the terminal and continue to accept input". My best guess is that the reinitialization also affects other state in readline and clobbers the signal handler's having set rl_done.

That's my best working hyphothesis at this point.

I can envision a couple ways to deal with this:

1. Build some additional scaffolding using setjmp() and longjmp(). The idea is that a longjmp() from the handler would return *after* the readline() call. Note the need to call rl_cleanup_after_signal() in this case.

2. Look for a readline hook that gets called after the reinitialization that's supposedly done after return from the signal handler. Consider rl_startup_hook and rl_pre_input_hook. The idea is that the hook function would test the value of attention_raised (and interrupt_raised) and set rl_done.

I'd start with (2). The thought of setjmp()/longjmp() in a C++ program makes me itch... ;)

If you don't get to this today, I may have some time tonight to experiment with case (2).




On Tue, Jul 22, 2014 at 7:36 AM, Juergen Sauermann <address@hidden> wrote:
Hi Blake,

I tried, but it did not work.

The deeper I go into readline the more weird it gets.

If I do nothing then I get the first ^C delivered as signal but not subsequent ones.
I would have preferred if two ^Cs (i.e. INTERRUPT rather than ATTENTION) would
stop printouts, but readline delivers only one.

I also tried binding to ^C; interestingly I can bind to any other key except ^C. The
bind to ^C succeeds (returns no error) but the function bound to it is not
called. For other keys this works.

/// Jürgen



On 07/21/2014 08:12 PM, Blake McBride wrote:
Does this help?

This may be related to the cooked/uncooked/rare terminal modes; ^C does not always send a signal. It seems likely that readline uncooks the terminal, and thus any signals caused by keyboard input must be due to logic within readline itself; it seems plausible that it might only trigger a SIGINT on two sequential ^Cs (especially since for many programs that utilise readline such as shells and REPLs, the program exiting on a single ^C would be very annoying!).

You might be able to change this behaviour by using the readline API to rebind ^C to some of your own code that triggers a SIGINT. I haven't used readline from Haskell, just from C, so I'm not sure exactly how you'd go about this, but the binding seems rich enough to achieve it.



Blake McBride

www.arahant.com
Cell:    615-394-6760
Office:  615-376-5500
Fax:     615-377-6006









--
"Far out in the uncharted backwaters of the unfashionable end of the Western Spiral arm of the Galaxy lies a small unregarded yellow sun. Orbiting this at a distance of roughly ninety-eight million miles is an utterly insignificant little blue-green planet whose ape-descended life forms are so amazingly primitive that they still think programming in Java is a pretty neat idea."

 -- With apologies to Douglas Adams, who I like to think would have appreciated this.


http://soundcloud.com/davidlamkins
http://reverbnation.com/lamkins
http://reverbnation.com/lcw
http://lamkins-guitar.com/
http://lamkins.net/
http://successful-lisp.com/


reply via email to

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