1module Network.Socket.Handle where 2 3import qualified GHC.IO.Device (IODeviceType(Stream)) 4import GHC.IO.Handle.FD (fdToHandle') 5import System.IO (IOMode(..), Handle, BufferMode(..), hSetBuffering) 6 7import Network.Socket.Types 8 9-- | Turns a Socket into an 'Handle'. By default, the new handle is 10-- unbuffered. Use 'System.IO.hSetBuffering' to change the buffering. 11-- 12-- Note that since a 'Handle' is automatically closed by a finalizer 13-- when it is no longer referenced, you should avoid doing any more 14-- operations on the 'Socket' after calling 'socketToHandle'. To 15-- close the 'Socket' after 'socketToHandle', call 'System.IO.hClose' 16-- on the 'Handle'. 17-- 18-- Caveat 'Handle' is not recommended for network programming in 19-- Haskell, e.g. merely performing 'hClose' on a TCP socket won't 20-- cooperate with peer's 'gracefulClose', i.e. proper shutdown 21-- sequence with appropriate handshakes specified by the protocol. 22 23socketToHandle :: Socket -> IOMode -> IO Handle 24socketToHandle s mode = invalidateSocket s err $ \oldfd -> do 25 h <- fdToHandle' oldfd (Just GHC.IO.Device.Stream) True (show s) mode True{-bin-} 26 hSetBuffering h NoBuffering 27 return h 28 where 29 err _ = ioError $ userError $ "socketToHandle: socket is no longer valid" 30