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

5

聚会迟到了,但我写了一个可以提供帮助的库。它允许在 Windows 和 Linux 上进行信号处理。它可用于 hackage: https ://hackage.haskell.org/package/signal

于 2015-09-02T08:47:03.117 回答
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文档中查找您安装的任何版本。但是,我确实对构建系统以及如何获取要构建的函数的两个版本之一有所了解。所以策略将如下所示:

  1. 创建两个目录,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 回答