+{- |The 'getPermissions' operation returns the
+permissions for the file or directory.
+
+The operation may fail with:
+
+* 'isPermissionError' if the user is not permitted to access
+ the permissions; or
+
+* 'isDoesNotExistError' if the file or directory does not exist.
+
+-}
+
+getPermissions :: FilePath -> IO Permissions
+getPermissions name = do
+ withCString name $ \s -> do
+ read <- c_access s r_OK
+ write <- c_access s w_OK
+ exec <- c_access s x_OK
+ withFileStatus "getPermissions" name $ \st -> do
+ is_dir <- isDirectory st
+ return (
+ Permissions {
+ readable = read == 0,
+ writable = write == 0,
+ executable = not is_dir && exec == 0,
+ searchable = is_dir && exec == 0
+ }
+ )
+
+{- |The 'setPermissions' operation sets the
+permissions for the file or directory.
+
+The operation may fail with:
+
+* 'isPermissionError' if the user is not permitted to set
+ the permissions; or
+
+* 'isDoesNotExistError' if the file or directory does not exist.
+
+-}
+
+setPermissions :: FilePath -> Permissions -> IO ()
+setPermissions name (Permissions r w e s) = do
+ allocaBytes sizeof_stat $ \ p_stat -> do
+ withCString name $ \p_name -> do
+ throwErrnoIfMinus1_ "setPermissions" $ do
+ c_stat p_name p_stat
+ mode <- st_mode p_stat
+ let mode1 = modifyBit r mode s_IRUSR
+ let mode2 = modifyBit w mode1 s_IWUSR
+ let mode3 = modifyBit (e || s) mode2 s_IXUSR
+ c_chmod p_name mode3
+
+ where
+ modifyBit :: Bool -> CMode -> CMode -> CMode
+ modifyBit False m b = m .&. (complement b)
+ modifyBit True m b = m .|. b
+