summaryrefslogtreecommitdiff
path: root/Presence/FGConsole.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Presence/FGConsole.hs')
-rw-r--r--Presence/FGConsole.hs67
1 files changed, 67 insertions, 0 deletions
diff --git a/Presence/FGConsole.hs b/Presence/FGConsole.hs
new file mode 100644
index 00000000..03aaebf2
--- /dev/null
+++ b/Presence/FGConsole.hs
@@ -0,0 +1,67 @@
1{-# LANGUAGE ForeignFunctionInterface #-}
2{-# LANGUAGE ScopedTypeVariables #-}
3module FGConsole where
4
5import Data.Word
6import System.Posix.IO
7import System.Posix.Types
8import Control.Concurrent
9-- import GHC.IO.Handle
10import Unsafe.Coerce
11import Control.Exception as E
12-- import Prelude as E
13import Control.Monad
14import Foreign.C
15
16import Logging
17import System.Posix.Signals
18
19-- c_monitorTTY fd = trace "c_monitorTTY" (return ()) -- (trace "WTF" todo)
20
21foreign import ccall "monitorTTY" c_monitorTTY :: Fd -> IO CInt
22foreign import ccall "closeTTY" c_closeTTY :: IO ()
23
24forkTTYMonitor :: (Word8 -> IO ()) -> IO (Maybe (Fd,ThreadId))
25forkTTYMonitor handler = do
26 (rfd,wfd) <- createPipe
27 retvar <- newEmptyMVar
28 thread <- forkIO $ do
29 let cleanup = do
30 trace "quitting monitorTTY thread." (return ())
31 closeFd wfd `E.catch` \(e::IOException) -> return ()
32 closeFd rfd `E.catch` \(e::IOException) -> return ()
33 c_closeTTY
34 -- rh <- fdToHandle rfd
35 didfork <- c_monitorTTY wfd
36 putMVar retvar didfork
37 when (didfork == 0) $ do
38 let monitor =
39 (do
40 threadWaitRead rfd
41 (cs,cnt) <- fdRead rfd 1
42 forM_ cs (handler . unsafeCoerce {- . trace "read byte" -})
43 monitor)
44 `E.catch`
45 \(e :: IOException) -> do
46 err <- getErrno
47 case () of
48 _ | err==eAGAIN -> monitor
49 _ | otherwise -> cleanup
50 `E.catch`
51 \(e :: AsyncException) -> cleanup
52 monitor
53 didfork <- takeMVar retvar
54 if didfork == 0
55 then return $! Just (rfd,thread)
56 else return $! Nothing
57
58killTTYMonitor :: (Fd, ThreadId) -> IO ()
59killTTYMonitor (rfd,thread) = do
60 closeFd rfd
61 yield
62 killThread thread
63 raiseSignal sigUSR1
64 -- threadDelay 1000000
65
66
67-- vim:ft=haskell: