<font class="Apple-style-span" face="arial, helvetica, sans-serif">On Sat, Oct 29, 2011 at 9:36 AM, Donn Cave <span dir="ltr">&lt;<a href="mailto:donn@avvanta.com">donn@avvanta.com</a>&gt;</span> wrote:<br></font><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im"><font class="Apple-style-span" face="arial, helvetica, sans-serif">The SIGINT handler looks like more of a quirk of the RTS, than</font></div>
<font class="Apple-style-span" face="arial, helvetica, sans-serif">
a feature whose behavior you should depend on in great detail.<br></font></blockquote><div><font class="Apple-style-span" face="arial, helvetica, sans-serif"><br></font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">I looked into this some more, and found that it is indeed a quirk of the RTS -- an apparently /intentional/ one.  From <a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Signals">http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Signals</a>:</font></div>
<div><font class="Apple-style-span" face="arial, helvetica, sans-serif"><br></font></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">&quot;<span class="Apple-style-span" style="font-size: 13px; background-color: rgb(255, 255, 255); ">When the interrupt signal is received, the default behaviour of the runtime is to attempt to shut down the Haskell program gracefully. It does this by calling <tt>interruptStgRts()</tt> in <a href="http://hackage.haskell.org/trac/ghc/browser/rts/Schedule.c" style="text-decoration: none; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: rgb(187, 187, 187); ">rts/Schedule.c</a> (see <a class="wiki" href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Scheduler#ShuttingDown" style="text-decoration: none; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: rgb(187, 187, 187); ">Commentary/Rts/Scheduler#ShuttingDown</a>). If a second interrupt signal is received, then we terminate the process immediately; this is just in case the normal shutdown procedure failed or hung for some reason, the user is always able to stop the process with two control-C keystrokes&quot;</span></font></div>
<div><span class="Apple-style-span" style="font-size: 13px; background-color: rgb(255, 255, 255); "><font class="Apple-style-span" face="arial, helvetica, sans-serif"><br></font></span></div><div><font class="Apple-style-span" face="arial, helvetica, sans-serif">While I&#39;m sure someone or ones meant well when designing the RTS to work in this way, I do not agree that this is sensible.  It&#39;s fine for calculation or utility programs that perform one task and exit, but not for interactive programs such as shells, editors, or anything with a command line interface.  </font><span class="Apple-style-span" style="font-family: arial, helvetica, sans-serif; ">IMO, handholding behavior such as this is exactly the sort of thing that risks new Haskell users coming to the conclusion that &quot;Haskell is not intended for real programming projects&quot; -- I know, because I nearly came to this exact conclusion while pulling my hair out trying to figure out what was going on here.  Further complicating the matter is that this feature only exists in POSIX environments, i.e. not on Windows.</span></div>
<div><font class="Apple-style-span" face="arial, helvetica, sans-serif"><br></font></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><font class="Apple-style-span" face="arial, helvetica, sans-serif">
I can use System.Posix.Signals.installHandler to catch &lt;ctrl&gt;C (SIGINT)<br>
in a repeatable way, on MacOS X, so that&#39;s working as it should.  If you<br>
want it to return control to the user interface, that&#39;s going to take<br>
some work - for all I know, there may be some way to hook a signal handler<br>
up with Control.Exception.catch.</font></blockquote><div><br></div><div>Indeed, it&#39;s easy to hook up your own signal handler so that ALL keyboard interrupts have the expected behavior of throwing a UserInterrupt exception -- although I would not have thought to do this before learning that the RTS is &quot;broken&quot; in this regard:</div>
<div><br></div><div><div>import Control.Exception as C</div><div>import Control.Concurrent</div><div>import System.Posix.Signals</div></div><div><br></div><div><div>main = do</div><div>  tid &lt;- myThreadId</div><div>  installHandler keyboardSignal (Catch (throwTo tid UserInterrupt)) Nothing</div>
</div><div>  ... -- rest of program</div><div><br></div><div><br></div><div>Brian</div></div>