2011-12-23 6 views
6

通常、Control-Cはsigintをプログラムに送り、捕捉されていなければ殺します。 gnureadlineライブラリはsigintのハンドラをインストールします。しかし、これらのハンドラをhaskellで無効にしても、プログラムを強制終了するためにControl-Cを2回押す必要があります。どうしたの?なぜgnuのreadlineはコントロールcを2回押す必要がありますか?

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が2つの連続した '^ C 'に対してのみSIGTERMを引き起こす可能性があります。 – ehird

+0

ああ、面白いです。私は端末モードについては知らなかった。私はreadlineがそれを使って何かをしているかどうかを調べます。ありがとうございました。 – archgoon

+0

私はそれを少し答えに拡張しました:) – ehird

答えて

8

これはcooked/uncooked/rare端末モードに関連している可能性があります。 ^Cは必ずしも信号を送信しません。 readlineがターミナルを隠している可能性が高いので、キーボード入力によって引き起こされるシグナルは、readline自体のロジックに起因するものでなければなりません。 (特にシェルやREPLなどのreadlineを利用する多くのプログラムでは、1つの^Cで終了するプログラムは非常に厄介なものになります)。

この動作を変更するには、readline APIを使用して、^CをSIGINTをトリガーするコードに再バインドします。私はハスケルからのreadlineをCのものから使用していないので、あなたはこれについてどうやってどうやって行くのかは分かりませんが、the bindingは十分に豊かに見えます。

関連する問題