Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does gnu readline require me to hit control c twice?

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
like image 760
archgoon Avatar asked Dec 23 '11 19:12

archgoon


People also ask

What is GNU readline in Linux?

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.

How do read-line commands work?

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.

What functionality does the readline library provide?

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.

What are the basic constructs allowed in the readline init file?

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.


1 Answers

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.

like image 110
ehird Avatar answered Oct 21 '22 13:10

ehird