git-annex/Utility/OpenFile.hs
Joey Hess 76a1989a0e
implement openFileBeingWritten
This bypasses the usual haskell file locking used to prevent opening a
file for read that is being written to.

This is unfortunately a bit of a hack. But it seems fairly unlikely to
get broken by changes to ghc. I hope. Using fdToHandle' will also work.

This does not work on windows because it uses openFd from posix. It
would probably be possible to implement it for windows too, just opening
the FD using the Win32 library instead. However, whether windows will
allow reading from a file that is also being written to I don't know,
and since in the git-annex case the writer could be another process (eg
external special remote), that might be doing its own locking in
windows, that seems a can of worms I'd prefer not to open.
2024-10-15 11:56:42 -04:00

32 lines
965 B
Haskell

{- Opening files
-
- Copyright 2024 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
module Utility.OpenFile where
import System.IO
import System.Posix.IO
import GHC.IO.FD
import GHC.IO.Handle.FD
import GHC.IO.Device
import Utility.OpenFd
import Utility.RawFilePath
import Utility.FileSystemEncoding
{- Usually, opening a Handle to a file that another thread also has open
- for write is prevented, which avoids a lot of concurrency bugs especially
- with lazy IO.
-
- However, sometimes one thread is writing and another thread really wants
- to read from the same file. This bypasses the usual locking, by claiming
- that an opened FD is a Stream.
-}
openFileBeingWritten :: RawFilePath -> IO Handle
openFileBeingWritten f = do
fd <- openFdWithMode f ReadOnly Nothing defaultFileFlags
(fd', fdtype) <- mkFD (fromIntegral fd) ReadMode (Just (Stream, 0, 0)) False False
mkHandleFromFD fd' fdtype (fromRawFilePath f) ReadMode False Nothing