2012-04-26 9 views
6

¿Hay algo así como System.Posix en Windows?cómo manejar la señal en las ventanas con haskell?

Quiero que el código siguiente se ejecute en Windows, ¿debería cambiarlo?

import IO 
import Control.Exception hiding (catch) 
import Control.Concurrent 
import Network 
import System.Posix ---cannot be run on windows. 

main = withSocketsDo (installHandler sigPIPE Ignore Nothing >> main') 
    --so the signal handler cannot be used 

main' = listenOn (PortNumber 9900) >>= acceptConnections 

acceptConnections sock = do 
     putStrLn "trying to accept" -- debug msg 
     [email protected](h,host,port) <- accept sock 
     print conn -- debug msg 
     forkIO $ catch (talk conn `finally` hClose h) (\e -> print e) 
     acceptConnections sock 

talk [email protected](h,_,_) = hGetLine h >>= hPutStrLn h >> hFlush h >> talk conn 

por ejemplo, si quiero el programa para dejar de fumar cuando ctrl + c, debo agregar un controlador para SIGINT, por lo que en C++, escribir algo de código como este:

void callback(int sig) 
{ 
    // printf("catch\n"); 
} 
... 
signal(SIGINT,callback); 

Pero Don ¿No sabe cómo hacer esto en Haskell, use FFI?

Respuesta

4
import Foreign 
import Foreign.C.Types 

type Handler = CInt->IO() 
foreign import ccall "wrapper" 
    genHandler:: (Handler) -> IO (FunPtr Handler) 

foreign import ccall safe "signal.h signal" 
     install:: CInt->FunPtr Handler->IO CInt 
main=do 
     s<-genHandler (\x->putStrLn $ "catch "++(show x)) 
     res<- install 2 s 
     putStrLn $ show res 
     s<-getLine 

el código anterior es lo que quiero hacer, simplemente importar la función signal, con una devolución de llamada Haskell.

3

No soy un experto en Windows, por lo que no sé lo que tendrá que hacer para ignorar cualquier evento que esté ignorando aquí. Probablemente quiera hojear la documentación Win32 para la versión que tenga instalada. Sin embargo, sé un poco sobre el sistema de compilación y cómo obtener una de las dos versiones de una función para compilar. Por lo que la estrategia se verá así:

  1. Hacer dos directorios, y unix-srcWin32-src (o algunos nombres similares).
  2. En cada directorio, poner un módulo de OSCompat (o algún nombre similar) que contiene algo como esto:

    -- unix-src/OSCompat.hs 
    module OSCompat where 
    import System.Posix 
    ignorePipe = installHandler sigPIPE Ignore Nothing 
    
    -- Win32-src/OSCompat.hs 
    module OSCompat where 
    import System.Win32 
    ignorePipe = -- ??? 
    
  3. En el archivo de project.cabal, poner algo como lo siguiente en su executable bloque:

    if os(windows) 
        build-depends: Win32 
        hs-source-dirs: Win32-src 
    else 
        build-depends: unix 
        hs-source-dirs: unix-src 
    
  4. Cambiar el módulo de nivel superior para tener este aspecto:

    import OSCompat 
    main = withSocketsDo (ignorePipe >> main') 
    
1

No creo que pueda hacer algo como eso en Windows. Windows no es compatible con Posix, por lo que no admite señales en toda su extensión, p. es does not support enviando señales a otros procesos. También la cantidad de señales disponibles is pretty limited.

Si lo entendí correctamente, está ignorando SIGPIPE para evitar que su programa salga si su salida fue canalizada a otro proceso y luego ese proceso finaliza, ¿no? Lo siento, no sé cómo hacer esto en Windows (y de hecho, a menudo no se ven los programas que se comunican a través de un simple conducto en Windows). Si su manejo de señal está conectado con tomas de corriente, this puede ayudar.

Cuestiones relacionadas