
On 26 June 2004 02:48, Glynn Clements wrote:
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 ()
I'm tempted to replace the current setSocketOption with this version. Would anyone object? Or perhaps we should include the new version under a different name? Cheers, Simon

Simon Marlow writes:
I'm tempted to replace the current setSocketOption with this version. Would anyone object?
On the contrary. IMHO, the SockOption type should be extended to contain the required parameter, for example: data SocketOption = Debug Bool | ReuseAddr Bool | SendBuffer (Maybe Int) -- bytes | RecvTimeOut (Maybe Int) -- milliseconds | SendTimeOut (Maybe Int) | [...] Then setSocketOption would even add the type-safety which the original function call doesn't have, and it would be more intuitive to use. Peter

mån 2004-06-28 klockan 14.00 skrev Peter Simons:
Simon Marlow writes:
I'm tempted to replace the current setSocketOption with this version. Would anyone object?
On the contrary. IMHO, the SockOption type should be extended to contain the required parameter, for example:
data SocketOption = Debug Bool | ReuseAddr Bool | SendBuffer (Maybe Int) -- bytes | RecvTimeOut (Maybe Int) -- milliseconds | SendTimeOut (Maybe Int) | [...]
Then setSocketOption would even add the type-safety which the original function call doesn't have, and it would be more intuitive to use.
Wouldn't that make
getSocketOption :: Socket -> SocketOption -> IO Int
a bit strange? How would you propose to change it?
/Martin
--
Martin Sjögren

Hi! On Mon, Jun 28, 2004 at 02:08:29PM +0200, Martin Sjögren wrote:
mån 2004-06-28 klockan 14.00 skrev Peter Simons:
Simon Marlow writes:
I'm tempted to replace the current setSocketOption with this version. Would anyone object?
On the contrary. IMHO, the SockOption type should be extended to contain the required parameter, for example:
data SocketOption = Debug Bool | ReuseAddr Bool | SendBuffer (Maybe Int) -- bytes | RecvTimeOut (Maybe Int) -- milliseconds | SendTimeOut (Maybe Int) | [...]
Then setSocketOption would even add the type-safety which the original function call doesn't have, and it would be more intuitive to use.
Wouldn't that make getSocketOption :: Socket -> SocketOption -> IO Int a bit strange? How would you propose to change it?
Possible, but also possibly overkill, would be: newtype Debug = Debug Bool newtype SendBuffer = SendBuffer (Maybe Int) [...] class SocketOption a where [...] instance SocketOption Debug [...] instance SocketOption SendBuffer [...] [...] setSocketOption :: SocketOption a => Socket -> a -> IO () getSocketOption :: SockerOption a => Socket -> IO a However, while quite clever :-), this would not be far from having a seperate get/set-functions for every option (and could indeed be implemented that way). Greetings, Carsten -- Carsten Schultz (2:38, 33:47), FB Mathematik, FU Berlin http://carsten.codimi.de/ PGP/GPG key on the pgp.net key servers, fingerprint on my home page.

Carsten Schultz wrote:
Wouldn't that make getSocketOption :: Socket -> SocketOption -> IO Int a bit strange? How would you propose to change it?
Possible, but also possibly overkill, would be:
newtype Debug = Debug Bool newtype SendBuffer = SendBuffer (Maybe Int) [...]
class SocketOption a where [...]
instance SocketOption Debug [...] instance SocketOption SendBuffer [...] [...]
setSocketOption :: SocketOption a => Socket -> a -> IO () getSocketOption :: SockerOption a => Socket -> IO a
However, while quite clever :-), this would not be far from having a seperate get/set-functions for every option (and could indeed be implemented that way).
This is a recurring problem and has been solved several times e.g. in some Haskell GUI bindings and my OpenGL/GLUT binding, see e.g.: http://haskell.org/HOpenGL/newAPI/OpenGL/Graphics.Rendering.OpenGL.GL.StateV... If we had: socketOptionDebug :: Socket -> StateVar Bool socketOptionSendBuffer :: Socket -> StateVar (Maybe Int) ... then we could write: socketOptionDebug mySocket $= True maybeBuf <- get $ socketOptionSendBuffer mySocket ... But there are some reasons for not using this here: * Alas, HasGetter/HasSetter/StateVar/... are not standard. * It's a bit overkill for the simple task at hand. :-) I would simply go for a single setter function and several getters here. Cheers, S.

Martin Sjögren writes:
Wouldn't that make getSocketOption :: Socket -> SocketOption -> IO Int a bit strange? How would you propose to change it?
Right, that is a problem. My first idea how to fix this would be getSocketOption :: Socket -> SocketOption -> IO SocketOption as in: Debug v <- getSocketOption sock (Debug undefined) But that's the first idea, not necessarily the best. Peter
participants (5)
-
Carsten Schultz
-
Martin Sjögren
-
Peter Simons
-
Simon Marlow
-
Sven Panne