
Unix domain sockets are a type of socket created between two programs on a single Unix system. They are useful in part because over them you can send so-called ancillary data: file descriptors and credentials (i.e. a proof of who the process on the other end is). The thing is, Haskell doesn't have a nice way of sending ancillary data. Network.Socket does have these really opaque functions for sending and receiving ancillary data: sendAncillary :: Socket -> Int -> Int -> Int -> Ptr a -> Int -> IO () sendAncillary sock level ty flags datum len = do ... recvAncillary :: Socket -> Int -> Int -> IO (Int, Int, Ptr a, Int) recvAncillary sock flags len = do ... return (lev,ty,pD,len) Looking in the man page UNIX(7), which describes Unix domain sockets, some enlightening information is given. It says that ancillary data is sent and received using sendmsg(2) and recvmsg(2). Those two man pages say that sock and flags are arguments to sendmsg and recvmsg. UNIX(7) says that level is always SOL_SOCKET, and ty is either SCM_RIGHTS or SCM_CREDENTIALS depending on whether the ancillary data is file descriptors or credentials. In the former case, datum is "an integer array of the file descriptors"; in the latter case, it's the following struct: struct ucred { pid_t pid; /* process ID of the sending process */ uid_t uid; /* user ID of the sending process */ gid_t gid; /* group ID of the sending process */ }; As for len, this struct seems to be enlightening: struct cmsghdr { socklen_t cmsg_len; /* data byte count, including header */ int cmsg_level; /* originating protocol */ int cmsg_type; /* protocol-specific type */ /* followed by unsigned char cmsg_data[]; */ }; So, sock is a Socket, level is the constant SOL_SOCKET, ty is either SCM_RIGHTS or SCM_CREDENTIALS (strangely, Network.Socket contains the former but not the latter), flags is the flags passed to sendmsg or recvmsg (whatever those are--what are they?), datum is either a C integer array or that struct, and len is the length in bytes of all that. For me, this presents a few problems. I don't know where to get the SCM_CREDENTIALS constant, I have no idea what flags to use (does the Network module help with that?), I don't know how to get from a list of file descriptors or a tuple to a Ptr, and perhaps most importantly, I have no idea how to get the lengths of pid_t, uid_t, gid_t, and socklen_t. Can anyone offer assistance?