Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><em>Control-C handling does not work with <code>catch</code></em>: may be related to <a href="http://hackage.haskell.org/trac/ghc/ticket/2301">GHC #2301: Proper handling of SIGINT/SIGQUIT</a></p> <p>Here is a working testcase, with the <code>evaluator</code> removed:</p> <pre><code>module Main where import Prelude hiding (catch) import Control.Exception ( SomeException(..), AsyncException(..) , catch, handle, throw) import Control.Monad (forever) import System.IO repl :: IO () repl = forever $ (do putStr "&gt;&gt;&gt; " &gt;&gt; hFlush stdout out &lt;- getLine if null out then return () else putStrLn out) `catch` onUserInterrupt onUserInterrupt UserInterrupt = putStrLn "\nUserInterruption" onUserInterrupt e = throw e main = do handle onAbort repl putStrLn "Exiting..." onAbort e = do let x = show (e :: SomeException) putStrLn $ "\nAborted: " ++ x </code></pre> <p>On Linux, Control-Z is not caught as Sjoerd mentioned. Perhaps you are on Windows, where Control-Z is used for EOF. We can signal EOF on Linux with Control-D, which replicates the behavior you saw:</p> <pre><code>&gt;&gt;&gt; ^D Aborted: &lt;stdin&gt;: hGetLine: end of file Exiting... </code></pre> <p>EOF is handled by your <code>handle/onAbort</code> function, and Control-C is handled by <code>catch/onUserInterrupt</code>. The issue here is that your <code>repl</code> function will only catch the first Control-C -- the testcase can be simplified by removing the <code>handle/onAbort</code> function. As noted above, that Control-C handling does not work with <code>catch</code> may be related to <a href="http://hackage.haskell.org/trac/ghc/ticket/2301">GHC #2301: Proper handling of SIGINT/SIGQUIT</a>.</p> <p>The following version instead uses the Posix API to install a persistent signal handler for Control-C:</p> <pre><code>module Main where import Prelude hiding (catch) import Control.Exception ( SomeException(..), AsyncException(..) , catch, handle, throw) import Control.Monad (forever) import System.IO import System.Posix.Signals repl :: IO () repl = forever $ do putStr "&gt;&gt;&gt; " &gt;&gt; hFlush stdout out &lt;- getLine if null out then return () else putStrLn out reportSignal :: IO () reportSignal = putStrLn "\nkeyboardSignal" main = do _ &lt;- installHandler keyboardSignal (Catch reportSignal) Nothing handle onAbort repl putStrLn "Exiting..." onAbort e = do let x = show (e :: SomeException) putStrLn $ "\nAborted: " ++ x </code></pre> <p>which can handle Control-Cs being pressed multiple times:</p> <pre><code>&gt;&gt;&gt; ^C keyboardSignal &gt;&gt;&gt; ^C keyboardSignal &gt;&gt;&gt; ^C keyboardSignal </code></pre> <p>If not using the Posix API, installing a persistent signal handler on Windows requires re-raising the exception each time it is caught, as described in <a href="http://suacommunity.com/dictionary/signals.php">http://suacommunity.com/dictionary/signals.php</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload