packages feed

bindings-sipc-1.0: src/Bindings/SELinux/SIPC.chs

{- |
Module      : Bindings.SELinux.SIPC
Copyright   : Justin Ethier
License     : LGPL

Maintainer  : github.com/justinethier
Stability   : experimental
Portability : portable

This module provides Haskell bindings for the SELinux SIPC library.

-}

{-# LANGUAGE ForeignFunctionInterface#-}

module Bindings.SELinux.SIPC
    ( SipcRole(..)
    , SipcType(..)
    , SipcIOCtl(..)
    , SipcPtr
    , sipcOpen
    , sipcClose
    , sipcUnlink
    , sipcIoctl
    , sipcSendData 
    , sipcGetDataPtr
    , sipcRecvData
    , sipcShmRecvDone
    ) where

import Foreign
import Foreign.C

-- The sipc header must be installed on your system
-- in order to compile this module!!
#include <sipc/sipc.h>

#c
enum SipcRole {
 SipcCreator  = SIPC_CREATOR,
 SipcSender   = SIPC_SENDER,
 SipcReceiver = SIPC_RECEIVER
};
enum SipcType {
 SipcSysvShm     = SIPC_SYSV_SHM,
 SipcSysvMqueues = SIPC_SYSV_MQUEUES,
 SipcNumTypes    = SIPC_NUM_TYPES
};
enum SipcIOCtl {
 SipcBlock   = SIPC_BLOCK,
 SipcNoblock = SIPC_NOBLOCK
};
#endc

-- |SIPC Roles
{#enum SipcRole {} deriving (Eq, Show)#}
-- |SIPC Types
{#enum SipcType {} deriving (Eq, Show)#}
-- |SIPC behaviors, for sipc_ioctl()
{#enum SipcIOCtl {} deriving (Eq, Show)#}

-- |A pointer to the sipc struct type
type SipcPtr = Ptr ()

{-
/* sipc_open(char *key, int role, int ipc_type, size_t size)
 *	key		Unique key to identify IPC communication channel,
 *			must be the same for the sender and reciever.
 *	role		SIPC_CREATOR if this application is the IPC creator,
 *			SIPC_SENDER for the sender and SIPC_RECEIVER
 *			for the reciever
 *	ipc_type	Which IPC type used, must be the same for sender
 *			and reciever.
 *	size		Maximum message size to be transmitted.
 *
-}

-- |This function must be called before any other function to initialize
--  the sipc struct.  Caller must call sipcClose to free the memory.
{#fun unsafe sipc_open as ^ {
    `String',               -- ^ Unique key to identify the communication channel 
    cFromEnum `SipcRole', 
    cFromEnum `SipcType', 
    fromIntegral `CSize' 
  } -> `SipcPtr' id #}

-- |Free the sipc struct and its contents
{#fun unsafe sipc_close as ^ {id `SipcPtr'} -> `()' #}

-- |Called by a helper application to destroy an IPC resource.
{#fun unsafe sipc_unlink as ^ {`String', cFromEnum `SipcType'} -> `()' #}

-- |Modify the behavior of an open SIPC channel.  Returns 0 on success,
--  <0 on failure.
{#fun unsafe sipc_ioctl as ^ {id `SipcPtr', cFromEnum `SipcIOCtl'} -> `Int' #}

-- |Blocking call to send msglen bytes of data.
--  This can only be called if sender was specified when sipcOpen was called.
--  returns 0 on success, <0 on failure
{#fun unsafe sipc_send_data as ^ {id `SipcPtr', fromIntegral `CSize'} -> `Int' #}

-- |Returns a pointer to the data contained within the IPC resource
{#fun unsafe sipc_get_data_ptr as ^ {id `SipcPtr'} -> `Ptr CChar' id #}

-- |Call to receive data.  Data will be allocated and filled and len
--  will be set to the length.  Returns 0 on success, <0 on failure.
sipcRecvData :: SipcPtr -> IO (Int, Ptr CChar, CSize)
sipcRecvData a1 =
  let {a1' = id a1} in
  alloca $ \a2' ->
  alloca $ \a3' ->
  sipcRecvData'_ a1' a2' a3' >>= \res ->
  peek  a2'>>= \a2'' ->
  peek  a3'>>= \a3'' ->
  let {res' = fromIntegral res} in
  return (res', a2'', fromIntegral a3'')
foreign import ccall unsafe "Bindings/SELinux/SIPC.chs.h sipc_recv_data"
  sipcRecvData'_ :: ((Ptr ()) -> ((Ptr (Ptr CChar)) -> ((Ptr CUInt) -> (IO CInt))))

-- FUTURE: It would be nice to use the following directive to generate 
--         sipcRecvData, but CSize maps to either CUInt (32-bit) or
--         CULong (64-bit) and I can only get this #fun to work by 
--         hardcoding one of those types instead of CSize: 
--{#fun unsafe sipc_recv_data as ^ {id `SipcPtr', alloca- `Ptr CChar' peek*, alloca- `CSize' peek*} -> `Int' #}

-- |Receiver calls this when it is done receiving a message in shared
--  memory.  There must be exactly one call to sipcShmRecvDone() for
--  every call to sipcRecvData(), if the sipc was created as shared
--  memory.
{#fun unsafe sipc_shm_recv_done as ^ {id `SipcPtr'} -> `Int' #}

-- |Convert a Haskell enumeration to C.
-- 
--  This code is from C2HS, but it has been added
--  here since C2HS is deprecated.
cFromEnum :: (Enum e, Integral i) => e -> i
cFromEnum  = fromIntegral . fromEnum