Normally, Control-C sends a sigint to a program, and kills it if it's not caught. The gnureadline library will install handlers for sigint. However, even when disabling those handlers in haskell, I still need to hit Control-C twice to kill a program. What's going on?
import System.Console.Readline
main = do
setCatchSignals False
mainLoop
mainLoop = do
maybeLine <- readline ">"
case maybeLine of
Nothing -> putStrLn ":("
Just line -> do
putStr line
putStr " catch:"
catch <- getCatchSignals
putStrLn $ show $ catch
mainLoop
GNU Readline. It allows users to move the text cursor, search the command history, control a kill ring (a more flexible version of a copy/paste clipboard) and use tab completion on a text terminal. As a cross-platform library, readline allows applications on various systems to exhibit identical line-editing behavior.
Readline commands may be given numeric arguments, which normally act as a repeat count. Sometimes, however, it is the sign of the argument that is significant. Passing a negative argument to a command that acts in the forward direction (e.g., kill-line ) causes that command to act in a backward direction.
Much more functionality is available; see The GNU Readline Library and The GNU History Library for additional information. readline returns the text of the line read. A blank line returns the empty string.
There are only a few basic constructs allowed in the readline init file. Blank lines are ignored. Lines beginning with a # are comments. Lines beginning with a $ indicate conditional constructs. Other lines denote key bindings and variable settings. Each program using this library may add its own commands and bindings.
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 ^C
s (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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With