2011-12-23 28 views
6

通常情况下,Control-C向程序发送一个sigint,如果它没有被捕获,则会终止它。 gnureadline库将安装sigint的处理程序。但是,即使在haskell中禁用这些处理程序时,我仍然需要敲两次Control-C来杀死一个程序。这是怎么回事?为什么gnu readline要求我两次打控制c?

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 
+2

这可能与煮熟/未煮熟/稀有终端模式有关; '^ C'并不总是发送信号。这可能是readline只在两个连续的'^ C'上产生一个SIGTERM。 – ehird 2011-12-23 19:47:14

+0

哦,有趣。我不知道有关终端模式。我会检查一下readline是否做了一些事情。谢谢。 – archgoon 2011-12-23 19:49:34

+0

我已将它稍微扩展为答案:) – ehird 2011-12-23 19:59:25

回答

8

这可能与cooked/uncooked/rare终端模式有关; ^C并不总是发送信号。 readline可能会终止终端,因此由键盘输入引起的任何信号都必须归因于readline本身内的逻辑;似乎可能的是,它可能只触发两个连续的^C s上的SIGINT(特别是对于许多利用readline的程序,例如shell和REPL,单个^C上的程序会非常烦人!)。

您可能可以通过使用readline API将^C重新绑定到触发SIGINT的某些自己的代码来更改此行为。我没有使用Haskell的readline,仅仅是来自C,所以我不确定你会怎么做,但是the binding似乎足够实现它。