packages feed

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 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