summaryrefslogtreecommitdiff
path: root/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'Utility')
-rw-r--r--Utility/FileSize.hs33
-rw-r--r--Utility/InodeCache.hs3
-rw-r--r--Utility/Url.hs7
3 files changed, 41 insertions, 2 deletions
diff --git a/Utility/FileSize.hs b/Utility/FileSize.hs
new file mode 100644
index 000000000..3113695d3
--- /dev/null
+++ b/Utility/FileSize.hs
@@ -0,0 +1,33 @@
+{- File size.
+ -
+ - License: BSD-2-clause
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.FileSize where
+
+import System.PosixCompat.Files
+import Control.Exception (bracket)
+import System.IO
+
+{- Gets the size of a file.
+ -
+ - This is better than using fileSize, because on Windows that returns a
+ - FileOffset which maxes out at 2 gb.
+ - See https://github.com/jystic/unix-compat/issues/16
+ -}
+getFileSize :: FilePath -> IO Integer
+#ifndef mingw32_HOST_OS
+getFileSize f = fromIntegral . fileSize <$> getFileStatus f
+#else
+getFileSize f = bracket (openFile f ReadMode) hClose hFileSize
+#endif
+
+{- Gets the size of the file, when its FileStatus is already known. -}
+getFileSize' :: FilePath -> FileStatus -> IO Integer
+#ifndef mingw32_HOST_OS
+getFileSize' _ s = return $ fromIntegral $ fileSize s
+#else
+getFileSize' f _ = getFileSize f
+#endif
diff --git a/Utility/InodeCache.hs b/Utility/InodeCache.hs
index 8a182449b..0b0b040cb 100644
--- a/Utility/InodeCache.hs
+++ b/Utility/InodeCache.hs
@@ -40,6 +40,9 @@ module Utility.InodeCache (
import Common
import System.PosixCompat.Types
import Utility.QuickCheck
+-- While fileSize overflows and wraps at 2gb on Windows,
+-- it's ok for purposes of comparison.
+import System.PosixCompat.Files (fileSize)
#ifdef mingw32_HOST_OS
import Data.Word (Word64)
diff --git a/Utility/Url.hs b/Utility/Url.hs
index cc15c82d0..a8828e048 100644
--- a/Utility/Url.hs
+++ b/Utility/Url.hs
@@ -102,9 +102,12 @@ exists url uo = case parseURIRelaxed url of
-- so fall back to reading files and using curl.
Nothing
| uriScheme u == "file:" -> do
- s <- catchMaybeIO $ getFileStatus (unEscapeString $ uriPath u)
+ let f = unEscapeString (uriPath u)
+ s <- catchMaybeIO $ getFileStatus f
case s of
- Just stat -> return (True, Just $ fromIntegral $ fileSize stat)
+ Just stat -> do
+ sz <- getFileSize' f stat
+ return (True, Just sz)
Nothing -> dne
| Build.SysConfig.curl -> do
output <- catchDefaultIO "" $