summaryrefslogtreecommitdiff
path: root/compiler/GHC/SysTools.hs
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2021-05-20 20:10:26 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-05-21 06:24:44 -0400
commit6eed426bf24fe4ddc4c4802ff44b949e74f9d7ee (patch)
treec6517e8aa2df1f780bb5f64e75921ede319ba9b2 /compiler/GHC/SysTools.hs
parentf5f741673079ea58d204acea8dd363dd300b157e (diff)
downloadhaskell-6eed426bf24fe4ddc4c4802ff44b949e74f9d7ee.tar.gz
SysTools: make file copy more efficient
Diffstat (limited to 'compiler/GHC/SysTools.hs')
-rw-r--r--compiler/GHC/SysTools.hs62
1 files changed, 32 insertions, 30 deletions
diff --git a/compiler/GHC/SysTools.hs b/compiler/GHC/SysTools.hs
index 36f924bf90..0b19d50825 100644
--- a/compiler/GHC/SysTools.hs
+++ b/compiler/GHC/SysTools.hs
@@ -20,7 +20,9 @@ module GHC.SysTools (
module GHC.SysTools.Tasks,
module GHC.SysTools.Info,
- copy,
+ -- * Fast file copy
+ copyFile,
+ copyHandle,
copyWithHeader,
-- * General utilities
@@ -32,21 +34,22 @@ import GHC.Prelude
import GHC.Settings.Utils
-import GHC.Utils.Error
import GHC.Utils.Panic
-import GHC.Utils.Logger
import GHC.Driver.Session
-import Control.Monad.Trans.Except (runExceptT)
-import System.FilePath
-import System.IO
-import System.IO.Unsafe (unsafeInterleaveIO)
import GHC.Linker.ExtraObj
import GHC.SysTools.Info
import GHC.SysTools.Tasks
import GHC.SysTools.BaseDir
import GHC.Settings.IO
+import Control.Monad.Trans.Except (runExceptT)
+import System.FilePath
+import System.IO
+import System.IO.Unsafe (unsafeInterleaveIO)
+import Foreign.Marshal.Alloc (allocaBytes)
+import System.Directory (copyFile)
+
{-
Note [How GHC finds toolchain utilities]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -184,26 +187,25 @@ for more information.
-}
-copy :: Logger -> DynFlags -> String -> FilePath -> FilePath -> IO ()
-copy logger dflags purpose from to = copyWithHeader logger dflags purpose Nothing from to
-
-copyWithHeader :: Logger -> DynFlags -> String -> Maybe String -> FilePath -> FilePath
- -> IO ()
-copyWithHeader logger dflags purpose maybe_header from to = do
- showPass logger dflags purpose
-
- hout <- openBinaryFile to WriteMode
- hin <- openBinaryFile from ReadMode
- ls <- hGetContents hin -- inefficient, but it'll do for now. ToDo: speed up
- maybe (return ()) (header hout) maybe_header
- hPutStr hout ls
- hClose hout
- hClose hin
- where
- -- write the header string in UTF-8. The header is something like
- -- {-# LINE "foo.hs" #-}
- -- and we want to make sure a Unicode filename isn't mangled.
- header h str = do
- hSetEncoding h utf8
- hPutStr h str
- hSetBinaryMode h True
+-- | Copy remaining bytes from the first Handle to the second one
+copyHandle :: Handle -> Handle -> IO ()
+copyHandle hin hout = do
+ let buf_size = 8192
+ allocaBytes buf_size $ \ptr -> do
+ let go = do
+ c <- hGetBuf hin ptr buf_size
+ hPutBuf hout ptr c
+ if c == 0 then return () else go
+ go
+
+-- | Copy file after printing the given header
+copyWithHeader :: String -> FilePath -> FilePath -> IO ()
+copyWithHeader header from to =
+ withBinaryFile to WriteMode $ \hout -> do
+ -- write the header string in UTF-8. The header is something like
+ -- {-# LINE "foo.hs" #-}
+ -- and we want to make sure a Unicode filename isn't mangled.
+ hSetEncoding hout utf8
+ hPutStr hout header
+ withBinaryFile from ReadMode $ \hin ->
+ copyHandle hin hout