{-# LINE 1 "Network/Socket/Unix.hsc" #-}
{-# LANGUAGE CPP #-}
#include "HsNetDef.h"
module Network.Socket.Unix (
    isUnixDomainSocketAvailable
  , socketPair
  , sendFd
  , recvFd
  , getPeerCredential
  , getPeerCred
  , getPeerEid
  ) where
import Network.Socket.Imports
import Network.Socket.Types
{-# LINE 20 "Network/Socket/Unix.hsc" #-}
import Foreign.Marshal.Utils (with)
{-# LINE 22 "Network/Socket/Unix.hsc" #-}
{-# LINE 26 "Network/Socket/Unix.hsc" #-}
{-# LINE 27 "Network/Socket/Unix.hsc" #-}
import Control.Monad (void)
import Foreign.Marshal.Alloc (allocaBytes)
import Foreign.Marshal.Array (peekArray)
import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable(..))
import Network.Socket.Fcntl
import Network.Socket.Internal
{-# LINE 36 "Network/Socket/Unix.hsc" #-}
{-# LINE 37 "Network/Socket/Unix.hsc" #-}
import Network.Socket.Options (c_getsockopt)
{-# LINE 39 "Network/Socket/Unix.hsc" #-}
getPeerCredential :: Socket -> IO (Maybe CUInt, Maybe CUInt, Maybe CUInt)
{-# LINE 54 "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 67 "Network/Socket/Unix.hsc" #-}
getPeerCred :: Socket -> IO (CUInt, CUInt, CUInt)
{-# LINE 74 "Network/Socket/Unix.hsc" #-}
getPeerCred s = do
  let sz = (12)
{-# LINE 76 "Network/Socket/Unix.hsc" #-}
  fd <- fdSocket s
  allocaBytes sz $ \ ptr_cr ->
   with (fromIntegral sz) $ \ ptr_sz -> do
     _ <- ($) throwSocketErrorIfMinus1Retry "Network.Socket.getPeerCred" $
       c_getsockopt fd (1) (17) ptr_cr ptr_sz
{-# LINE 81 "Network/Socket/Unix.hsc" #-}
     pid <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr_cr
{-# LINE 82 "Network/Socket/Unix.hsc" #-}
     uid <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) ptr_cr
{-# LINE 83 "Network/Socket/Unix.hsc" #-}
     gid <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) ptr_cr
{-# LINE 84 "Network/Socket/Unix.hsc" #-}
     return (pid, uid, gid)
{-# LINE 88 "Network/Socket/Unix.hsc" #-}
{-# Deprecated getPeerCred "Use getPeerCredential instead" #-}
getPeerEid :: Socket -> IO (CUInt, CUInt)
{-# LINE 109 "Network/Socket/Unix.hsc" #-}
getPeerEid _ = return (0, 0)
{-# LINE 111 "Network/Socket/Unix.hsc" #-}
{-# Deprecated getPeerEid "Use getPeerCredential instead" #-}
isUnixDomainSocketAvailable :: Bool
{-# LINE 119 "Network/Socket/Unix.hsc" #-}
isUnixDomainSocketAvailable = True
{-# LINE 123 "Network/Socket/Unix.hsc" #-}
sendFd :: Socket -> CInt -> IO ()
{-# LINE 129 "Network/Socket/Unix.hsc" #-}
sendFd s outfd = void $ do
  fd <- fdSocket s
  throwSocketErrorWaitWrite s "Network.Socket.sendFd" $ c_sendFd fd outfd
foreign import ccall SAFE_ON_WIN "sendFd" c_sendFd :: CInt -> CInt -> IO CInt
{-# LINE 136 "Network/Socket/Unix.hsc" #-}
recvFd :: Socket -> IO CInt
{-# LINE 144 "Network/Socket/Unix.hsc" #-}
recvFd s = do
  fd <- fdSocket s
  throwSocketErrorWaitRead s "Network.Socket.recvFd" $ c_recvFd fd
foreign import ccall SAFE_ON_WIN "recvFd" c_recvFd :: CInt -> IO CInt
{-# LINE 151 "Network/Socket/Unix.hsc" #-}
socketPair :: Family              
           -> SocketType          
           -> ProtocolNumber      
           -> IO (Socket, Socket) 
{-# LINE 161 "Network/Socket/Unix.hsc" #-}
socketPair family stype protocol =
    allocaBytes (2 * sizeOf (1 :: CInt)) $ \ fdArr -> do
      c_stype <- packSocketTypeOrThrow "socketPair" 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 178 "Network/Socket/Unix.hsc" #-}