module System.Linux.XAttr
(
setXAttr
, lSetXAttr
, fdSetXAttr
, createXAttr
, lCreateXAttr
, fdCreateXAttr
, replaceXAttr
, lReplaceXAttr
, fdReplaceXAttr
, getXAttr
, lGetXAttr
, fdGetXAttr
, listXAttr
, lListXAttr
, fdListXAttr
, removeXAttr
, lRemoveXAttr
, fdRemoveXAttr
) where
import Data.ByteString (ByteString, packCStringLen,
useAsCStringLen)
import Foreign.C (CInt (..), CSize (..), CString,
peekCStringLen, throwErrnoIfMinus1,
throwErrnoIfMinus1_, withCString)
import Foreign.Marshal (allocaBytes)
import Foreign.Ptr (Ptr, castPtr, nullPtr)
import System.Posix.Types (CSsize (..), Fd (..))
xAttrSet :: String
-> ByteString
-> (a -> CString -> Ptr () -> CSize -> CInt -> IO CInt)
-> String
-> CInt
-> a
-> IO ()
xAttrSet attr value func name mode f =
throwErrnoIfMinus1_ name $ withCString attr $ \b ->
useAsCStringLen value $ \(c,d) ->
func f b (castPtr c) (fromIntegral d) mode
setXAttr :: FilePath
-> String
-> ByteString
-> IO ()
setXAttr path attr value =
withCString path $ xAttrSet attr value c_setxattr "setxattr" 0
lSetXAttr :: FilePath -> String -> ByteString -> IO ()
lSetXAttr path attr value =
withCString path $ xAttrSet attr value c_lsetxattr "lsetxattr" 0
fdSetXAttr :: Fd -> String -> ByteString -> IO ()
fdSetXAttr (Fd n) attr value =
xAttrSet attr value c_fsetxattr "fsetxattr" 0 n
createXAttr :: FilePath -> String -> ByteString -> IO ()
createXAttr path attr value =
withCString path $
xAttrSet attr value c_setxattr "setxattr" 1
lCreateXAttr :: FilePath -> String -> ByteString -> IO ()
lCreateXAttr path attr value =
withCString path $
xAttrSet attr value c_lsetxattr "lsetxattr" 1
fdCreateXAttr :: Fd -> String -> ByteString -> IO ()
fdCreateXAttr (Fd n) attr value =
xAttrSet attr value c_fsetxattr "fsetxattr" 1 n
replaceXAttr :: FilePath -> String -> ByteString -> IO ()
replaceXAttr path attr value =
withCString path $
xAttrSet attr value c_setxattr "setxattr" 2
lReplaceXAttr :: FilePath -> String -> ByteString -> IO ()
lReplaceXAttr path attr value =
withCString path $
xAttrSet attr value c_lsetxattr "lsetxattr" 2
fdReplaceXAttr :: Fd -> String -> ByteString -> IO ()
fdReplaceXAttr (Fd n) attr value =
xAttrSet attr value c_fsetxattr "fsetxattr" 2 n
xAttrGet :: String
-> (a -> CString -> Ptr () -> CSize -> IO CSsize)
-> String
-> a
-> IO ByteString
xAttrGet attr func name f =
withCString attr $ \cstr ->
do size <- throwErrnoIfMinus1 name (func f cstr nullPtr 0)
allocaBytes (fromIntegral size) $ \p ->
do throwErrnoIfMinus1_ name $ func f cstr p (fromIntegral size)
packCStringLen (castPtr p, fromIntegral size)
getXAttr :: FilePath
-> String
-> IO ByteString
getXAttr path attr =
withCString path $ xAttrGet attr c_getxattr "getxattr"
lGetXAttr :: FilePath -> String -> IO ByteString
lGetXAttr path attr =
withCString path $ xAttrGet attr c_lgetxattr "lgetxattr"
fdGetXAttr :: Fd -> String -> IO ByteString
fdGetXAttr (Fd n) attr =
xAttrGet attr c_fgetxattr "fgetxattr" n
xAttrList :: (a -> CString -> CSize -> IO CSsize)
-> String
-> a
-> IO [String]
xAttrList func name f =
do size <- throwErrnoIfMinus1 name (func f nullPtr 0)
allocaBytes (fromIntegral size) $ \p ->
do throwErrnoIfMinus1_ name (func f p (fromIntegral size))
str <- peekCStringLen (p, fromIntegral size)
return $ split str
where split "" = []
split xs = fst c : split (tail $ snd c)
where c = break (== '\NUL') xs
listXAttr :: FilePath
-> IO [String]
listXAttr path = withCString path $ xAttrList c_listxattr "listxattr"
lListXAttr :: FilePath -> IO [String]
lListXAttr path =
withCString path $ xAttrList c_llistxattr "llistxattr"
fdListXAttr :: Fd -> IO [String]
fdListXAttr (Fd n) =
xAttrList c_flistxattr "flistxattr" n
xAttrRemove :: String -> (a -> CString -> IO CInt) -> String -> a -> IO ()
xAttrRemove attr func name f =
throwErrnoIfMinus1_ name $ withCString attr (func f)
removeXAttr :: FilePath
-> String
-> IO ()
removeXAttr path attr =
withCString path $ xAttrRemove attr c_removexattr "removexattr"
lRemoveXAttr :: FilePath -> String -> IO ()
lRemoveXAttr path attr =
withCString path $ xAttrRemove attr c_lremovexattr "lremovexattr"
fdRemoveXAttr :: Fd -> String -> IO ()
fdRemoveXAttr (Fd n) attr =
xAttrRemove attr c_fremovexattr "fremovexattr" n
foreign import ccall unsafe "setxattr" c_setxattr :: CString
-> CString
-> Ptr ()
-> CSize
-> CInt
-> IO CInt
foreign import ccall unsafe "lsetxattr" c_lsetxattr :: CString
-> CString
-> Ptr ()
-> CSize
-> CInt
-> IO CInt
foreign import ccall unsafe "fsetxattr" c_fsetxattr :: CInt
-> CString
-> Ptr ()
-> CSize
-> CInt
-> IO CInt
foreign import ccall unsafe "getxattr" c_getxattr :: CString
-> CString
-> Ptr ()
-> CSize
-> IO CSsize
foreign import ccall unsafe "lgetxattr" c_lgetxattr :: CString
-> CString
-> Ptr ()
-> CSize
-> IO CSsize
foreign import ccall unsafe "fgetxattr" c_fgetxattr :: CInt
-> CString
-> Ptr ()
-> CSize
-> IO CSsize
foreign import ccall unsafe "listxattr" c_listxattr :: CString
-> CString
-> CSize
-> IO CSsize
foreign import ccall unsafe "llistxattr" c_llistxattr :: CString
-> CString
-> CSize
-> IO CSsize
foreign import ccall unsafe "flistxattr" c_flistxattr :: CInt
-> CString
-> CSize
-> IO CSsize
foreign import ccall unsafe "removexattr" c_removexattr :: CString
-> CString
-> IO CInt
foreign import ccall unsafe "lremovexattr" c_lremovexattr :: CString
-> CString
-> IO CInt
foreign import ccall unsafe "fremovexattr" c_fremovexattr :: CInt
-> CString
-> IO CInt