Skip to content

Socket bug on Mac OS X, with patch

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)
Trac metadata
Trac field Value
Version 6.4.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information