2011-12-23 41 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似乎足夠實現它。