|
1 | 1 | module Server where
|
2 | 2 |
|
3 |
| -import Control.Exception (bracket, finally, tryJust) |
| 3 | +import Control.Exception (bracket, finally, handleJust, tryJust) |
4 | 4 | import Control.Monad (guard)
|
5 | 5 | import Data.IORef (IORef, newIORef, readIORef, writeIORef)
|
| 6 | +import GHC.IO.Exception (IOErrorType(ResourceVanished)) |
6 | 7 | import Network (PortID(UnixSocket), Socket, accept, listenOn, sClose)
|
7 | 8 | import System.Directory (removeFile)
|
8 | 9 | import System.Exit (ExitCode(ExitSuccess))
|
9 | 10 | import System.IO (Handle, hClose, hFlush, hGetLine, hPutStrLn)
|
10 |
| -import System.IO.Error (isDoesNotExistError) |
| 11 | +import System.IO.Error (ioeGetErrorType, isDoesNotExistError) |
11 | 12 |
|
12 | 13 | import CommandLoop (newCommandLoopState, startCommandLoop)
|
13 | 14 | import Types (ClientDirective(..), Command, ServerDirective(..))
|
@@ -44,11 +45,14 @@ clientSend :: IORef (Maybe Handle) -> ClientDirective -> IO ()
|
44 | 45 | clientSend currentClient clientDirective = do
|
45 | 46 | mbH <- readIORef currentClient
|
46 | 47 | case mbH of
|
47 |
| - Just h -> do |
48 |
| - -- TODO catch exception |
| 48 | + Just h -> ignoreEPipe $ do |
49 | 49 | hPutStrLn h (show clientDirective)
|
50 | 50 | hFlush h
|
51 | 51 | Nothing -> error "This is impossible"
|
| 52 | + where |
| 53 | + -- EPIPE means that the client is no longer there. |
| 54 | + ignoreEPipe = handleJust (guard . isEPipe) (const $ return ()) |
| 55 | + isEPipe = (==ResourceVanished) . ioeGetErrorType |
52 | 56 |
|
53 | 57 | getNextCommand :: IORef (Maybe Handle) -> Socket -> IO (Maybe (Command, [String]))
|
54 | 58 | getNextCommand currentClient sock = do
|
|
0 commit comments