2011-12-23 10 views
6

Normalmente, Control-C envía un sigint a un programa y lo elimina si no se detecta. La biblioteca gnureadline instalará controladores para sigint. Sin embargo, incluso cuando deshabilite esos manejadores en haskell, aún necesito presionar Control-C dos veces para matar un programa. ¿Que esta pasando?¿Por qué gnu readline requiere que presione el control c dos veces?

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

Esto puede estar relacionado con los modos de terminal cocido/crudo/raro; '^ C' no siempre envía una señal. Podría ser que readline causa un SIGTERM solo en dos '^ C's secuenciales. – ehird

+0

Oh, interesante. No sabía eso sobre los modos de terminal. Comprobaré y veré si readline hace algo con eso. Gracias. – archgoon

+0

Lo he expandido un poco en una respuesta :) – ehird

Respuesta

8

Esto puede estar relacionado con los cooked/uncooked/rare modos de terminales; ^C no siempre envía una señal. Parece probable que readline descocte el terminal y, por lo tanto, cualquier señal causada por la entrada del teclado debe ser debida a la lógica dentro de readline; parece plausible que solo active un SIGINT en dos ^C s secuenciales (especialmente porque para muchos programas que utilizan readline como shells y REPLs, el programa que sale en un solo ^C sería muy molesto).

Es posible que pueda cambiar este comportamiento utilizando la API readline para volver a vincular ^C a algunos de sus propios códigos que desencadenan un SIGINT. No he usado readline de Haskell, solo de C, así que no estoy seguro de cómo hacerlo, pero the binding parece lo suficientemente rico como para lograrlo.

Cuestiones relacionadas