dupTo与STDOUT有关的奇怪之处

时间:2015-07-30 06:26:31

标签: haskell operating-system daemon ghc stdio

我正在编写一些代码来守护进程。当然,我希望能够重定向STDOUT。

但是,一旦我切换文件描述符,Haskell的打印函数不会向我的文件或控制台写入任何内容,但在新更新的fdWrite文件描述符上调用stdOutput可以按预期工作

作为旁注,如果我在daemonize'之前使用任何Haskell的打印功能(print,hPutStr等),一切都按预期工作(stdout写入我的文件)

如何解决此问题?

以下是我如何守护:

daemonize' :: Maybe String -> Maybe String -> IO () -> IO () 
daemonize' outpath errpath program = do
  forkProcess $ do
    createSession
    forkProcess $ do
      redirectIO outpath errpath
      blockSignal sigHUP
      program
    exitImmediately ExitSuccess
  exitImmediately ExitSuccess

blockSignal :: Signal -> IO () 
blockSignal sig = installHandler sig Ignore Nothing >> (return ())

这是重定向STDOUT的代码:

redirectIO :: Maybe String -> Maybe String -> IO ()
redirectIO outpath errpath = do
  dnull <- openFd "/dev/null" ReadWrite Nothing defaultFileFlags
  closeFd stdInput >> dupTo dnull stdInput
  case outpath of
    Nothing -> closeFd stdOutput >> dupTo dnull stdOutput >> return ()
    Just out -> do
      fdWrite stdOutput "HELLO"
      fd <- openFd out ReadWrite Nothing defaultFileFlags
      setFdOption fd AppendOnWrite True
      dupTo fd stdOutput
      closeFd fd
  case errpath of
    Nothing -> closeFd stdError >> dupTo dnull stdError >> return ()
    Just err -> do
      fd <- openFd err ReadWrite Nothing defaultFileFlags
      setFdOption fd AppendOnWrite True
      dupTo fd stdError
      closeFd fd

1 个答案:

答案 0 :(得分:2)

虽然我没有解决我的问题,但stdout未正确重定向的这些问题仅在我的程序如上所述守护程序时出现;在程序未被守护程序时重定向stdout按预期工作,写入我指定的文件。

更新7.31.15:

事实证明,stdout句柄没有正确缓冲。在我stdoutstderr Handle停止缓冲之后,一切都按预期工作。

hSetBuffering stdout NoBuffering
hSetBuffering stderr NoBuffering -- for consistency
hSetBuffering stdin  NoBuffering -- for consistency