Merge remote-tracking branch 'origin/streamly'
This commit is contained in:
commit
7db7a9402f
20
.travis.yml
20
.travis.yml
@ -7,16 +7,16 @@ dist: trusty
|
|||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- env: CABALVER=1.18 GHCVER=7.6.3
|
- env: CABALVER=2.2 GHCVER=7.6.3
|
||||||
addons: {apt: {packages: [cabal-install-1.18,ghc-7.6.3], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [cabal-install-2.2,ghc-7.6.3], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=1.22 GHCVER=7.8.4
|
- env: CABALVER=2.2 GHCVER=7.8.4
|
||||||
addons: {apt: {packages: [cabal-install-1.22,ghc-7.8.4], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [cabal-install-2.2,ghc-7.8.4], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=1.24 GHCVER=7.10.2
|
- env: CABALVER=2.2 GHCVER=7.10.2
|
||||||
addons: {apt: {packages: [cabal-install-1.24,ghc-7.10.2], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [cabal-install-2.2,ghc-7.10.2], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=1.24 GHCVER=8.0.1
|
- env: CABALVER=2.2 GHCVER=8.0.1
|
||||||
addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [cabal-install-2.2,ghc-8.0.1], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=2.0 GHCVER=8.2.2
|
- env: CABALVER=2.2 GHCVER=8.2.2
|
||||||
addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [cabal-install-2.2,ghc-8.2.2], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=2.2 GHCVER=8.4.1
|
- env: CABALVER=2.2 GHCVER=8.4.1
|
||||||
addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.1], sources: [hvr-ghc]}}
|
addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.1], sources: [hvr-ghc]}}
|
||||||
- env: CABALVER=head GHCVER=head
|
- env: CABALVER=head GHCVER=head
|
||||||
|
@ -41,12 +41,14 @@ library
|
|||||||
, deepseq
|
, deepseq
|
||||||
, exceptions
|
, exceptions
|
||||||
, hspec
|
, hspec
|
||||||
, simple-sendfile >= 0.2.24
|
|
||||||
, unix >= 2.5
|
, unix >= 2.5
|
||||||
, unix-bytestring
|
, unix-bytestring
|
||||||
, utf8-string
|
, utf8-string
|
||||||
, word8
|
, word8
|
||||||
|
if impl(ghc >= 8.2)
|
||||||
|
build-depends: streamly >= 0.7
|
||||||
|
else
|
||||||
|
build-depends: simple-sendfile >= 0.2.24
|
||||||
|
|
||||||
test-suite doctests-hpath
|
test-suite doctests-hpath
|
||||||
if os(windows)
|
if os(windows)
|
||||||
|
@ -150,12 +150,14 @@ import Data.Word
|
|||||||
import Foreign.C.Error
|
import Foreign.C.Error
|
||||||
(
|
(
|
||||||
eEXIST
|
eEXIST
|
||||||
, eINVAL
|
|
||||||
, eNOENT
|
, eNOENT
|
||||||
, eNOSYS
|
|
||||||
, eNOTEMPTY
|
, eNOTEMPTY
|
||||||
, eXDEV
|
, eXDEV
|
||||||
, getErrno
|
, getErrno
|
||||||
|
#if __GLASGOW_HASKELL__ < 802
|
||||||
|
, eINVAL
|
||||||
|
, eNOSYS
|
||||||
|
#endif
|
||||||
)
|
)
|
||||||
import Foreign.C.Types
|
import Foreign.C.Types
|
||||||
(
|
(
|
||||||
@ -177,16 +179,23 @@ import HPath
|
|||||||
import HPath.Internal
|
import HPath.Internal
|
||||||
import HPath.IO.Errors
|
import HPath.IO.Errors
|
||||||
import Prelude hiding (appendFile, readFile, writeFile)
|
import Prelude hiding (appendFile, readFile, writeFile)
|
||||||
import System.IO.Error
|
#if __GLASGOW_HASKELL__ >= 802
|
||||||
(
|
import qualified Streamly.FileSystem.Handle as FH
|
||||||
catchIOError
|
import qualified Streamly.Internal.FileSystem.Handle as IFH
|
||||||
, ioeGetErrorType
|
import qualified Streamly.Prelude as S
|
||||||
)
|
import qualified System.IO as SIO
|
||||||
|
#else
|
||||||
import System.Linux.Sendfile
|
import System.Linux.Sendfile
|
||||||
(
|
(
|
||||||
sendfileFd
|
sendfileFd
|
||||||
, FileRange(..)
|
, FileRange(..)
|
||||||
)
|
)
|
||||||
|
#endif
|
||||||
|
import System.IO.Error
|
||||||
|
(
|
||||||
|
catchIOError
|
||||||
|
, ioeGetErrorType
|
||||||
|
)
|
||||||
import System.Posix.ByteString
|
import System.Posix.ByteString
|
||||||
(
|
(
|
||||||
exclusive
|
exclusive
|
||||||
@ -466,6 +475,7 @@ recreateSymlink symsource@(MkPath symsourceBS) newsym@(MkPath newsymBS) cm
|
|||||||
-- instead.
|
-- instead.
|
||||||
--
|
--
|
||||||
-- In `Overwrite` copy mode only overwrites actual files, not directories.
|
-- In `Overwrite` copy mode only overwrites actual files, not directories.
|
||||||
|
-- In `Strict` mode the destination file must not exist.
|
||||||
--
|
--
|
||||||
-- Safety/reliability concerns:
|
-- Safety/reliability concerns:
|
||||||
--
|
--
|
||||||
@ -493,12 +503,45 @@ recreateSymlink symsource@(MkPath symsourceBS) newsym@(MkPath newsymBS) cm
|
|||||||
--
|
--
|
||||||
-- Notes:
|
-- Notes:
|
||||||
--
|
--
|
||||||
-- - calls `sendfile` and possibly `read`/`write` as fallback
|
-- - on GHC < 8.2: calls `sendfile` and possibly `read`/`write` as fallback
|
||||||
|
-- - on GHC >= 8.2: uses streamly for file copying
|
||||||
-- - may call `getcwd` in Overwrite mode (if destination is a relative path)
|
-- - may call `getcwd` in Overwrite mode (if destination is a relative path)
|
||||||
copyFile :: Path b1 -- ^ source file
|
copyFile :: Path b1 -- ^ source file
|
||||||
-> Path b2 -- ^ destination file
|
-> Path b2 -- ^ destination file
|
||||||
-> CopyMode
|
-> CopyMode
|
||||||
-> IO ()
|
-> IO ()
|
||||||
|
#if __GLASGOW_HASKELL__ >= 802
|
||||||
|
copyFile fp@(MkPath from) tp@(MkPath to) cm = do
|
||||||
|
throwSameFile fp tp
|
||||||
|
bracket (do
|
||||||
|
fd <- openFd from SPI.ReadOnly [SPDF.oNofollow] Nothing
|
||||||
|
handle <- SPI.fdToHandle fd
|
||||||
|
pure (fd, handle))
|
||||||
|
(\(_, handle) -> SIO.hClose handle)
|
||||||
|
$ \(fromFd, fH) -> do
|
||||||
|
sourceFileMode <- System.Posix.Files.ByteString.fileMode <$> getFdStatus fromFd
|
||||||
|
let dflags = [SPDF.oNofollow, case cm of
|
||||||
|
Strict -> SPDF.oExcl
|
||||||
|
Overwrite -> SPDF.oTrunc]
|
||||||
|
bracketeer (do
|
||||||
|
fd <- openFd to SPI.WriteOnly dflags $ Just sourceFileMode
|
||||||
|
handle <- SPI.fdToHandle fd
|
||||||
|
pure (fd, handle))
|
||||||
|
(\(_, handle) -> SIO.hClose handle)
|
||||||
|
(\(_, handle) -> do
|
||||||
|
SIO.hClose handle
|
||||||
|
case cm of
|
||||||
|
-- if we created the file and copying failed, it's
|
||||||
|
-- safe to clean up
|
||||||
|
Strict -> deleteFile tp
|
||||||
|
Overwrite -> pure ())
|
||||||
|
$ \(_, tH) -> do
|
||||||
|
SIO.hSetBinaryMode fH True
|
||||||
|
SIO.hSetBinaryMode tH True
|
||||||
|
streamlyCopy (fH, tH)
|
||||||
|
where
|
||||||
|
streamlyCopy (fH, tH) = S.fold (FH.writeChunks tH) $ IFH.toChunksWithBufferOf (256*1024) fH
|
||||||
|
#else
|
||||||
copyFile from to cm = do
|
copyFile from to cm = do
|
||||||
throwSameFile from to
|
throwSameFile from to
|
||||||
|
|
||||||
@ -569,7 +612,7 @@ _copyFile sflags dflags (MkPath fromBS) to@(MkPath toBS)
|
|||||||
when (rsize /= size) (ioError $ userError
|
when (rsize /= size) (ioError $ userError
|
||||||
"wrong size!")
|
"wrong size!")
|
||||||
write' sfd dfd buf (totalsize + fromIntegral size)
|
write' sfd dfd buf (totalsize + fromIntegral size)
|
||||||
|
#endif
|
||||||
|
|
||||||
-- |Copies a regular file, directory or symbolic link. In case of a
|
-- |Copies a regular file, directory or symbolic link. In case of a
|
||||||
-- symbolic link it is just recreated, even if it points to a directory.
|
-- symbolic link it is just recreated, even if it points to a directory.
|
||||||
|
Loading…
Reference in New Issue
Block a user