diff options
author | Simon Marlow <marlowsd@gmail.com> | 2011-11-11 16:18:48 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2011-11-22 12:36:48 +0000 |
commit | 34c7bf896f19b182cf6fa104e057f1df9df1254a (patch) | |
tree | abdb8264ae52c62263fc0fb4b395906a64acb104 /System/Posix/Files.hsc | |
parent | c213ae2ec6d9c71266aebc8e5b2326a9625fba7a (diff) |
Provide a raw ByteString version of FilePath and environment APIs
The new module System.Posix.ByteString provides exactly the same API
as System.Posix, except that:
- There is a new type: RawFilePath = ByteString
- All functions mentioning FilePath in the System.Posix API
use RawFilePath in the System.Posix.ByteString API
- RawFilePaths are not subject to Unicode locale encoding and
decoding, unlike FilePaths. They are the exact bytes passed to and
returned from the underlying POSIX API.
- Similarly for functions that deal in environment
strings (System.Posix.Env): these use untranslated ByteStrings
in System.Posix.Environment
- There is a new function
System.Posix.ByteString.getArgs :: [ByteString]
returning the raw untranslated arguments as passed to exec() when
the program was started.
Diffstat (limited to 'System/Posix/Files.hsc')
-rw-r--r-- | System/Posix/Files.hsc | 337 |
1 files changed, 9 insertions, 328 deletions
diff --git a/System/Posix/Files.hsc b/System/Posix/Files.hsc index 5606388..5916d1a 100644 --- a/System/Posix/Files.hsc +++ b/System/Posix/Files.hsc @@ -89,13 +89,15 @@ module System.Posix.Files ( PathVar(..), getPathVar, getFdPathVar, ) where + +import Foreign +import Foreign.C + import System.Posix.Error import System.Posix.Types -import System.IO.Unsafe -import Data.Bits import System.Posix.Internals -import Foreign hiding (unsafePerformIO) -import Foreign.C +import System.Posix.Files.Common + #if __GLASGOW_HASKELL__ > 700 import System.Posix.Internals (withFilePath, peekFilePath) #elif __GLASGOW_HASKELL__ > 611 @@ -118,114 +120,7 @@ peekFilePathLen = peekCStringLen #endif -- ----------------------------------------------------------------------------- --- POSIX file modes - --- The abstract type 'FileMode', constants and operators for --- manipulating the file modes defined by POSIX. - --- | No permissions. -nullFileMode :: FileMode -nullFileMode = 0 - --- | Owner has read permission. -ownerReadMode :: FileMode -ownerReadMode = (#const S_IRUSR) - --- | Owner has write permission. -ownerWriteMode :: FileMode -ownerWriteMode = (#const S_IWUSR) - --- | Owner has execute permission. -ownerExecuteMode :: FileMode -ownerExecuteMode = (#const S_IXUSR) - --- | Group has read permission. -groupReadMode :: FileMode -groupReadMode = (#const S_IRGRP) - --- | Group has write permission. -groupWriteMode :: FileMode -groupWriteMode = (#const S_IWGRP) - --- | Group has execute permission. -groupExecuteMode :: FileMode -groupExecuteMode = (#const S_IXGRP) - --- | Others have read permission. -otherReadMode :: FileMode -otherReadMode = (#const S_IROTH) - --- | Others have write permission. -otherWriteMode :: FileMode -otherWriteMode = (#const S_IWOTH) - --- | Others have execute permission. -otherExecuteMode :: FileMode -otherExecuteMode = (#const S_IXOTH) - --- | Set user ID on execution. -setUserIDMode :: FileMode -setUserIDMode = (#const S_ISUID) - --- | Set group ID on execution. -setGroupIDMode :: FileMode -setGroupIDMode = (#const S_ISGID) - --- | Owner, group and others have read and write permission. -stdFileMode :: FileMode -stdFileMode = ownerReadMode .|. ownerWriteMode .|. - groupReadMode .|. groupWriteMode .|. - otherReadMode .|. otherWriteMode - --- | Owner has read, write and execute permission. -ownerModes :: FileMode -ownerModes = (#const S_IRWXU) - --- | Group has read, write and execute permission. -groupModes :: FileMode -groupModes = (#const S_IRWXG) - --- | Others have read, write and execute permission. -otherModes :: FileMode -otherModes = (#const S_IRWXO) - --- | Owner, group and others have read, write and execute permission. -accessModes :: FileMode -accessModes = ownerModes .|. groupModes .|. otherModes - --- | Combines the two file modes into one that contains modes that appear in --- either. -unionFileModes :: FileMode -> FileMode -> FileMode -unionFileModes m1 m2 = m1 .|. m2 - --- | Combines two file modes into one that only contains modes that appear in --- both. -intersectFileModes :: FileMode -> FileMode -> FileMode -intersectFileModes m1 m2 = m1 .&. m2 - -fileTypeModes :: FileMode -fileTypeModes = (#const S_IFMT) - -blockSpecialMode :: FileMode -blockSpecialMode = (#const S_IFBLK) - -characterSpecialMode :: FileMode -characterSpecialMode = (#const S_IFCHR) - -namedPipeMode :: FileMode -namedPipeMode = (#const S_IFIFO) - -regularFileMode :: FileMode -regularFileMode = (#const S_IFREG) - -directoryMode :: FileMode -directoryMode = (#const S_IFDIR) - -symbolicLinkMode :: FileMode -symbolicLinkMode = (#const S_IFLNK) - -socketMode :: FileMode -socketMode = (#const S_IFSOCK) +-- chmod() -- | @setFileMode path mode@ changes permission of the file given by @path@ -- to @mode@. This operation may fail with 'throwErrnoPathIfMinus1_' if @path@ @@ -238,25 +133,6 @@ setFileMode name m = withFilePath name $ \s -> do throwErrnoPathIfMinus1_ "setFileMode" name (c_chmod s m) --- | @setFdMode fd mode@ acts like 'setFileMode' but uses a file descriptor --- @fd@ instead of a 'FilePath'. --- --- Note: calls @fchmod@. -setFdMode :: Fd -> FileMode -> IO () -setFdMode (Fd fd) m = - throwErrnoIfMinus1_ "setFdMode" (c_fchmod fd m) - -foreign import ccall unsafe "fchmod" - c_fchmod :: CInt -> CMode -> IO CInt - --- | @setFileCreationMask mode@ sets the file mode creation mask to @mode@. --- Modes set by this operation are subtracted from files and directories upon --- creation. The previous file creation mask is returned. --- --- Note: calls @umask@. -setFileCreationMask :: FileMode -> IO FileMode -setFileCreationMask mask = c_umask mask - -- ----------------------------------------------------------------------------- -- access() @@ -298,92 +174,6 @@ access name flags = then return False else throwErrnoPath "fileAccess" name --- ----------------------------------------------------------------------------- --- stat() support - --- | POSIX defines operations to get information, such as owner, permissions, --- size and access times, about a file. This information is represented by the --- 'FileStatus' type. --- --- Note: see @chmod@. -newtype FileStatus = FileStatus (ForeignPtr CStat) - --- | ID of the device on which this file resides. -deviceID :: FileStatus -> DeviceID --- | inode number -fileID :: FileStatus -> FileID --- | File mode (such as permissions). -fileMode :: FileStatus -> FileMode --- | Number of hard links to this file. -linkCount :: FileStatus -> LinkCount --- | ID of owner. -fileOwner :: FileStatus -> UserID --- | ID of group. -fileGroup :: FileStatus -> GroupID --- | Describes the device that this file represents. -specialDeviceID :: FileStatus -> DeviceID --- | Size of the file in bytes. If this file is a symbolic link the size is --- the length of the pathname it contains. -fileSize :: FileStatus -> FileOffset --- | Time of last access. -accessTime :: FileStatus -> EpochTime --- | Time of last modification. -modificationTime :: FileStatus -> EpochTime --- | Time of last status change (i.e. owner, group, link count, mode, etc.). -statusChangeTime :: FileStatus -> EpochTime - -deviceID (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_dev) -fileID (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_ino) -fileMode (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_mode) -linkCount (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_nlink) -fileOwner (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_uid) -fileGroup (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_gid) -specialDeviceID (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_rdev) -fileSize (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_size) -accessTime (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_atime) -modificationTime (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_mtime) -statusChangeTime (FileStatus stat) = - unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_ctime) - --- | Checks if this file is a block device. -isBlockDevice :: FileStatus -> Bool --- | Checks if this file is a character device. -isCharacterDevice :: FileStatus -> Bool --- | Checks if this file is a named pipe device. -isNamedPipe :: FileStatus -> Bool --- | Checks if this file is a regular file device. -isRegularFile :: FileStatus -> Bool --- | Checks if this file is a directory device. -isDirectory :: FileStatus -> Bool --- | Checks if this file is a symbolic link device. -isSymbolicLink :: FileStatus -> Bool --- | Checks if this file is a socket device. -isSocket :: FileStatus -> Bool - -isBlockDevice stat = - (fileMode stat `intersectFileModes` fileTypeModes) == blockSpecialMode -isCharacterDevice stat = - (fileMode stat `intersectFileModes` fileTypeModes) == characterSpecialMode -isNamedPipe stat = - (fileMode stat `intersectFileModes` fileTypeModes) == namedPipeMode -isRegularFile stat = - (fileMode stat `intersectFileModes` fileTypeModes) == regularFileMode -isDirectory stat = - (fileMode stat `intersectFileModes` fileTypeModes) == directoryMode -isSymbolicLink stat = - (fileMode stat `intersectFileModes` fileTypeModes) == symbolicLinkMode -isSocket stat = - (fileMode stat `intersectFileModes` fileTypeModes) == socketMode -- | @getFileStatus path@ calls gets the @FileStatus@ information (user ID, -- size, access times, etc.) for the file @path@. @@ -397,16 +187,6 @@ getFileStatus path = do throwErrnoPathIfMinus1_ "getFileStatus" path (c_stat s p) return (FileStatus fp) --- | @getFdStatus fd@ acts as 'getFileStatus' but uses a file descriptor @fd@. --- --- Note: calls @fstat@. -getFdStatus :: Fd -> IO FileStatus -getFdStatus (Fd fd) = do - fp <- mallocForeignPtrBytes (#const sizeof(struct stat)) - withForeignPtr fp $ \p -> - throwErrnoIfMinus1_ "getFdStatus" (c_fstat fd p) - return (FileStatus fp) - -- | Acts as 'getFileStatus' except when the 'FilePath' refers to a symbolic -- link. In that case the @FileStatus@ information of the symbolic link itself -- is returned instead of that of the file it points to. @@ -420,10 +200,10 @@ getSymbolicLinkStatus path = do throwErrnoPathIfMinus1_ "getSymbolicLinkStatus" path (c_lstat s p) return (FileStatus fp) -foreign import ccall unsafe "__hsunix_lstat" +foreign import ccall unsafe "__hsunix_lstat" c_lstat :: CString -> Ptr CStat -> IO CInt --- | @createNamedPipe fifo mode@ +-- | @createNamedPipe fifo mode@ -- creates a new named pipe, @fifo@, with permissions based on -- @mode@. May fail with 'throwErrnoPathIfMinus1_' if a file named @name@ -- already exists or if the effective user ID of the current process doesn't @@ -546,17 +326,6 @@ setOwnerAndGroup name uid gid = do foreign import ccall unsafe "chown" c_chown :: CString -> CUid -> CGid -> IO CInt --- | Acts as 'setOwnerAndGroup' but uses a file descriptor instead of a --- 'FilePath'. --- --- Note: calls @fchown@. -setFdOwnerAndGroup :: Fd -> UserID -> GroupID -> IO () -setFdOwnerAndGroup (Fd fd) uid gid = - throwErrnoIfMinus1_ "setFdOwnerAndGroup" (c_fchown fd uid gid) - -foreign import ccall unsafe "fchown" - c_fchown :: CInt -> CUid -> CGid -> IO CInt - #if HAVE_LCHOWN -- | Acts as 'setOwnerAndGroup' but does not follow symlinks (and thus -- changes permissions on the link itself). @@ -611,81 +380,9 @@ setFileSize file off = foreign import ccall unsafe "truncate" c_truncate :: CString -> COff -> IO CInt --- | Acts as 'setFileSize' but uses a file descriptor instead of a 'FilePath'. --- --- Note: calls @ftruncate@. -setFdSize :: Fd -> FileOffset -> IO () -setFdSize (Fd fd) off = - throwErrnoIfMinus1_ "setFdSize" (c_ftruncate fd off) - -- ----------------------------------------------------------------------------- -- pathconf()/fpathconf() support -data PathVar - = FileSizeBits {- _PC_FILESIZEBITS -} - | LinkLimit {- _PC_LINK_MAX -} - | InputLineLimit {- _PC_MAX_CANON -} - | InputQueueLimit {- _PC_MAX_INPUT -} - | FileNameLimit {- _PC_NAME_MAX -} - | PathNameLimit {- _PC_PATH_MAX -} - | PipeBufferLimit {- _PC_PIPE_BUF -} - -- These are described as optional in POSIX: - {- _PC_ALLOC_SIZE_MIN -} - {- _PC_REC_INCR_XFER_SIZE -} - {- _PC_REC_MAX_XFER_SIZE -} - {- _PC_REC_MIN_XFER_SIZE -} - {- _PC_REC_XFER_ALIGN -} - | SymbolicLinkLimit {- _PC_SYMLINK_MAX -} - | SetOwnerAndGroupIsRestricted {- _PC_CHOWN_RESTRICTED -} - | FileNamesAreNotTruncated {- _PC_NO_TRUNC -} - | VDisableChar {- _PC_VDISABLE -} - | AsyncIOAvailable {- _PC_ASYNC_IO -} - | PrioIOAvailable {- _PC_PRIO_IO -} - | SyncIOAvailable {- _PC_SYNC_IO -} - -pathVarConst :: PathVar -> CInt -pathVarConst v = case v of - LinkLimit -> (#const _PC_LINK_MAX) - InputLineLimit -> (#const _PC_MAX_CANON) - InputQueueLimit -> (#const _PC_MAX_INPUT) - FileNameLimit -> (#const _PC_NAME_MAX) - PathNameLimit -> (#const _PC_PATH_MAX) - PipeBufferLimit -> (#const _PC_PIPE_BUF) - SetOwnerAndGroupIsRestricted -> (#const _PC_CHOWN_RESTRICTED) - FileNamesAreNotTruncated -> (#const _PC_NO_TRUNC) - VDisableChar -> (#const _PC_VDISABLE) - -#ifdef _PC_SYNC_IO - SyncIOAvailable -> (#const _PC_SYNC_IO) -#else - SyncIOAvailable -> error "_PC_SYNC_IO not available" -#endif - -#ifdef _PC_ASYNC_IO - AsyncIOAvailable -> (#const _PC_ASYNC_IO) -#else - AsyncIOAvailable -> error "_PC_ASYNC_IO not available" -#endif - -#ifdef _PC_PRIO_IO - PrioIOAvailable -> (#const _PC_PRIO_IO) -#else - PrioIOAvailable -> error "_PC_PRIO_IO not available" -#endif - -#if _PC_FILESIZEBITS - FileSizeBits -> (#const _PC_FILESIZEBITS) -#else - FileSizeBits -> error "_PC_FILESIZEBITS not available" -#endif - -#if _PC_SYMLINK_MAX - SymbolicLinkLimit -> (#const _PC_SYMLINK_MAX) -#else - SymbolicLinkLimit -> error "_PC_SYMLINK_MAX not available" -#endif - - -- | @getPathVar var path@ obtains the dynamic value of the requested -- configurable file limit or option associated with file or directory @path@. -- For defined file limits, @getPathVar@ returns the associated @@ -701,19 +398,3 @@ getPathVar name v = do foreign import ccall unsafe "pathconf" c_pathconf :: CString -> CInt -> IO CLong - - --- | @getFdPathVar var fd@ obtains the dynamic value of the requested --- configurable file limit or option associated with the file or directory --- attached to the open channel @fd@. For defined file limits, @getFdPathVar@ --- returns the associated value. For defined file options, the result of --- @getFdPathVar@ is undefined, but not failure. --- --- Note: calls @fpathconf@. -getFdPathVar :: Fd -> PathVar -> IO Limit -getFdPathVar (Fd fd) v = - throwErrnoIfMinus1 "getFdPathVar" $ - c_fpathconf fd (pathVarConst v) - -foreign import ccall unsafe "fpathconf" - c_fpathconf :: CInt -> CInt -> IO CLong |