Patch with new API for get/setsockopt

Hi, Russell O'Connor pointed out the other day that it is impossible to use the getSocketOption/setSocketOption functions on options which expect or provide a non-Int value. I've concocted another API which allows values to be constructed from a specific disjoint union. This should make it possible to use options like SendTimeOut which expect a struct timeval. The attached darcs patch to the network package has the new functions setSockOpt/getSockOpt and SocketOptionValue. Whether or not those will be the final names, I am not sure. Also, I thought of some better possible interfaces, but on Ian's suggestion I stuck to Haskell'98 capabilities only. I've tested it on Linux/x86-64 and run the validate script. I'm new to GHC development, though, so I'm not sure if I should just go ahead and submit the patch. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org

Hi, Matthew -
I've concocted another API which allows values to be constructed from a specific disjoint union. This should make it possible to use options like SendTimeOut which expect a struct timeval.
Thanks for posting the patch. Unfortunately, I don't think it's an improvement over the current API, as it dcontinues to defer the detection of mismatches between names and the types of their values to runtime. I would prefer to see the API changed to associate the type of a value with the name of its constructor, like this: data SocketOption = DontRoute Bool | TimeToLive Int64 | ... One could still pass values of this type into getSocketOption by filling out the arguments to a constructor with any value, including undefined. There's already ample precedent for this, in the form of Data.Storable's sizeOf. This presents a safer statically checkable interface, while remaining in the bounds of H98.

On Sat, Sep 08, 2007 at 09:03:45PM -0700, Bryan O'Sullivan wrote:
I would prefer to see the API changed to associate the type of a value with the name of its constructor, like this:
data SocketOption = DontRoute Bool | TimeToLive Int64 | ...
One could still pass values of this type into getSocketOption by filling out the arguments to a constructor with any value, including undefined. There's already ample precedent for this, in the form of Data.Storable's sizeOf.
This presents a safer statically checkable interface, while remaining in the bounds of H98.
I thought of this, but didn't go this way because I did not want to change the existing SocketOption type. There's also some argument that providing such a type is higher-level than the Network.Socket library, since everything else is pretty much as unforgiving as C. The point of this patch was to bring the Haskell API to getsockopt/setsockopt at least to the level of the C API (which exploits weak typing). I would much prefer a nicer interface, of course, but I am not sure that it should be part of Network.Socket. I was originally planning to write something with type families, but then realized that this had to run in Hugs as well. -- -- Matthew Danish -- user: mrd domain: cmu.edu -- OpenPGP public key: C24B6010 on keyring.debian.org

Matthew Danish wrote:
I thought of this, but didn't go this way because I did not want to change the existing SocketOption type.
Sure.
There's also some argument that providing such a type is higher-level than the Network.Socket library, since everything else is pretty much as unforgiving as C.
There's already extensive use of ADTs where C's socket interface accepts ints and pointers to untyped structs (e.g. struct sockaddr).

Matthew Danish wrote:
Russell O'Connor pointed out the other day that it is impossible to use the getSocketOption/setSocketOption functions on options which expect or provide a non-Int value.
I've concocted another API which allows values to be constructed from a specific disjoint union. This should make it possible to use options like SendTimeOut which expect a struct timeval.
The attached darcs patch to the network package has the new functions setSockOpt/getSockOpt and SocketOptionValue. Whether or not those will be the final names, I am not sure. Also, I thought of some better possible interfaces, but on Ian's suggestion I stuck to Haskell'98 capabilities only.
I've tested it on Linux/x86-64 and run the validate script. I'm new to GHC development, though, so I'm not sure if I should just go ahead and submit the patch.
I had a half finished patch for this problem last year that makes getSocketOption and setSocketOption polymorphic, and with compile time type checks [*] - see http://www.haskell.org/pipermail/libraries/2006-June/005468.html Sadly I dropped the ball on this - the missing bit is marshalling time_val stuff and I'm still unsure where that should go; System.Posix.Time seems reasonable. Should I pick it up again? The downside of this approach is that it does break backwards compatibility for all options that don't take Int values. (This is curable of course, by providing two interfaces, like you do.) Bertram [*] not completely secure but good enough to catch mistakes for reasonable uses. Better safety could be achieved with GADTs as pointed out by Simon Marlow in http://www.haskell.org/pipermail/libraries/2006-July/005534.html
participants (3)
-
Bertram Felgenhauer
-
Bryan O'Sullivan
-
Matthew Danish