1-----------------------------------------------------------------------------
2-- |
3-- Module      :  Plugins.PipeReader
4-- Copyright   :  (c) Andrea Rossato
5-- License     :  BSD-style (see LICENSE)
6--
7-- Maintainer  :  Jose A. Ortega Ruiz <jao@gnu.org>
8-- Stability   :  unstable
9-- Portability :  unportable
10--
11-- A plugin for reading from named pipes
12--
13-----------------------------------------------------------------------------
14
15module Xmobar.Plugins.PipeReader(PipeReader(..)) where
16
17import System.IO
18import Xmobar.Run.Exec(Exec(..))
19import Xmobar.System.Environment(expandEnv)
20import System.Posix.Files
21import Control.Concurrent(threadDelay)
22import Control.Exception
23import Control.Monad(forever, unless)
24
25data PipeReader = PipeReader String String
26    deriving (Read, Show)
27
28instance Exec PipeReader where
29    alias (PipeReader _ a)    = a
30    start (PipeReader p _) cb = do
31        (def, pipe) <- split ':' <$> expandEnv p
32        unless (null def) (cb def)
33        checkPipe pipe
34        h <- openFile pipe ReadWriteMode
35        forever (hGetLine h >>= cb)
36      where
37        split c xs | c `elem` xs = let (pre, post) = span (c /=) xs
38                                   in (pre, dropWhile (c ==) post)
39                   | otherwise   = ([], xs)
40
41checkPipe :: FilePath -> IO ()
42checkPipe file =
43    handle (\(SomeException _) -> waitForPipe) $ do
44        status <- getFileStatus file
45        unless (isNamedPipe status) waitForPipe
46    where waitForPipe = threadDelay 1000000 >> checkPipe file
47