From 9acb33c819356a49068ec041c38e438d335e9781 Mon Sep 17 00:00:00 2001 From: Marios Titas Date: Wed, 13 Jun 2012 02:52:03 -0400 Subject: Extract high resolution timestamps from FileStatus Signed-off-by: Paolo Capriotti --- System/Posix/Files.hsc | 1 + System/Posix/Files/ByteString.hsc | 1 + System/Posix/Files/Common.hsc | 78 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) (limited to 'System') diff --git a/System/Posix/Files.hsc b/System/Posix/Files.hsc index 5916d1a..cb9663c 100644 --- a/System/Posix/Files.hsc +++ b/System/Posix/Files.hsc @@ -57,6 +57,7 @@ module System.Posix.Files ( deviceID, fileID, fileMode, linkCount, fileOwner, fileGroup, specialDeviceID, fileSize, accessTime, modificationTime, statusChangeTime, + accessTimeHiRes, modificationTimeHiRes, statusChangeTimeHiRes, isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile, isDirectory, isSymbolicLink, isSocket, diff --git a/System/Posix/Files/ByteString.hsc b/System/Posix/Files/ByteString.hsc index 5853ab9..cb183ff 100644 --- a/System/Posix/Files/ByteString.hsc +++ b/System/Posix/Files/ByteString.hsc @@ -55,6 +55,7 @@ module System.Posix.Files.ByteString ( deviceID, fileID, fileMode, linkCount, fileOwner, fileGroup, specialDeviceID, fileSize, accessTime, modificationTime, statusChangeTime, + accessTimeHiRes, modificationTimeHiRes, statusChangeTimeHiRes, isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile, isDirectory, isSymbolicLink, isSocket, diff --git a/System/Posix/Files/Common.hsc b/System/Posix/Files/Common.hsc index 2894244..01f9fb3 100644 --- a/System/Posix/Files/Common.hsc +++ b/System/Posix/Files/Common.hsc @@ -54,6 +54,7 @@ module System.Posix.Files.Common ( deviceID, fileID, fileMode, linkCount, fileOwner, fileGroup, specialDeviceID, fileSize, accessTime, modificationTime, statusChangeTime, + accessTimeHiRes, modificationTimeHiRes, statusChangeTimeHiRes, isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile, isDirectory, isSymbolicLink, isSocket, @@ -71,6 +72,8 @@ import System.Posix.Error import System.Posix.Types import System.IO.Unsafe import Data.Bits +import Data.Time.Clock.POSIX +import Data.Ratio import System.Posix.Internals import Foreign hiding (unsafePerformIO) import Foreign.C @@ -233,10 +236,16 @@ specialDeviceID :: FileStatus -> DeviceID fileSize :: FileStatus -> FileOffset -- | Time of last access. accessTime :: FileStatus -> EpochTime +-- | Time of last access in sub-second resolution. +accessTimeHiRes :: FileStatus -> POSIXTime -- | Time of last modification. modificationTime :: FileStatus -> EpochTime +-- | Time of last modification in sub-second resolution. +modificationTimeHiRes :: FileStatus -> POSIXTime -- | Time of last status change (i.e. owner, group, link count, mode, etc.). statusChangeTime :: FileStatus -> EpochTime +-- | Time of last status change (i.e. owner, group, link count, mode, etc.) in sub-second resolution. +statusChangeTimeHiRes :: FileStatus -> POSIXTime deviceID (FileStatus stat) = unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_dev) @@ -261,6 +270,75 @@ modificationTime (FileStatus stat) = statusChangeTime (FileStatus stat) = unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_ctime) +accessTimeHiRes (FileStatus stat) = + unsafePerformIO $ withForeignPtr stat $ \stat -> do + sec <- (#peek struct stat, st_atime) stat :: IO EpochTime +#ifdef HAVE_STRUCT_STAT_ST_ATIM + nsec <- (#peek struct stat, st_atim.tv_nsec) stat :: IO (#type long) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_ATIMESPEC + nsec <- (#peek struct stat, st_atimespec.tv_nsec) stat :: IO (#type long) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_ATIMENSEC + nsec <- (#peek struct stat, st_atimensec) stat :: IO (#type long) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_ATIME_N + nsec <- (#peek struct stat, st_atime_n) stat :: IO (#type int) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_UATIME + usec <- (#peek struct stat, st_uatime) stat :: IO (#type int) + let frac = toInteger usec % 10^6 +#else + let frac = 0 +#endif + return $ fromRational $ toRational sec + frac + +modificationTimeHiRes (FileStatus stat) = + unsafePerformIO $ withForeignPtr stat $ \stat -> do + sec <- (#peek struct stat, st_mtime) stat :: IO EpochTime +#ifdef HAVE_STRUCT_STAT_ST_MTIM + nsec <- (#peek struct stat, st_mtim.tv_nsec) stat :: IO (#type long) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_MTIMESPEC + nsec <- (#peek struct stat, st_mtimespec.tv_nsec) stat :: IO (#type long) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_MTIMENSEC + nsec <- (#peek struct stat, st_mtimensec) stat :: IO (#type long) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_MTIME_N + nsec <- (#peek struct stat, st_mtime_n) stat :: IO (#type int) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_UMTIME + usec <- (#peek struct stat, st_umtime) stat :: IO (#type int) + let frac = toInteger usec % 10^6 +#else + let frac = 0 +#endif + return $ fromRational $ toRational sec + frac + +statusChangeTimeHiRes (FileStatus stat) = + unsafePerformIO $ withForeignPtr stat $ \stat -> do + sec <- (#peek struct stat, st_ctime) stat :: IO EpochTime +#ifdef HAVE_STRUCT_STAT_ST_CTIM + nsec <- (#peek struct stat, st_ctim.tv_nsec) stat :: IO (#type long) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_CTIMESPEC + nsec <- (#peek struct stat, st_ctimespec.tv_nsec) stat :: IO (#type long) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_CTIMENSEC + nsec <- (#peek struct stat, st_ctimensec) stat :: IO (#type long) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_CTIME_N + nsec <- (#peek struct stat, st_ctime_n) stat :: IO (#type int) + let frac = toInteger nsec % 10^9 +#elif HAVE_STRUCT_STAT_ST_UCTIME + usec <- (#peek struct stat, st_uctime) stat :: IO (#type int) + let frac = toInteger usec % 10^6 +#else + let frac = 0 +#endif + return $ fromRational $ toRational sec + frac + -- | Checks if this file is a block device. isBlockDevice :: FileStatus -> Bool -- | Checks if this file is a character device. -- cgit v1.2.3