{-# LINE 1 "System/Posix/Files/Common.hsc" #-}
{-# LANGUAGE CApiFFI #-}
{-# LANGUAGE Trustworthy #-}
module System.Posix.Files.Common (
unionFileModes, intersectFileModes,
nullFileMode,
ownerReadMode, ownerWriteMode, ownerExecuteMode, ownerModes,
groupReadMode, groupWriteMode, groupExecuteMode, groupModes,
otherReadMode, otherWriteMode, otherExecuteMode, otherModes,
setUserIDMode, setGroupIDMode,
stdFileMode, accessModes,
fileTypeModes,
blockSpecialMode, characterSpecialMode, namedPipeMode, regularFileMode,
directoryMode, symbolicLinkMode, socketMode,
setFdMode, setFileCreationMask,
FileStatus(..),
getFdStatus,
deviceID, fileID, fileMode, linkCount, fileOwner, fileGroup,
specialDeviceID, fileSize, accessTime, modificationTime,
statusChangeTime,
accessTimeHiRes, modificationTimeHiRes, statusChangeTimeHiRes,
setFdTimesHiRes, touchFd,
isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile,
isDirectory, isSymbolicLink, isSocket,
fileBlockSize,
fileBlocks,
setFdSize,
setFdOwnerAndGroup,
PathVar(..), getFdPathVar, pathVarConst,
{-# LINE 74 "System/Posix/Files/Common.hsc" #-}
CTimeSpec(..),
toCTimeSpec,
c_utimensat,
{-# LINE 78 "System/Posix/Files/Common.hsc" #-}
CTimeVal(..),
toCTimeVal,
c_utimes,
{-# LINE 82 "System/Posix/Files/Common.hsc" #-}
c_lutimes,
{-# LINE 84 "System/Posix/Files/Common.hsc" #-}
) where
import System.Posix.Types
import System.IO.Unsafe
import Data.Bits
import Data.Int
import Data.Ratio
import Data.Time.Clock.POSIX (POSIXTime)
import System.Posix.Internals
import Foreign.C
import Foreign.ForeignPtr
{-# LINE 96 "System/Posix/Files/Common.hsc" #-}
import Foreign.Marshal (withArray)
{-# LINE 98 "System/Posix/Files/Common.hsc" #-}
import Foreign.Ptr
import Foreign.Storable
{-# LINE 105 "System/Posix/Files/Common.hsc" #-}
nullFileMode :: FileMode
nullFileMode = 0
ownerReadMode :: FileMode
ownerReadMode = (256)
{-# LINE 119 "System/Posix/Files/Common.hsc" #-}
ownerWriteMode :: FileMode
ownerWriteMode = (128)
{-# LINE 123 "System/Posix/Files/Common.hsc" #-}
ownerExecuteMode :: FileMode
ownerExecuteMode = (64)
{-# LINE 127 "System/Posix/Files/Common.hsc" #-}
groupReadMode :: FileMode
groupReadMode = (32)
{-# LINE 131 "System/Posix/Files/Common.hsc" #-}
groupWriteMode :: FileMode
groupWriteMode = (16)
{-# LINE 135 "System/Posix/Files/Common.hsc" #-}
groupExecuteMode :: FileMode
groupExecuteMode = (8)
{-# LINE 139 "System/Posix/Files/Common.hsc" #-}
otherReadMode :: FileMode
otherReadMode = (4)
{-# LINE 143 "System/Posix/Files/Common.hsc" #-}
otherWriteMode :: FileMode
otherWriteMode = (2)
{-# LINE 147 "System/Posix/Files/Common.hsc" #-}
otherExecuteMode :: FileMode
otherExecuteMode = (1)
{-# LINE 151 "System/Posix/Files/Common.hsc" #-}
setUserIDMode :: FileMode
setUserIDMode = (2048)
{-# LINE 155 "System/Posix/Files/Common.hsc" #-}
setGroupIDMode :: FileMode
setGroupIDMode = (1024)
{-# LINE 159 "System/Posix/Files/Common.hsc" #-}
stdFileMode :: FileMode
stdFileMode = ownerReadMode .|. ownerWriteMode .|.
groupReadMode .|. groupWriteMode .|.
otherReadMode .|. otherWriteMode
ownerModes :: FileMode
ownerModes = (448)
{-# LINE 169 "System/Posix/Files/Common.hsc" #-}
groupModes :: FileMode
groupModes = (56)
{-# LINE 173 "System/Posix/Files/Common.hsc" #-}
otherModes :: FileMode
otherModes = (7)
{-# LINE 177 "System/Posix/Files/Common.hsc" #-}
accessModes :: FileMode
accessModes = ownerModes .|. groupModes .|. otherModes
unionFileModes :: FileMode -> FileMode -> FileMode
unionFileModes m1 m2 = m1 .|. m2
intersectFileModes :: FileMode -> FileMode -> FileMode
intersectFileModes m1 m2 = m1 .&. m2
fileTypeModes :: FileMode
fileTypeModes = (61440)
{-# LINE 194 "System/Posix/Files/Common.hsc" #-}
blockSpecialMode :: FileMode
blockSpecialMode = (24576)
{-# LINE 197 "System/Posix/Files/Common.hsc" #-}
characterSpecialMode :: FileMode
characterSpecialMode = (8192)
{-# LINE 200 "System/Posix/Files/Common.hsc" #-}
namedPipeMode :: FileMode
namedPipeMode = (4096)
{-# LINE 203 "System/Posix/Files/Common.hsc" #-}
regularFileMode :: FileMode
regularFileMode = (32768)
{-# LINE 206 "System/Posix/Files/Common.hsc" #-}
directoryMode :: FileMode
directoryMode = (16384)
{-# LINE 209 "System/Posix/Files/Common.hsc" #-}
symbolicLinkMode :: FileMode
symbolicLinkMode = (40960)
{-# LINE 212 "System/Posix/Files/Common.hsc" #-}
socketMode :: FileMode
socketMode = (49152)
{-# LINE 215 "System/Posix/Files/Common.hsc" #-}
{-# LINE 217 "System/Posix/Files/Common.hsc" #-}
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
{-# LINE 236 "System/Posix/Files/Common.hsc" #-}
setFileCreationMask :: FileMode -> IO FileMode
setFileCreationMask mask = c_umask mask
newtype FileStatus = FileStatus (ForeignPtr CStat)
deviceID :: FileStatus -> DeviceID
fileID :: FileStatus -> FileID
fileMode :: FileStatus -> FileMode
linkCount :: FileStatus -> LinkCount
fileOwner :: FileStatus -> UserID
fileGroup :: FileStatus -> GroupID
specialDeviceID :: FileStatus -> DeviceID
fileSize :: FileStatus -> FileOffset
fileBlocks :: FileStatus -> Maybe CBlkCnt
fileBlockSize :: FileStatus -> Maybe CBlkSize
accessTime :: FileStatus -> EpochTime
accessTimeHiRes :: FileStatus -> POSIXTime
modificationTime :: FileStatus -> EpochTime
modificationTimeHiRes :: FileStatus -> POSIXTime
statusChangeTime :: FileStatus -> EpochTime
statusChangeTimeHiRes :: FileStatus -> POSIXTime
deviceID (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 0))
{-# LINE 303 "System/Posix/Files/Common.hsc" #-}
fileID (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 8))
{-# LINE 305 "System/Posix/Files/Common.hsc" #-}
fileMode (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 24))
{-# LINE 307 "System/Posix/Files/Common.hsc" #-}
linkCount (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 16))
{-# LINE 309 "System/Posix/Files/Common.hsc" #-}
fileOwner (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 28))
{-# LINE 311 "System/Posix/Files/Common.hsc" #-}
fileGroup (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 32))
{-# LINE 313 "System/Posix/Files/Common.hsc" #-}
specialDeviceID (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 40))
{-# LINE 315 "System/Posix/Files/Common.hsc" #-}
fileSize (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 48))
{-# LINE 317 "System/Posix/Files/Common.hsc" #-}
accessTime (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 72))
{-# LINE 319 "System/Posix/Files/Common.hsc" #-}
modificationTime (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 88))
{-# LINE 321 "System/Posix/Files/Common.hsc" #-}
statusChangeTime (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 104))
{-# LINE 323 "System/Posix/Files/Common.hsc" #-}
{-# LINE 325 "System/Posix/Files/Common.hsc" #-}
fileBlocks (FileStatus stat) =
Just $ unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 64))
{-# LINE 327 "System/Posix/Files/Common.hsc" #-}
{-# LINE 330 "System/Posix/Files/Common.hsc" #-}
{-# LINE 331 "System/Posix/Files/Common.hsc" #-}
fileBlockSize (FileStatus stat) =
Just $ unsafePerformIO $ withForeignPtr stat $ ((\hsc_ptr -> peekByteOff hsc_ptr 56))
{-# LINE 333 "System/Posix/Files/Common.hsc" #-}
{-# LINE 336 "System/Posix/Files/Common.hsc" #-}
accessTimeHiRes (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ \stat_ptr -> do
sec <- ((\hsc_ptr -> peekByteOff hsc_ptr 72)) stat_ptr :: IO EpochTime
{-# LINE 340 "System/Posix/Files/Common.hsc" #-}
{-# LINE 341 "System/Posix/Files/Common.hsc" #-}
nsec <- ((\hsc_ptr -> peekByteOff hsc_ptr 80)) stat_ptr :: IO (Int64)
{-# LINE 342 "System/Posix/Files/Common.hsc" #-}
let frac = toInteger nsec % 10^(9::Int)
{-# LINE 358 "System/Posix/Files/Common.hsc" #-}
return $ fromRational $ toRational sec + frac
modificationTimeHiRes (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ \stat_ptr -> do
sec <- ((\hsc_ptr -> peekByteOff hsc_ptr 88)) stat_ptr :: IO EpochTime
{-# LINE 363 "System/Posix/Files/Common.hsc" #-}
{-# LINE 364 "System/Posix/Files/Common.hsc" #-}
nsec <- ((\hsc_ptr -> peekByteOff hsc_ptr 96)) stat_ptr :: IO (Int64)
{-# LINE 365 "System/Posix/Files/Common.hsc" #-}
let frac = toInteger nsec % 10^(9::Int)
{-# LINE 381 "System/Posix/Files/Common.hsc" #-}
return $ fromRational $ toRational sec + frac
statusChangeTimeHiRes (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ \stat_ptr -> do
sec <- ((\hsc_ptr -> peekByteOff hsc_ptr 104)) stat_ptr :: IO EpochTime
{-# LINE 386 "System/Posix/Files/Common.hsc" #-}
{-# LINE 387 "System/Posix/Files/Common.hsc" #-}
nsec <- ((\hsc_ptr -> peekByteOff hsc_ptr 112)) stat_ptr :: IO (Int64)
{-# LINE 388 "System/Posix/Files/Common.hsc" #-}
let frac = toInteger nsec % 10^(9::Int)
{-# LINE 404 "System/Posix/Files/Common.hsc" #-}
return $ fromRational $ toRational sec + frac
isBlockDevice :: FileStatus -> Bool
isCharacterDevice :: FileStatus -> Bool
isNamedPipe :: FileStatus -> Bool
isRegularFile :: FileStatus -> Bool
isDirectory :: FileStatus -> Bool
isSymbolicLink :: FileStatus -> Bool
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
getFdStatus :: Fd -> IO FileStatus
getFdStatus (Fd fd) = do
fp <- mallocForeignPtrBytes (144)
{-# LINE 442 "System/Posix/Files/Common.hsc" #-}
withForeignPtr fp $ \p ->
throwErrnoIfMinus1_ "getFdStatus" (c_fstat fd p)
return (FileStatus fp)
{-# LINE 450 "System/Posix/Files/Common.hsc" #-}
data CTimeSpec = CTimeSpec EpochTime CLong
instance Storable CTimeSpec where
sizeOf _ = (16)
{-# LINE 454 "System/Posix/Files/Common.hsc" #-}
alignment _ = alignment (undefined :: CInt)
poke p (CTimeSpec sec nsec) = do
((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p sec
{-# LINE 457 "System/Posix/Files/Common.hsc" #-}
((\hsc_ptr -> pokeByteOff hsc_ptr 8)) p nsec
{-# LINE 458 "System/Posix/Files/Common.hsc" #-}
peek p = do
sec <- (\hsc_ptr -> peekByteOff hsc_ptr 0) p
{-# LINE 460 "System/Posix/Files/Common.hsc" #-}
nsec <- (\hsc_ptr -> peekByteOff hsc_ptr 8) p
{-# LINE 461 "System/Posix/Files/Common.hsc" #-}
return $ CTimeSpec sec nsec
toCTimeSpec :: POSIXTime -> CTimeSpec
toCTimeSpec t = CTimeSpec (CTime sec) (truncate $ 10^(9::Int) * frac)
where
(sec, frac) = if (frac' < 0) then (sec' - 1, frac' + 1) else (sec', frac')
(sec', frac') = properFraction $ toRational t
{-# LINE 469 "System/Posix/Files/Common.hsc" #-}
{-# LINE 471 "System/Posix/Files/Common.hsc" #-}
foreign import capi unsafe "sys/stat.h utimensat"
c_utimensat :: CInt -> CString -> Ptr CTimeSpec -> CInt -> IO CInt
{-# LINE 474 "System/Posix/Files/Common.hsc" #-}
{-# LINE 476 "System/Posix/Files/Common.hsc" #-}
foreign import capi unsafe "sys/stat.h futimens"
c_futimens :: CInt -> Ptr CTimeSpec -> IO CInt
{-# LINE 479 "System/Posix/Files/Common.hsc" #-}
data CTimeVal = CTimeVal CLong CLong
instance Storable CTimeVal where
sizeOf _ = (16)
{-# LINE 484 "System/Posix/Files/Common.hsc" #-}
alignment _ = alignment (undefined :: CInt)
poke p (CTimeVal sec usec) = do
((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p sec
{-# LINE 487 "System/Posix/Files/Common.hsc" #-}
((\hsc_ptr -> pokeByteOff hsc_ptr 8)) p usec
{-# LINE 488 "System/Posix/Files/Common.hsc" #-}
peek p = do
sec <- (\hsc_ptr -> peekByteOff hsc_ptr 0) p
{-# LINE 490 "System/Posix/Files/Common.hsc" #-}
usec <- (\hsc_ptr -> peekByteOff hsc_ptr 8) p
{-# LINE 491 "System/Posix/Files/Common.hsc" #-}
return $ CTimeVal sec usec
toCTimeVal :: POSIXTime -> CTimeVal
toCTimeVal t = CTimeVal sec (truncate $ 10^(6::Int) * frac)
where
(sec, frac) = if (frac' < 0) then (sec' - 1, frac' + 1) else (sec', frac')
(sec', frac') = properFraction $ toRational t
foreign import capi unsafe "sys/time.h utimes"
c_utimes :: CString -> Ptr CTimeVal -> IO CInt
{-# LINE 503 "System/Posix/Files/Common.hsc" #-}
foreign import capi unsafe "sys/time.h lutimes"
c_lutimes :: CString -> Ptr CTimeVal -> IO CInt
{-# LINE 506 "System/Posix/Files/Common.hsc" #-}
{-# LINE 508 "System/Posix/Files/Common.hsc" #-}
foreign import capi unsafe "sys/time.h futimes"
c_futimes :: CInt -> Ptr CTimeVal -> IO CInt
{-# LINE 511 "System/Posix/Files/Common.hsc" #-}
setFdTimesHiRes :: Fd -> POSIXTime -> POSIXTime -> IO ()
{-# LINE 525 "System/Posix/Files/Common.hsc" #-}
setFdTimesHiRes (Fd fd) atime mtime =
withArray [toCTimeSpec atime, toCTimeSpec mtime] $ \times ->
throwErrnoIfMinus1_ "setFdTimesHiRes" (c_futimens fd times)
{-# LINE 537 "System/Posix/Files/Common.hsc" #-}
touchFd :: Fd -> IO ()
{-# LINE 547 "System/Posix/Files/Common.hsc" #-}
touchFd (Fd fd) =
throwErrnoIfMinus1_ "touchFd" (c_futimes fd nullPtr)
{-# LINE 554 "System/Posix/Files/Common.hsc" #-}
{-# LINE 559 "System/Posix/Files/Common.hsc" #-}
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
{-# LINE 578 "System/Posix/Files/Common.hsc" #-}
setFdSize :: Fd -> FileOffset -> IO ()
setFdSize (Fd fd) off =
throwErrnoIfMinus1_ "setFdSize" (c_ftruncate fd off)
data PathVar
= FileSizeBits
| LinkLimit
| InputLineLimit
| InputQueueLimit
| FileNameLimit
| PathNameLimit
| PipeBufferLimit
| SymbolicLinkLimit
| SetOwnerAndGroupIsRestricted
| FileNamesAreNotTruncated
| VDisableChar
| AsyncIOAvailable
| PrioIOAvailable
| SyncIOAvailable
pathVarConst :: PathVar -> CInt
pathVarConst v = case v of
LinkLimit -> (0)
{-# LINE 617 "System/Posix/Files/Common.hsc" #-}
InputLineLimit -> (1)
{-# LINE 618 "System/Posix/Files/Common.hsc" #-}
InputQueueLimit -> (2)
{-# LINE 619 "System/Posix/Files/Common.hsc" #-}
FileNameLimit -> (3)
{-# LINE 620 "System/Posix/Files/Common.hsc" #-}
PathNameLimit -> (4)
{-# LINE 621 "System/Posix/Files/Common.hsc" #-}
PipeBufferLimit -> (5)
{-# LINE 622 "System/Posix/Files/Common.hsc" #-}
SetOwnerAndGroupIsRestricted -> (6)
{-# LINE 623 "System/Posix/Files/Common.hsc" #-}
FileNamesAreNotTruncated -> (7)
{-# LINE 624 "System/Posix/Files/Common.hsc" #-}
VDisableChar -> (8)
{-# LINE 625 "System/Posix/Files/Common.hsc" #-}
{-# LINE 627 "System/Posix/Files/Common.hsc" #-}
SyncIOAvailable -> (9)
{-# LINE 628 "System/Posix/Files/Common.hsc" #-}
{-# LINE 631 "System/Posix/Files/Common.hsc" #-}
{-# LINE 633 "System/Posix/Files/Common.hsc" #-}
AsyncIOAvailable -> (10)
{-# LINE 634 "System/Posix/Files/Common.hsc" #-}
{-# LINE 637 "System/Posix/Files/Common.hsc" #-}
{-# LINE 639 "System/Posix/Files/Common.hsc" #-}
PrioIOAvailable -> (11)
{-# LINE 640 "System/Posix/Files/Common.hsc" #-}
{-# LINE 643 "System/Posix/Files/Common.hsc" #-}
{-# LINE 647 "System/Posix/Files/Common.hsc" #-}
FileSizeBits -> error "_PC_FILESIZEBITS not available"
{-# LINE 649 "System/Posix/Files/Common.hsc" #-}
{-# LINE 653 "System/Posix/Files/Common.hsc" #-}
SymbolicLinkLimit -> error "_PC_SYMLINK_MAX not available"
{-# LINE 655 "System/Posix/Files/Common.hsc" #-}
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