Skip to content

Instantly share code, notes, and snippets.

@nh2
Last active July 13, 2019 20:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nh2/3fb70820d89f5e9f6d1ee80415c53a72 to your computer and use it in GitHub Desktop.
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
{-# 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
@nh2
Copy link
Author

nh2 commented Jul 13, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment