aboutsummaryrefslogtreecommitdiffhomepage
path: root/System
diff options
context:
space:
mode:
authorGravatar Marios Titas <redneb@gmx.com>2012-06-13 02:52:03 -0400
committerGravatar Paolo Capriotti <p.capriotti@gmail.com>2012-07-17 16:42:13 +0100
commit9acb33c819356a49068ec041c38e438d335e9781 (patch)
tree470f4104a42dd64f2763aed6d34cea1d5611136c /System
parentba7961f118f42ba9db7e5fba017270a257852ff3 (diff)
Extract high resolution timestamps from FileStatus
Signed-off-by: Paolo Capriotti <p.capriotti@gmail.com>
Diffstat (limited to 'System')
-rw-r--r--System/Posix/Files.hsc1
-rw-r--r--System/Posix/Files/ByteString.hsc1
-rw-r--r--System/Posix/Files/Common.hsc78
3 files changed, 80 insertions, 0 deletions
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.