id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	os	architecture	failure	difficulty	testcase	blockedby	blocking	related
647	Socket bug on Mac OS X, with patch	gwright@…		"When using sockets on Mac OS X, some operations may fail with EADDRNOTAVAIL.
This is because a struct sockaddr_in (or struct sockaddr_un) is used
without being completely zeroed first.  Zeroing the struct first is necessary
on OS X and perhaps older BSDs as well.  The patch below only for darwin.

The bug was originally detected when trying the Zipper file system (ZFS)
example.  Without the patch, the program fails; with the patch, it runs
successfully.  Tested on an OS X 10.4.3, Xcode 2.2, powerbook G4 system.

-Greg Wright

patch:

{{{
--- libraries/network/Network/Socket.hsc.sav    2006-01-06 15:12:14.000000000 -0500
+++ libraries/network/Network/Socket.hsc        2006-01-06 18:08:48.000000000 -0500
@@ -357,15 +357,22 @@
    . shows port
 
 -- we can't write an instance of Storable for SockAddr, because the Storable
--- class can't easily handle alternatives.
+-- class can't easily handle alternatives. Also note that on Darwin, the
+-- sockaddr structure must be zeroed before use.
 
 #if defined(DOMAIN_SOCKET_SUPPORT)
 pokeSockAddr p (SockAddrUnix path) = do
+#if defined(darwin_TARGET_OS)
+       zeroMemory p (#const sizeof(struct sockaddr_un))
+#endif
        (#poke struct sockaddr_un, sun_family) p ((#const AF_UNIX) :: CSaFamily)
        let pathC = map castCharToCChar path
        pokeArray0 0 ((#ptr struct sockaddr_un, sun_path) p) pathC
 #endif
 pokeSockAddr p (SockAddrInet (PortNum port) addr) = do
+#if defined(darwin_TARGET_OS)
+       zeroMemory p (#const sizeof(struct sockaddr_in))
+#endif
        (#poke struct sockaddr_in, sin_family) p ((#const AF_INET) :: CSaFamily)
        (#poke struct sockaddr_in, sin_port) p port
        (#poke struct sockaddr_in, sin_addr) p addr
@@ -383,6 +390,11 @@
                port <- (#peek struct sockaddr_in, sin_port) p
                return (SockAddrInet (PortNum port) addr)
 
+-- helper function used to zero a structure
+zeroMemory :: Ptr a -> CSize -> IO ()
+zeroMemory dest nbytes = memset dest 0 (fromIntegral nbytes)
+foreign import ccall unsafe ""string.h"" memset :: Ptr a -> CInt -> CSize -> IO ()
+
 -- size of struct sockaddr by family
 #if defined(DOMAIN_SOCKET_SUPPORT)
 sizeOfSockAddr_Family AF_UNIX = #const sizeof(struct sockaddr_un)
}}}"	bug	closed	normal	6.4.2	libraries/network	6.4.1	fixed	"""OS X"" Sockets"	wolfgang.thaller@…	MacOS X	powerpc		Easy (less than 1 hour)				
