2011-12-23 1 views
6

Normalmente, Control-C invia un sigint a un programma e lo uccide se non viene rilevato. La libreria gnureadline installerà i gestori per sigint. Tuttavia, anche disabilitando quei gestori in haskell, devo comunque premere Control-C due volte per uccidere un programma. Cosa sta succedendo?Perchè gnu readline mi richiede di colpire il controllo c due volte?

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

Questo può essere correlato a modalità terminale cotte/non cotte/rare; '^ C' non invia sempre un segnale. Potrebbe essere che readline causi un SIGTERM solo su due 'sequenziali' 'C '. – ehird

+0

Oh, interessante. Non lo sapevo delle modalità terminali. Controllerò e vedrò se readline fa qualcosa con quello. Grazie. – archgoon

+0

L'ho ampliato leggermente in una risposta :) – ehird

risposta

8

Questo può essere correlato alle modalità di terminale cooked/uncooked/rare; ^C non invia sempre un segnale. Sembra probabile che readline prelevi il terminale, e quindi qualsiasi segnale causato dall'input della tastiera deve essere dovuto alla logica all'interno della readline stessa; sembra plausibile che possa attivare un SIGINT solo su due sequenziali ^C s (soprattutto perché per molti programmi che utilizzano readline come shell e REPL, il programma che esce su un singolo ^C sarebbe molto fastidioso!).

Potrebbe essere possibile modificare questo comportamento utilizzando l'API di readline per riassociare ^C a un po 'del proprio codice che attiva un SIGINT. Non ho usato readline da Haskell, solo da C, quindi non sono sicuro di come andresti su questo, ma lo the binding sembra abbastanza ricco per raggiungerlo.