linux-xattr 0.1.0.1 → 0.1.1.0
raw patch · 4 files changed
+424/−165 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ System.Linux.XAttr: createUserXAttr :: FilePath -> Name -> Value -> IO ()
+ System.Linux.XAttr: fdCreateUserXAttr :: Fd -> Name -> Value -> IO ()
+ System.Linux.XAttr: fdGetUserXAttr :: Fd -> Name -> IO Value
+ System.Linux.XAttr: fdListUserXAttr :: Fd -> IO [Name]
+ System.Linux.XAttr: fdRemoveUserXAttr :: Fd -> Name -> IO ()
+ System.Linux.XAttr: fdReplaceUserXAttr :: Fd -> Name -> Value -> IO ()
+ System.Linux.XAttr: fdSetUserXAttr :: Fd -> Name -> Value -> IO ()
+ System.Linux.XAttr: getUserXAttr :: FilePath -> Name -> IO Value
+ System.Linux.XAttr: lCreateUserXAttr :: FilePath -> Name -> Value -> IO ()
+ System.Linux.XAttr: lGetUserXAttr :: FilePath -> Name -> IO Value
+ System.Linux.XAttr: lListUserXAttr :: FilePath -> IO [Name]
+ System.Linux.XAttr: lRemoveUserXAttr :: FilePath -> Name -> IO ()
+ System.Linux.XAttr: lReplaceUserXAttr :: FilePath -> Name -> Value -> IO ()
+ System.Linux.XAttr: lSetUserXAttr :: FilePath -> Name -> Value -> IO ()
+ System.Linux.XAttr: listUserXAttr :: FilePath -> IO [Name]
+ System.Linux.XAttr: removeUserXAttr :: FilePath -> Name -> IO ()
+ System.Linux.XAttr: replaceUserXAttr :: FilePath -> Name -> Value -> IO ()
+ System.Linux.XAttr: setUserXAttr :: FilePath -> Name -> Value -> IO ()
+ System.Linux.XAttr: type Name = String
+ System.Linux.XAttr: type Value = ByteString
- System.Linux.XAttr: createXAttr :: FilePath -> String -> ByteString -> IO ()
+ System.Linux.XAttr: createXAttr :: FilePath -> Name -> Value -> IO ()
- System.Linux.XAttr: fdCreateXAttr :: Fd -> String -> ByteString -> IO ()
+ System.Linux.XAttr: fdCreateXAttr :: Fd -> Name -> Value -> IO ()
- System.Linux.XAttr: fdGetXAttr :: Fd -> String -> IO ByteString
+ System.Linux.XAttr: fdGetXAttr :: Fd -> Name -> IO Value
- System.Linux.XAttr: fdListXAttr :: Fd -> IO [String]
+ System.Linux.XAttr: fdListXAttr :: Fd -> IO [Name]
- System.Linux.XAttr: fdRemoveXAttr :: Fd -> String -> IO ()
+ System.Linux.XAttr: fdRemoveXAttr :: Fd -> Name -> IO ()
- System.Linux.XAttr: fdReplaceXAttr :: Fd -> String -> ByteString -> IO ()
+ System.Linux.XAttr: fdReplaceXAttr :: Fd -> Name -> Value -> IO ()
- System.Linux.XAttr: fdSetXAttr :: Fd -> String -> ByteString -> IO ()
+ System.Linux.XAttr: fdSetXAttr :: Fd -> Name -> Value -> IO ()
- System.Linux.XAttr: getXAttr :: FilePath -> String -> IO ByteString
+ System.Linux.XAttr: getXAttr :: FilePath -> Name -> IO Value
- System.Linux.XAttr: lCreateXAttr :: FilePath -> String -> ByteString -> IO ()
+ System.Linux.XAttr: lCreateXAttr :: FilePath -> Name -> Value -> IO ()
- System.Linux.XAttr: lGetXAttr :: FilePath -> String -> IO ByteString
+ System.Linux.XAttr: lGetXAttr :: FilePath -> Name -> IO Value
- System.Linux.XAttr: lListXAttr :: FilePath -> IO [String]
+ System.Linux.XAttr: lListXAttr :: FilePath -> IO [Name]
- System.Linux.XAttr: lRemoveXAttr :: FilePath -> String -> IO ()
+ System.Linux.XAttr: lRemoveXAttr :: FilePath -> Name -> IO ()
- System.Linux.XAttr: lReplaceXAttr :: FilePath -> String -> ByteString -> IO ()
+ System.Linux.XAttr: lReplaceXAttr :: FilePath -> Name -> Value -> IO ()
- System.Linux.XAttr: lSetXAttr :: FilePath -> String -> ByteString -> IO ()
+ System.Linux.XAttr: lSetXAttr :: FilePath -> Name -> Value -> IO ()
- System.Linux.XAttr: listXAttr :: FilePath -> IO [String]
+ System.Linux.XAttr: listXAttr :: FilePath -> IO [Name]
- System.Linux.XAttr: removeXAttr :: FilePath -> String -> IO ()
+ System.Linux.XAttr: removeXAttr :: FilePath -> Name -> IO ()
- System.Linux.XAttr: replaceXAttr :: FilePath -> String -> ByteString -> IO ()
+ System.Linux.XAttr: replaceXAttr :: FilePath -> Name -> Value -> IO ()
- System.Linux.XAttr: setXAttr :: FilePath -> String -> ByteString -> IO ()
+ System.Linux.XAttr: setXAttr :: FilePath -> Name -> Value -> IO ()
Files
- CHANGELOG.md +35/−1
- README.md +15/−6
- System/Linux/XAttr.hsc +361/−150
- linux-xattr.cabal +13/−8
CHANGELOG.md view
@@ -1,8 +1,42 @@+Version 0.1.1.0 (2014-06-05)+----------------------------++- New functions for working in the `user` namespace.+ * Set extended `user` attributes:+ - setUserXAttr+ - lSetUserXAttr+ - fdSetUserXAttr+ * Create extended `user` attributes:+ - createUserXAttr+ - lCreateUserXAttr+ - fdCreateUserXAttr+ * Replace extended `user` attributes:+ - replaceUserXAttr+ - lReplaceUserXAttr+ - fdReplaceUserXAttr+ * Retrieve extended `user` attributes:+ - getUserXAttr+ - lGetUserXAttr+ - fdGetUserXAttr+ * List extended `user` attributes:+ - listUserXAttr+ - lListUserXAttr+ - fdListUserXAttr+ * Remove extended `user` attributes:+ - removeUserXAttr+ - lRemoveUserXAttr+ - fdRemoveUserXAttr+- Use Safe Haskell extension.+- Use type synonyms `Name` and `Value` for name and value of extended+ attributes.+- Improve documentation.+- Minor code fixes.+ Version 0.1.0.1 (2014-04-08) ---------------------------- - Relicense under BSD3.-- Edit description and .cabal file+- Edit description and .cabal file. - Clean up code. Version 0.1.0.0 (2013-03-15)
README.md view
@@ -1,8 +1,17 @@ `linux-xattr` provides [Haskell][Haskell] bindings to the Linux syscalls for-reading and manipulating [extended attributes][ea] (`setxattr`, `getxattr`,-`listxattr`, ...).+reading and manipulating [extended attributes][ea] ([`setxattr`][setxattr],+[`getxattr`][getxattr], [`listxattr`][listxattr] and+[`removexattr`][removexattr]). - [Haskell]: http://www.haskell.org/- "Haskell Programming Language"- [ea]: http://en.wikipedia.org/wiki/Extended_file_attributes- "Extended file attributes"+ [Haskell]: http://www.haskell.org/+ "Haskell Programming Language"+ [ea]: http://en.wikipedia.org/wiki/Extended_file_attributes+ "Extended file attributes"+ [setxattr]: http://man7.org/linux/man-pages/man2/setxattr.2.html+ "setxattr(2) - Linux manual page"+ [getxattr]: http://man7.org/linux/man-pages/man2/getxattr.2.html+ "getxattr(2) - Linux manual page"+ [listxattr]: http://man7.org/linux/man-pages/man2/listxattr.2.html+ "listxattr(2) - Linux manual page"+ [removexattr]: http://man7.org/linux/man-pages/man2/removexattr.2.html+ "removexattr(2) - Linux manual page"
System/Linux/XAttr.hsc view
@@ -1,5 +1,3 @@-{-# LANGUAGE ForeignFunctionInterface #-}- -------------------------------------------------------------------------------- -- | -- Module : $Header$@@ -11,56 +9,157 @@ -- Portability : portable -- -- @linux-xattr@ provides bindings to the Linux syscalls for reading and--- manipulating extended attributes (@setxattr@, @getxattr@, @listxattr@, ...).+-- manipulating+-- <http://en.wikipedia.org/wiki/Extended_file_attributes extended attributes>+-- (@<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@,+-- @<http://man7.org/linux/man-pages/man2/getxattr.2.html getxattr>@,+-- @<http://man7.org/linux/man-pages/man2/listxattr.2.html listxattr>@ and+-- @<http://man7.org/linux/man-pages/man2/removexattr.2.html removexattr>@).+-- -- Each function in this module has two variants: one with the name prefixed by--- \"l\" and one prefixed by \"fd\". Both of these are identical to the--- original version except that the \"l\"-variant does not follow symbolic link--- but acts on the link itself, and the \"fd\"-variant take a file descriptor as--- argument rather than a @'FilePath'@.+-- @__l__@ and one prefixed by @__fd__@. Both of these are identical to the+-- original version except that the @__l__@-variant does not follow symbolic+-- link but acts on the link itself, and the @__fd__@-variant take a file+-- descriptor as argument rather than a @'FilePath'@. --+-- Moreover, every function has an @/xxx/__UserXAttr__@ variant for working+-- transparently in the @__user__@ namespace of extended attributes, without+-- worrying about the @"user."@ prefix: these functions automatically prepends+-- the string @"user."@ to the @'Name'@ of the attribute when @'Name'@ is an+-- input value, or strip the prefix @"user."@ from it when @'Name'@ is a+-- returned value. See the documentation of each individual function for+-- details.+-- -------------------------------------------------------------------------------- module System.Linux.XAttr ( -- * Set extended attributes++ -- | Functions in this section call the+ -- @<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@+ -- syscall.+ setXAttr , lSetXAttr , fdSetXAttr++ -- ** Set extended @user@ attributes++ , setUserXAttr+ , lSetUserXAttr+ , fdSetUserXAttr+ -- * Create extended attributes++ -- | Functions in this section call the+ -- @<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@+ -- syscall with the flag @XATTR_CREATE@.+ , createXAttr , lCreateXAttr , fdCreateXAttr++ -- ** Create extended @user@ attributes++ , createUserXAttr+ , lCreateUserXAttr+ , fdCreateUserXAttr+ -- * Replace extended attributes++ -- | Functions in this section call the+ -- @<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@+ -- syscall with the flag @XATTR_REPLACE@.+ , replaceXAttr , lReplaceXAttr , fdReplaceXAttr- -- * Retrive extended attributes++ -- ** Replace extended @user@ attributes++ , replaceUserXAttr+ , lReplaceUserXAttr+ , fdReplaceUserXAttr++ -- * Retrieve extended attributes++ -- | Functions in this section call the+ -- @<http://man7.org/linux/man-pages/man2/getxattr.2.html getxattr>@+ -- syscall.+ , getXAttr , lGetXAttr , fdGetXAttr++ -- ** Retrieve extended @user@ attributes++ , getUserXAttr+ , lGetUserXAttr+ , fdGetUserXAttr+ -- * List extended attributes++ -- | Functions in this section call the+ -- @<http://man7.org/linux/man-pages/man2/listxattr.2.html listxattr>@+ -- syscall.+ , listXAttr , lListXAttr , fdListXAttr++ -- ** List extended @user@ attributes++ -- | These functions only list those extended attributes with @'Name'@+ -- beginning with @"user."@. The @"user."@ prefix is removed from each+ -- @'Name'@ in the output list.++ , listUserXAttr+ , lListUserXAttr+ , fdListUserXAttr+ -- * Remove extended attributes++ -- | Functions in this section call the+ -- @<http://man7.org/linux/man-pages/man2/removexattr.2.html removexattr>@+ -- syscall.+ , removeXAttr , lRemoveXAttr , fdRemoveXAttr++ -- ** Remove extended @user@ attributes++ , removeUserXAttr+ , lRemoveUserXAttr+ , fdRemoveUserXAttr++ -- * Types for extended attributes++ , Name+ , Value ) where #include <sys/xattr.h> -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 (..))+import Control.Monad (liftM)+import Data.ByteString (ByteString, packCStringLen,+ useAsCStringLen)+import Foreign.C (CInt (..), CSize (..), CString,+ peekCStringLen, throwErrnoIfMinus1,+ throwErrnoIfMinus1_, withCString)+import Foreign.Marshal.Alloc (allocaBytes)+import Foreign.Ptr (Ptr, nullPtr)+import System.Posix.Types (CSsize (..), Fd (..)) -xAttrSet :: String- -> ByteString- -> (a -> CString -> Ptr () -> CSize -> CInt -> IO CInt)+-- | Name of extended attribute.+type Name = String++-- | Value of extended attribute.+type Value = ByteString++xAttrSet :: Name+ -> Value+ -> (a -> CString -> CString -> CSize -> CInt -> IO CInt) -> String -> CInt -> a@@ -68,101 +167,155 @@ xAttrSet attr value func name mode f = throwErrnoIfMinus1_ name $ withCString attr $ \b -> useAsCStringLen value $ \(c,d) ->- func f b (castPtr c) (fromIntegral d) mode+ func f b c (fromIntegral d) mode --- | Set the value of an extended attribute.-setXAttr :: FilePath -- ^ target file- -> String -- ^ name of attribute to set- -> ByteString -- ^ value of attribute- -> IO ()+-- | Set the @'Value'@ of the extended attribute identified by @'Name'@ and+-- associated with the given @'FilePath'@ in the filesystem.+setXAttr :: FilePath -> Name -> Value -> IO () setXAttr path attr value =- withCString path $ xAttrSet attr value c_setxattr "setxattr" 0+ withCString path $ xAttrSet attr value setxattr "setxattr" 0 --- | Set the value of an extended attribute (do not follow symbolic links).-lSetXAttr :: FilePath -> String -> ByteString -> IO ()+-- | @'setUserXAttr' "\/some\/path" "foo" "bar" = 'setXAttr' "\/some\/path" "user.foo" "bar"@+setUserXAttr :: FilePath -> Name -> Value -> IO ()+setUserXAttr = userXAttr setXAttr++-- | Set the @'Value'@ of the extended attribute identified by @'Name'@ and+-- associated with the given @'FilePath'@ in the filesystem (do not follow+-- symbolic links).+lSetXAttr :: FilePath -> Name -> Value -> IO () lSetXAttr path attr value =- withCString path $ xAttrSet attr value c_lsetxattr "lsetxattr" 0+ withCString path $ xAttrSet attr value lsetxattr "lsetxattr" 0 --- | Set the value of an extended attribute.-fdSetXAttr :: Fd -> String -> ByteString -> IO ()+-- | @'lSetUserXAttr' "\/some\/link" "foo" "bar" = 'lSetXAttr' "\/some\/link" "user.foo" "bar"@+lSetUserXAttr :: FilePath -> Name -> Value -> IO ()+lSetUserXAttr = userXAttr lSetXAttr++-- | Set the @'Value'@ of the extended attribute identified by @'Name'@ and+-- associated with the given file descriptor in the filesystem.+fdSetXAttr :: Fd -> Name -> Value -> IO () fdSetXAttr (Fd n) attr value =- xAttrSet attr value c_fsetxattr "fsetxattr" 0 n+ xAttrSet attr value fsetxattr "fsetxattr" 0 n --- | Identical to @'setXAttr'@, but if the attribute already exists fail and set--- errno to EEXIST.-createXAttr :: FilePath -> String -> ByteString -> IO ()+-- | @'fdSetUserXAttr' ('Fd' n) "foo" "bar" = 'fdSetXAttr' ('Fd' n) "user.foo" "bar"@+fdSetUserXAttr :: Fd -> Name -> Value -> IO ()+fdSetUserXAttr = userXAttr fdSetXAttr++-- | Identical to @'setXAttr'@, but if the attribute already exists fail with+-- @`System.IO.Error.isAlreadyExistsError`@.+createXAttr :: FilePath -> Name -> Value -> IO () createXAttr path attr value = withCString path $- xAttrSet attr value c_setxattr "setxattr" #{const XATTR_CREATE}+ xAttrSet attr value setxattr "setxattr" #{const XATTR_CREATE} --- | Identical to @'lSetXAttr'@, but if the attribute already exists fail and--- set errno to EEXIST.-lCreateXAttr :: FilePath -> String -> ByteString -> IO ()+-- | @'createUserXAttr' "\/some\/path" "foo" "bar" = 'createXAttr' "\/some\/path" "user.foo" "bar"@+createUserXAttr :: FilePath -> Name -> Value -> IO ()+createUserXAttr = userXAttr createXAttr++-- | Identical to @'lSetXAttr'@, but if the attribute already exists fail with+-- @`System.IO.Error.isAlreadyExistsError`@.+lCreateXAttr :: FilePath -> Name -> Value -> IO () lCreateXAttr path attr value = withCString path $- xAttrSet attr value c_lsetxattr "lsetxattr" #{const XATTR_CREATE}+ xAttrSet attr value lsetxattr "lsetxattr" #{const XATTR_CREATE} --- | Identical to @'fdSetXAttr'@, but if the attribute already exists fail and--- set errno to EEXIST.-fdCreateXAttr :: Fd -> String -> ByteString -> IO ()+-- | @'lCreateUserXAttr' "\/some\/link" "foo" "bar" = 'lCreateXAttr' "\/some\/link" "user.foo" "bar"@+lCreateUserXAttr :: FilePath -> Name -> Value -> IO ()+lCreateUserXAttr = userXAttr lCreateXAttr++-- | Identical to @'fdSetXAttr'@, but if the attribute already exists fail with+-- @`System.IO.Error.isAlreadyExistsError`@.+fdCreateXAttr :: Fd -> Name -> Value -> IO () fdCreateXAttr (Fd n) attr value =- xAttrSet attr value c_fsetxattr "fsetxattr" #{const XATTR_CREATE} n+ xAttrSet attr value fsetxattr "fsetxattr" #{const XATTR_CREATE} n --- | Identical to @'setXAttr'@, but if the attribute does not exist fail and set--- errno to ENOATTR.-replaceXAttr :: FilePath -> String -> ByteString -> IO ()+-- | @'fdCreateUserXAttr' ('Fd' n) "foo" "bar" = 'fdCreateXAttr' ('Fd' n) "user.foo" "bar"@+fdCreateUserXAttr :: Fd -> Name -> Value -> IO ()+fdCreateUserXAttr = userXAttr fdCreateXAttr++-- | Identical to @'setXAttr'@, but if the attribute does not exist fail with+-- @`System.IO.Error.isDoesNotExistError`@.+replaceXAttr :: FilePath -> Name -> Value -> IO () replaceXAttr path attr value = withCString path $- xAttrSet attr value c_setxattr "setxattr" #{const XATTR_REPLACE}+ xAttrSet attr value setxattr "setxattr" #{const XATTR_REPLACE} --- | Identical to @'lSetXAttr'@, but if the attribute does not exist fail and--- set errno to ENOATTR.-lReplaceXAttr :: FilePath -> String -> ByteString -> IO ()+-- | @'replaceUserXAttr' "\/some\/path" "foo" "bar" = 'replaceXAttr' "\/some\/path" "user.foo" "bar"@+replaceUserXAttr :: FilePath -> Name -> Value -> IO ()+replaceUserXAttr = userXAttr replaceXAttr++-- | Identical to @'lSetXAttr'@, but if the attribute does not exist fail with+-- @`System.IO.Error.isDoesNotExistError`@.+lReplaceXAttr :: FilePath -> Name -> Value -> IO () lReplaceXAttr path attr value = withCString path $- xAttrSet attr value c_lsetxattr "lsetxattr" #{const XATTR_REPLACE}+ xAttrSet attr value lsetxattr "lsetxattr" #{const XATTR_REPLACE} --- | Identical to @'fdSetXAttr'@, but if the attribute does not exist fail and--- set errno to ENOATTR.-fdReplaceXAttr :: Fd -> String -> ByteString -> IO ()+-- | @'lReplaceUserXAttr' "\/some\/link" "foo" "bar" = 'lReplaceXAttr' "\/some\/link" "user.foo" "bar"@+lReplaceUserXAttr :: FilePath -> Name -> Value -> IO ()+lReplaceUserXAttr = userXAttr lReplaceXAttr++-- | Identical to @'fdSetXAttr'@, but if the attribute does not exist fail with+-- @`System.IO.Error.isDoesNotExistError`@.+fdReplaceXAttr :: Fd -> Name -> Value -> IO () fdReplaceXAttr (Fd n) attr value =- xAttrSet attr value c_fsetxattr "fsetxattr" #{const XATTR_REPLACE} n+ xAttrSet attr value fsetxattr "fsetxattr" #{const XATTR_REPLACE} n +-- | @'fdReplaceUserXAttr' ('Fd' n) "foo" "bar" = 'fdReplaceXAttr' ('Fd' n) "user.foo" "bar"@+fdReplaceUserXAttr :: Fd -> Name -> Value -> IO ()+fdReplaceUserXAttr = userXAttr fdReplaceXAttr -xAttrGet :: String- -> (a -> CString -> Ptr () -> CSize -> IO CSsize)++xAttrGet :: Name+ -> (a -> CString -> CString -> CSize -> IO CSsize) -> String -> a- -> IO ByteString+ -> IO Value 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)+ packCStringLen (p, fromIntegral size) --- | Get the value of an extended attribute.-getXAttr :: FilePath -- ^ target file- -> String -- ^ name of the attribute- -> IO ByteString -- ^ value of the attribute+-- | Retrieve the @'Value'@ of the extended attribute identified by @'Name'@ and+-- associated with the given @'FilePath'@ in the filesystem, or fail with+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist.+getXAttr :: FilePath -> Name -> IO Value getXAttr path attr =- withCString path $ xAttrGet attr c_getxattr "getxattr"+ withCString path $ xAttrGet attr getxattr "getxattr" --- | Get the value of an extended attribute (do not follow symbolic links).-lGetXAttr :: FilePath -> String -> IO ByteString+-- | @'getUserXAttr' "\/some\/path" "foo" = 'getXAttr' "\/some\/path" "user.foo"@+getUserXAttr :: FilePath -> Name -> IO Value+getUserXAttr = userXAttr getXAttr++-- | Retrieve the @'Value'@ of the extended attribute identified by @'Name'@ and+-- associated with the given @'FilePath'@ in the filesystem, or fail with+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist (do+-- not follow symbolic links).+lGetXAttr :: FilePath -> Name -> IO Value lGetXAttr path attr =- withCString path $ xAttrGet attr c_lgetxattr "lgetxattr"+ withCString path $ xAttrGet attr lgetxattr "lgetxattr" --- | Get the value of an extended attribute.-fdGetXAttr :: Fd -> String -> IO ByteString+-- | @'lGetUserXAttr' "\/some\/link" "foo" = 'lGetXAttr' "\/some\/link" "user.foo"@+lGetUserXAttr :: FilePath -> Name -> IO Value+lGetUserXAttr = userXAttr lGetXAttr++-- | Retrieve the @'Value'@ of the extended attribute identified by @'Name'@ and+-- associated with the given file descriptor in the filesystem, or fail with+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist.+fdGetXAttr :: Fd -> Name -> IO Value fdGetXAttr (Fd n) attr =- xAttrGet attr c_fgetxattr "fgetxattr" n+ xAttrGet attr fgetxattr "fgetxattr" n +-- | @'fdGetUserXAttr' ('Fd' n) "foo" = 'fdGetXAttr' ('Fd' n) "user.foo"@+fdGetUserXAttr :: Fd -> Name -> IO Value+fdGetUserXAttr = userXAttr fdGetXAttr + xAttrList :: (a -> CString -> CSize -> IO CSsize) -> String -> a- -> IO [String]+ -> IO [Name] xAttrList func name f = do size <- throwErrnoIfMinus1 name (func f nullPtr 0) allocaBytes (fromIntegral size) $ \p ->@@ -173,111 +326,169 @@ split xs = fst c : split (tail $ snd c) where c = break (== '\NUL') xs --- | Get the list of attribute names associated with the given @'FilePath'@.-listXAttr :: FilePath -- ^ target file- -> IO [String] -- ^ list of attribute names-listXAttr path = withCString path $ xAttrList c_listxattr "listxattr"+-- | Get the list of extended attribute @'Name'@s associated with the given+-- @'FilePath'@ in the filesystem.+listXAttr :: FilePath -> IO [Name]+listXAttr path = withCString path $ xAttrList listxattr "listxattr" --- | Get the list of attribute names associated with the given @'FilePath'@ (do--- not follow symbolic links).-lListXAttr :: FilePath -> IO [String]+-- |+-- @+-- >>> 'listXAttr' "\/some\/path"+-- ["user.foo","user.bar"]+-- >>> 'listUserXAttr' "\/some\/path"+-- ["foo","bar"]+-- @+listUserXAttr :: FilePath -> IO [Name]+listUserXAttr = userXAttrList listXAttr++-- | Get the list of extended attribute @'Name'@s associated with the given+-- @'FilePath'@ in the filesystem (do not follow symbolic links).+lListXAttr :: FilePath -> IO [Name] lListXAttr path =- withCString path $ xAttrList c_llistxattr "llistxattr"+ withCString path $ xAttrList llistxattr "llistxattr" --- | Get the list of attribute names associated with the given file descriptor.-fdListXAttr :: Fd -> IO [String]+-- |+-- @+-- >>> 'lListXAttr' "\/some\/link"+-- ["user.foo","user.bar"]+-- >>> 'lListUserXAttr' "\/some\/link"+-- ["foo","bar"]+-- @+lListUserXAttr :: FilePath -> IO [Name]+lListUserXAttr = userXAttrList lListXAttr++-- | Get the list of extended attribute @'Name'@s associated with the given file+-- descriptor in the filesystem.+fdListXAttr :: Fd -> IO [Name] fdListXAttr (Fd n) =- xAttrList c_flistxattr "flistxattr" n+ xAttrList flistxattr "flistxattr" n +-- |+-- @+-- >>> 'fdListXAttr' ('Fd' n)+-- ["user.foo","user.bar"]+-- >>> 'fdListUserXAttr' ('Fd' n)+-- ["foo","bar"]+-- @+fdListUserXAttr :: Fd -> IO [Name]+fdListUserXAttr = userXAttrList fdListXAttr -xAttrRemove :: String -> (a -> CString -> IO CInt) -> String -> a -> IO ()++xAttrRemove :: Name -> (a -> CString -> IO CInt) -> String -> a -> IO () xAttrRemove attr func name f = throwErrnoIfMinus1_ name $ withCString attr (func f) --- | Remove an extended attribute from the given @'FilePath'@.-removeXAttr :: FilePath -- ^ target file- -> String -- ^ name of the attribute- -> IO ()+-- | Remove the extended attribute identified by @'Name'@ and associated with+-- the given @'FilePath'@ in the filesystem, or fail with+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist.+removeXAttr :: FilePath -> Name -> IO () removeXAttr path attr =- withCString path $ xAttrRemove attr c_removexattr "removexattr"+ withCString path $ xAttrRemove attr removexattr "removexattr" --- | Remove an extended attribute from the given @'FilePath'@ (do not follow--- symbolic links).-lRemoveXAttr :: FilePath -> String -> IO ()+-- | @'removeUserXAttr' "\/some\/path" "foo" = 'removeXAttr' "\/some\/path" "user.foo"@+removeUserXAttr :: FilePath -> Name -> IO ()+removeUserXAttr = userXAttr removeXAttr++-- | Remove the extended attribute identified by @'Name'@ and associated with+-- the given @'FilePath'@ in the filesystem, or fail with+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist (do+-- not follow symbolic links).+lRemoveXAttr :: FilePath -> Name -> IO () lRemoveXAttr path attr =- withCString path $ xAttrRemove attr c_lremovexattr "lremovexattr"+ withCString path $ xAttrRemove attr lremovexattr "lremovexattr" --- | Remove an extended attribute from the given file descriptor.-fdRemoveXAttr :: Fd -> String -> IO ()+-- | @'lRemoveUserXAttr' "\/some\/link" "foo" = 'lRemoveXAttr' "\/some\/link" "user.foo"@+lRemoveUserXAttr :: FilePath -> Name -> IO ()+lRemoveUserXAttr = userXAttr lRemoveXAttr++-- | Remove the extended attribute identified by @'Name'@ and associated with+-- the given file descriptor in the filesystem, or fail with+-- @`System.IO.Error.isDoesNotExistError`@ if the attribute does not exist.+fdRemoveXAttr :: Fd -> Name -> IO () fdRemoveXAttr (Fd n) attr =- xAttrRemove attr c_fremovexattr "fremovexattr" n+ xAttrRemove attr fremovexattr "fremovexattr" n +-- | @'fdRemoveUserXAttr' ('Fd' n) "foo" = 'fdRemoveXAttr' ('Fd' n) "user.foo"@+fdRemoveUserXAttr :: Fd -> Name -> IO ()+fdRemoveUserXAttr = userXAttr fdRemoveXAttr -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+userXAttr :: (a -> Name -> b) -> a -> Name -> b+userXAttr func f name = func f ("user." ++ name) -foreign import ccall unsafe "fsetxattr" c_fsetxattr :: CInt- -> CString- -> Ptr ()- -> CSize- -> CInt- -> IO CInt+userXAttrList :: (a -> IO [Name]) -> a -> IO [Name]+userXAttrList func f = liftM unUser $ func f+ where unUser [] = []+ unUser (x:xs) = case splitAt 5 x of+ ("user.",attr) -> attr : unUser xs+ _ -> unUser xs -foreign import ccall unsafe "getxattr" c_getxattr :: CString- -> CString- -> Ptr ()- -> CSize- -> IO CSsize+foreign import ccall unsafe setxattr :: CString+ -> CString+ -> Ptr a+ -> CSize+ -> CInt+ -> IO CInt -foreign import ccall unsafe "lgetxattr" c_lgetxattr :: CString- -> CString- -> Ptr ()- -> CSize- -> IO CSsize+foreign import ccall unsafe lsetxattr :: CString+ -> CString+ -> Ptr a+ -> CSize+ -> CInt+ -> IO CInt -foreign import ccall unsafe "fgetxattr" c_fgetxattr :: CInt- -> CString- -> Ptr ()- -> CSize- -> IO CSsize+foreign import ccall unsafe fsetxattr :: CInt+ -> CString+ -> Ptr a+ -> CSize+ -> CInt+ -> IO CInt -foreign import ccall unsafe "listxattr" c_listxattr :: CString- -> CString- -> CSize- -> IO CSsize+foreign import ccall unsafe getxattr :: CString+ -> CString+ -> Ptr a+ -> CSize+ -> IO CSsize -foreign import ccall unsafe "llistxattr" c_llistxattr :: CString- -> CString- -> CSize- -> IO CSsize+foreign import ccall unsafe lgetxattr :: CString+ -> CString+ -> Ptr a+ -> CSize+ -> IO CSsize -foreign import ccall unsafe "flistxattr" c_flistxattr :: CInt- -> CString- -> CSize- -> IO CSsize+foreign import ccall unsafe fgetxattr :: CInt+ -> CString+ -> Ptr a+ -> CSize+ -> IO CSsize -foreign import ccall unsafe "removexattr" c_removexattr :: CString- -> CString- -> IO CInt+foreign import ccall unsafe listxattr :: CString+ -> CString+ -> CSize+ -> IO CSsize -foreign import ccall unsafe "lremovexattr" c_lremovexattr :: CString- -> CString- -> IO CInt+foreign import ccall unsafe llistxattr :: CString+ -> CString+ -> CSize+ -> IO CSsize -foreign import ccall unsafe "fremovexattr" c_fremovexattr :: CInt- -> CString- -> IO CInt+foreign import ccall unsafe flistxattr :: CInt+ -> CString+ -> CSize+ -> IO CSsize+++foreign import ccall unsafe removexattr :: CString+ -> CString+ -> IO CInt++foreign import ccall unsafe lremovexattr :: CString+ -> CString+ -> IO CInt++foreign import ccall unsafe fremovexattr :: CInt+ -> CString+ -> IO CInt
linux-xattr.cabal view
@@ -1,6 +1,6 @@ Name: linux-xattr-Version: 0.1.0.1-Cabal-Version: >= 1.8+Version: 0.1.1.0+Cabal-Version: >= 1.10 Build-Type: Simple License: BSD3 License-File: LICENSE@@ -14,7 +14,10 @@ Description: Bindings to the Linux syscalls for reading and manipulating extended- attributes (@setxattr@, @getxattr@, @listxattr@, ...).+ attributes (@<http://man7.org/linux/man-pages/man2/setxattr.2.html setxattr>@,+ @<http://man7.org/linux/man-pages/man2/getxattr.2.html getxattr>@,+ @<http://man7.org/linux/man-pages/man2/listxattr.2.html listxattr>@ and+ @<http://man7.org/linux/man-pages/man2/removexattr.2.html removexattr>@). Extra-Source-Files: CHANGELOG.md@@ -27,10 +30,12 @@ Source-Repository this Type: git Location: git://github.com/tensor5/linux-xattr.git- Tag: v0.1.0.1+ Tag: v0.1.1.0 Library- Build-Depends: base == 4.*,- bytestring == 0.10.*- Ghc-Options: -Wall- Exposed-Modules: System.Linux.XAttr+ Default-Language: Haskell2010+ Default-Extensions: Safe+ Build-Depends: base == 4.*,+ bytestring == 0.10.*+ Ghc-Options: -Wall+ Exposed-Modules: System.Linux.XAttr