linuxhaskellfilesystemsfile-permissions

How can I check file permissions of a Linux file using Haskell?


How can I determine whether a file has write / read / executable permissions for the owner of a file?

I've found FileMode http://hackage.haskell.org/package/base-4.10.0.0/docs/System-Posix-Types.html#t:FileMode, but I can't seem to find a simple way to determine the permissions.


Solution

  • Well FileMode is a type alias for CMode with is a 32-bit number. The package further contains constants like ownerReadMode, ownerWriteMode, ownerExecuteMode; groupReadMode, groupWriteMode, groupExecuteMode; otherReadMode, otherWriteMode and otherExecuteMode.

    You can use intersectFileModes :: FileMode -> FileMode -> FileMode to determine the intersection. If the intersection with one of the constants is the same as that constant, then the file has that mode.

    For example:

    import System.Posix.Files(getFileStatus,fileMode,ownerReadMode)
    import System.Posix.Files.ByteString(intersectFileModes)
    
    main = do
        fs <- getFileStatus "foo.file"
        if intersectFileModes (fileMode fs) ownerReadMode == ownerReadMode
            then print "owner can read"
            else print "owner can not read"
    

    To make it more convenient, we can define a function:

    import System.Posix.Types(FileMode)
    import System.Posix.Files.ByteString(intersectFileModes)
    
    hasMode :: FileMode -> FileMode -> Bool
    hasMode fa fb = intersectFileModes fa fb == fa
    

    So then function hasMode ownerReadMode will check a filemode and return True if the filemode contains that permission, otherwise False.

    Now we can rewrite the above program as:

    import System.Posix.Types(FileMode)
    import System.Posix.Files(getFileStatus,fileMode,ownerReadMode)
    import System.Posix.Files.ByteString(intersectFileModes)
    
    hasMode :: FileMode -> FileMode -> Bool
    hasMode fa fb = intersectFileModes fa fb == fa
    
    main = do
        fs <- getFileStatus "../README.md"
        if hasMode ownerReadMode (fileMode fs)
            then print "owner can read"
            else print "owner can not read"