Last active
July 13, 2019 20:20
-
-
Save nh2/3fb70820d89f5e9f6d1ee80415c53a72 to your computer and use it in GitHub Desktop.
Check whether a port is open in Haskell - OUTDATED; newer version here: https://gist.github.com/nh2/0a1442eb71ec0405a1e3ce83a467dfde
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE ScopedTypeVariables #-} | |
module IsPortOpen where | |
import Control.Exception (bracket, catchJust) | |
import Network (PortID(PortNumber), PortNumber, connectTo) | |
import System.IO (hClose) | |
import System.IO.Error (ioeGetErrorType, isDoesNotExistErrorType) | |
isPortOpen :: String -> PortNumber -> IO Bool | |
isPortOpen host portNo = do | |
let connectOrThrow :: IO () | |
connectOrThrow = | |
bracket | |
(connectTo host (PortNumber portNo)) | |
(hClose) | |
(\_ -> return ()) | |
catchJust | |
(\(err :: IOError) -> | |
-- Unfortunately IOError doesn't give us the exact `errno` so we | |
-- cannot precisely match `ECONNREFUSED`. | |
-- `isDoesNotExistErrorType` is the closest Haskell approximation | |
-- because `ECONNREFUSED` gets mapped to `NoSuchThing` which | |
-- gets matched with `isDoesNotExistErrorType`. | |
if isDoesNotExistErrorType (ioeGetErrorType err) then Just () else Nothing) | |
(connectOrThrow >> return True) -- on success | |
(\() -> return False) -- on failure |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This example is outdated now because it uses the deprecated
Socket
module.See this newer version for a better version, that also solves the
Unfortunately IOError doesn't give us the exact errno
problem.