import Network.BSD
import Network.Socket

connectToHaskell = do
  proto <- getProtocolNumber "tcp"
  sock <- socket AF_INET Stream proto
  he <- getHostByName "www.haskell.org"
  connect sock (SockAddrInet 80 (hostAddress he))
  send sock "GET / HTTP/0.9\r\n\r\n"
  return sock

main = do
  sock1 <- connectToHaskell
  -- Close the socket we just created.  This does not change the
  -- socket's status, but it frees up the underlying FD
  sClose sock1
  -- Now, when we create a new socket, *NIX will pick the lowest free
  -- FD, which should be the same FD number that backed sock1
  sock2 <- connectToHaskell
  -- Read from sock2, just to make sure it worked
  print =<< recv sock2 128

  -- Now we make it misbehave

  -- The following should fail because we closed sock1, but instead it
  -- reads from sock2
  putStrLn "Reading from closed socket; should fail but succeeds"
  print =<< recv sock1 128
  -- The following should fail or do nothing, but instead it closes
  -- sock2
  putStrLn "Closing closed socket; should fail or do nothing but succeeds"
  sClose sock1
  -- The following should succeed but doesn't because the previous
  -- line accidentally closed sock2
  putStrLn "Reading from supposedly open socket; should succeed but fails"
  print =<< recv sock2 128
