summaryrefslogtreecommitdiff
path: root/Presence/FGConsole.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Presence/FGConsole.hs')
-rw-r--r--Presence/FGConsole.hs62
1 files changed, 62 insertions, 0 deletions
diff --git a/Presence/FGConsole.hs b/Presence/FGConsole.hs
new file mode 100644
index 00000000..623fb493
--- /dev/null
+++ b/Presence/FGConsole.hs
@@ -0,0 +1,62 @@
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.Error
15import Foreign.C
16
17import Logging
18import System.Posix.Signals
19
20-- c_monitorTTY fd = trace "c_monitorTTY" (return ()) -- (trace "WTF" todo)
21
22foreign import ccall "monitorTTY" c_monitorTTY :: Fd -> IO ()
23foreign import ccall "closeTTY" c_closeTTY :: IO ()
24
25monitorTTY :: (Word8 -> IO ()) -> IO (Fd,ThreadId)
26monitorTTY handler = do
27 (rfd,wfd) <- createPipe
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 c_monitorTTY wfd
36 let monitor =
37 (do
38 threadWaitRead rfd
39 (cs,cnt) <- fdRead rfd 1
40 forM_ cs (handler . unsafeCoerce {- . trace "read byte" -})
41 monitor)
42 `E.catch`
43 \(e :: IOException) -> do
44 err <- getErrno
45 case () of
46 _ | err==eAGAIN -> monitor
47 _ | otherwise -> cleanup
48 `E.catch`
49 \(e :: AsyncException) -> cleanup
50 monitor
51 return (rfd,thread)
52
53unmonitorTTY :: (Fd, ThreadId) -> IO ()
54unmonitorTTY (rfd,thread) = do
55 closeFd rfd
56 yield
57 killThread thread
58 raiseSignal sigUSR1
59 -- threadDelay 1000000
60
61
62-- vim:ft=haskell: