{-# LINE 1 "Network/Socket/Unix.hsc" #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
#include "HsNetDef.h"
module Network.Socket.Unix (
isUnixDomainSocketAvailable
, socketPair
, sendFd
, recvFd
, getPeerCredential
, getPeerCred
, getPeerEid
) where
import Foreign.Marshal.Alloc (allocaBytes)
import Network.Socket.Buffer
import Network.Socket.Fcntl
import Network.Socket.Imports
import Network.Socket.Types
import System.Posix.Types (Fd(..))
{-# LINE 31 "Network/Socket/Unix.hsc" #-}
import Foreign.Marshal.Array (peekArray)
import Network.Socket.Internal
import Network.Socket.Posix.Cmsg
{-# LINE 35 "Network/Socket/Unix.hsc" #-}
{-# LINE 39 "Network/Socket/Unix.hsc" #-}
{-# LINE 42 "Network/Socket/Unix.hsc" #-}
{-# LINE 44 "Network/Socket/Unix.hsc" #-}
import Network.Socket.Options
{-# LINE 46 "Network/Socket/Unix.hsc" #-}
getPeerCredential :: Socket -> IO (Maybe CUInt, Maybe CUInt, Maybe CUInt)
{-# LINE 61 "Network/Socket/Unix.hsc" #-}
getPeerCredential sock = do
(pid, uid, gid) <- getPeerCred sock
if uid == maxBound then
return (Nothing, Nothing, Nothing)
else
return (Just pid, Just uid, Just gid)
{-# LINE 77 "Network/Socket/Unix.hsc" #-}
getPeerCred :: Socket -> IO (CUInt, CUInt, CUInt)
{-# LINE 84 "Network/Socket/Unix.hsc" #-}
getPeerCred s = do
let opt = SockOpt (1) (17)
{-# LINE 86 "Network/Socket/Unix.hsc" #-}
PeerCred cred <- getSockOpt s opt
return cred
newtype PeerCred = PeerCred (CUInt, CUInt, CUInt)
instance Storable PeerCred where
sizeOf ~_ = (12)
{-# LINE 92 "Network/Socket/Unix.hsc" #-}
alignment ~_ = alignment (0 :: CInt)
poke _ _ = return ()
peek p = do
pid <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p
{-# LINE 96 "Network/Socket/Unix.hsc" #-}
uid <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) p
{-# LINE 97 "Network/Socket/Unix.hsc" #-}
gid <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) p
{-# LINE 98 "Network/Socket/Unix.hsc" #-}
return $ PeerCred (pid, uid, gid)
{-# LINE 102 "Network/Socket/Unix.hsc" #-}
{-# Deprecated getPeerCred "Use getPeerCredential instead" #-}
getPeerEid :: Socket -> IO (CUInt, CUInt)
{-# LINE 123 "Network/Socket/Unix.hsc" #-}
getPeerEid _ = return (0, 0)
{-# LINE 125 "Network/Socket/Unix.hsc" #-}
{-# Deprecated getPeerEid "Use getPeerCredential instead" #-}
isUnixDomainSocketAvailable :: Bool
isUnixDomainSocketAvailable = True
sendFd :: Socket -> CInt -> IO ()
sendFd s outfd = void $ allocaBytes dummyBufSize $ \buf -> do
let cmsg = encodeCmsg [Fd outfd]
sendBufMsg s NullSockAddr [(buf,dummyBufSize)] [cmsg] mempty
where
dummyBufSize = 1
recvFd :: Socket -> IO CInt
recvFd s = allocaBytes dummyBufSize $ \buf -> do
(NullSockAddr, _, cmsgs, _) <- recvBufMsg s [(buf,dummyBufSize)] 32 mempty
case (lookupCmsg CmsgIdFds cmsgs >>= decodeCmsg) :: Maybe [Fd] of
Just (Fd fd : _) -> return fd
_ -> return (-1)
where
dummyBufSize = 16
socketPair :: Family
-> SocketType
-> ProtocolNumber
-> IO (Socket, Socket)
{-# LINE 180 "Network/Socket/Unix.hsc" #-}
socketPair family stype protocol =
allocaBytes (2 * sizeOf (1 :: CInt)) $ \ fdArr -> do
let c_stype = packSocketType stype
_rc <- throwSocketErrorIfMinus1Retry "Network.Socket.socketpair" $
c_socketpair (packFamily family) c_stype protocol fdArr
[fd1,fd2] <- peekArray 2 fdArr
setNonBlockIfNeeded fd1
setNonBlockIfNeeded fd2
s1 <- mkSocket fd1
s2 <- mkSocket fd2
return (s1, s2)
foreign import ccall unsafe "socketpair"
c_socketpair :: CInt -> CInt -> CInt -> Ptr CInt -> IO CInt
{-# LINE 195 "Network/Socket/Unix.hsc" #-}