6

WindowsにSystem.Posixのようなものはありますか?

以下のコードを Windows で実行したいのですが、変更する必要がありますか?

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
        conn@(h,host,port) <- accept sock
        print conn -- debug msg
        forkIO $ catch (talk conn `finally` hClose h) (\e -> print e)
        acceptConnections sock

talk conn@(h,_,_) = hGetLine h >>= hPutStrLn h >> hFlush h >> talk conn

たとえば、ctrl+c でプログラムを終了させたい場合は、SIGINT のハンドラを追加する必要があるため、C++ では次のようなコードを記述します。

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

しかし、haskell でこれを行う方法がわかりません。FFI を使用しますか?

4

4 に答える 4

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

上記のコードは私がやりたいことですsignal。haskell コールバックを使用して関数をインポートするだけです。

于 2012-05-06T17:10:35.913 に答える
3

私は Windows の専門家ではないので、ここで無視しているイベントを無視するために何をする必要があるかわかりません。インストールしたバージョンに関係なく、 Win32のドキュメントを調べてみるとよいでしょう。ただし、ビルド システムと、ビルドする関数の 2 つのバージョンのうちの 1 つを取得する方法については少し知っています。したがって、戦略は次のようになります。

  1. 2 つのディレクトリunix-srcWin32-src(または類似の名前) を作成します。
  2. 各ディレクトリに、次のOSCompatようなモジュール (または類似の名前) を配置します。

    -- 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. ファイルのブロックproject.cabalに次のようなものを入れます。executable

    if os(windows)
        build-depends: Win32
        hs-source-dirs: Win32-src
    else
        build-depends: unix
        hs-source-dirs: unix-src
    
  4. トップレベル モジュールを次のように変更します。

    import OSCompat
    main = withSocketsDo (ignorePipe >> main')
    
于 2012-04-26T17:10:02.040 に答える
1

Windowsでそのようなことができるとは思いません。Windows は Posix 互換ではないため、シグナルを完全にはサポートしていません。たとえば、他のプロセスへのシグナルの送信をサポートしていません。また、利用可能な信号の数はかなり限られています。

私が正しく理解していれば、出力が別のプロセスにパイプされてそのプロセスが終了した場合に、プログラムが終了するのを防ぐために SIGPIPE を無視していますね。申し訳ありませんが、Windows でこれを行う方法がわかりません (実際、Windows で単純なパイプを介して通信するプログラムを目にすることはあまりありません)。シグナル処理がソケットに接続されている場合、これが役立つ場合があります。

于 2012-04-26T17:48:51.333 に答える