
Hi, the Network module provides the data type SocketOption. I am particularly interested in setting the RecvTimeOut and SendTimeOut values, but I wonder how to set them. The function setSocketOption :: Socket -> SocketOption -> Int -> IO () allows me only 'Int' parameters, but the kernel expects a struct timeval here -- or more accurately, a pointer to one. Do I really have to engage in FFI pointer wizardry here, or is there a simpler way to set these values? Am I even supposed to set them, or is there a better way to specify general I/O timeouts than on the socket level? Peter

Peter Simons wrote:
the Network module provides the data type SocketOption. I am particularly interested in setting the RecvTimeOut and SendTimeOut values, but I wonder how to set them. The function
setSocketOption :: Socket -> SocketOption -> Int -> IO ()
allows me only 'Int' parameters, but the kernel expects a struct timeval here -- or more accurately, a pointer to one. Do I really have to engage in FFI pointer wizardry here, or is there a simpler way to set these values?
You can't set the send/receive timeouts using that function; it always passes a C int (with the optlen parameter set to sizeof(int)). You would have to re-write it with a more flexible interface, e.g.:
import Foreign import Foreign.C import Network.Socket hiding (setSocketOption)
foreign import CALLCONV unsafe "setsockopt" c_setsockopt :: CInt -> CInt -> CInt -> Ptr () -> CInt -> IO CInt
setSocketOption :: (Storable a) => Socket -> SocketOption -- Option Name -> a -- Option Value -> IO () setSocketOption (MkSocket s _ _ _ _) so v = do with v $ \ptr_v -> do throwErrnoIfMinus1_ "setSocketOption" $ c_setsockopt s (socketOptLevel so) (packSocketOption so) (castPtr ptr_v) (fromIntegral (sizeOf v)) return ()
Note: neither socketOptLevel nor packSocketOption are exported from Network.Socket, so you would need to copy those (or just pass a pair of integers instead of the SocketOption).
Am I even supposed to set them, or is there a better way to specify general I/O timeouts than on the socket level?
Non-blocking I/O and select/poll; although I don't know how well that
is supported.
--
Glynn Clements

Glynn Clements writes:
Am I even supposed to set them, or is there a better way to specify general I/O timeouts than on the socket level?
Non-blocking I/O and select/poll; although I don't know how well that is supported.
Can anyone tell me how well supported it is? What would happen if a timeout occurs in the _socket_ level? Will an exception be thrown? Can I count on this behavior even when reading from a socket (read: a Handle promoted from a Socket) with hGetContents? Peter
participants (2)
-
Glynn Clements
-
Peter Simons