2011-12-23 20 views
6

Normal olarak, Control-C bir programa bir imza gönderir ve yakalanmadığında onu öldürür. Gnureadline kütüphanesi, sigint için işleyicileri kuracak. Bununla birlikte, bu işleyicileri haskell'de devre dışı bırakırken bile, bir programı öldürmek için Control-C'ye iki kez vurmam gerekiyor. Neler oluyor?Neden gnu readline kontrol c'ye iki kere vurmamı gerektiriyor?

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

Bu, pişmiş/pişmemiş/nadir terminal modları ile ilgili olabilir; '^ C' her zaman bir sinyal göndermez. Bu, bir SIGTERM'in sadece iki ardışık '^ C'de neden olmasına neden olabilir. – ehird

+0

Oh, ilginç. Terminal modları hakkında bir şey bilmiyordum. Okuyucunun bununla bir şey yapıp yapmadığını kontrol edip göreceğim. Teşekkür ederim. – archgoon

+0

Birazcık bir cevaba dönüştürdüm :) – ehird

cevap

8

Bu, cooked/uncooked/rare terminal modları ile ilgili olabilir; ^C, her zaman bir sinyal göndermez. Okunmanın terminali çıkarması olasıdır ve bu nedenle klavye girişinin neden olduğu herhangi bir sinyal, okuma dizisindeki mantıktan dolayı olmalıdır; sadece bir SIGINT'i iki sıralı ^C s'de tetikleyebileceği makul gözükmektedir (özellikle de kabuklar ve REPL'ler gibi bir çok okuma programından dolayı, tek bir ^C'dan çıkan program çok can sıkıcı olacaktır!). Bu davranışı, ^C yeniden kodlamak için readline API kullanarak SIGINT'i tetikleyen kendi kodunuzun bir kısmı için değiştirebilirsiniz. Haskell'den, sadece C'den bir okuma çizgisi kullanmamıştım, bu yüzden bununla ilgili tam olarak nasıl emin olacağınızdan emin değilim, ancak the binding bunu başarmak için yeterince zengin görünüyor.

İlgili konular