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.
This commit is contained in:
Joey Hess 2024-10-15 11:56:42 -04:00
parent 57ac43e4f1
commit 76a1989a0e
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 33 additions and 0 deletions

32
Utility/OpenFile.hs Normal file
View file

@ -0,0 +1,32 @@
{- 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

View file

@ -1091,6 +1091,7 @@ Executable git-annex
Utility.Network
Utility.NotificationBroadcaster
Utility.OpenFd
Utility.OpenFile
Utility.OptParse
Utility.OSX
Utility.PID