File: Handle.hs

package info (click to toggle)
haskell-network 3.2.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 760 kB
  • sloc: sh: 3,379; haskell: 2,211; ansic: 536; makefile: 3
file content (28 lines) | stat: -rw-r--r-- 1,256 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module Network.Socket.Handle where

import qualified GHC.IO.Device (IODeviceType (Stream))
import GHC.IO.Handle.FD (fdToHandle')
import System.IO (BufferMode (..), Handle, IOMode (..), hSetBuffering)

import Network.Socket.Types

-- | Turns a Socket into an 'Handle'. By default, the new handle is
-- unbuffered. Use 'System.IO.hSetBuffering' to change the buffering.
--
-- Note that since a 'Handle' is automatically closed by a finalizer
-- when it is no longer referenced, you should avoid doing any more
-- operations on the 'Socket' after calling 'socketToHandle'.  To
-- close the 'Socket' after 'socketToHandle', call 'System.IO.hClose'
-- on the 'Handle'.
--
-- Caveat 'Handle' is not recommended for network programming in
-- Haskell, e.g. merely performing 'hClose' on a TCP socket won't
-- cooperate with peer's 'gracefulClose', i.e. proper shutdown
-- sequence with appropriate handshakes specified by the protocol.
socketToHandle :: Socket -> IOMode -> IO Handle
socketToHandle s mode = invalidateSocket s err $ \oldfd -> do
    h <- fdToHandle' oldfd (Just GHC.IO.Device.Stream) True (show s) mode True {-bin-}
    hSetBuffering h NoBuffering
    return h
  where
    err _ = ioError $ userError $ "socketToHandle: socket is no longer valid"