2012-04-26 12 views
6

WindowsにSystem.Posixのようなものがありますか?haskellでウィンドウ上の信号を処理する方法は?

以下のコードをウィンドウで実行したいのですが、変更する必要がありますか?例えば

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 

私はプログラムが時にCtrl + Cを終了したい場合は、Cの++で、このようないくつかのコードを書くので、私は、SIGINTのハンドラを追加する必要があります。

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

しかし、私はドンこれを行う方法を知っているのではなく、FFIを使うのですか?

答えて

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 

上記のコードは、私はHaskellのコールバックで、ちょうどsignal機能をインポート、行いたいものです。

3

私はWindowsのエキスパートではないので、ここで無視しているイベントは無視する必要があります。インストールしたバージョンについては、Win32のドキュメントを参照してください。しかし、ビルドシステムと、関数の2つのバージョンのうちの1つをビルドする方法について少しは分かっています。したがって、戦略は次のようになります。

  • unix-srcWin32-src(または類似の名前)という2つのディレクトリを作成します。各ディレクトリで
  • 、このような何か含むモジュールOSCompat(またはいくつかの類似した名前)入れ:

    if os(windows) 
        build-depends: Win32 
        hs-source-dirs: Win32-src 
    else 
        build-depends: unix 
        hs-source-dirs: unix-src 
    
    :あなたのproject.cabalファイルで

    -- 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 = -- ??? 
    
  • は、あなたのexecutableブロックに次のようなものを置きます

  • トップレベルモジュールを次のように変更してください。

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

    私はあなたがWindows上でそういうことをすることはできないと思います。 WindowsはPosixと互換性がないため、シグナルを完全にサポートしていません。信号を他のプロセスに送る。利用可能な信号数もis pretty limitedです。

    私が正しく理解していれば、出力が別のプロセスにパイプされ、プロセスが終了した場合、プログラムが終了しないようにSIGPIPEを無視していますか?申し訳ありませんが、私はWindowsでこれを行う方法がわかりません(実際には、Windows上で簡単なパイプで通信するプログラムはほとんどありません)。 信号処理がソケットに接続されている場合は、thisが役立ちます。

    4

    私はパーティーに遅れましたが、私は助けることができる図書館を書いていました。 WindowsとLinuxの両方で信号処理が可能です。ハックで利用できます: https://hackage.haskell.org/package/signal

    関連する問題