
Hi all, It seems I'm not allowed to open same file both for writing and for reading: Prelude System.IO> f_out <- openFile "mylog.log" AppendMode Prelude System.IO> f_in <- openFile "mylog.log" ReadMode *** Exception: mylog.log: openFile: resource busy (file is locked) Usage scenario: I use hslogger to write to logs, but I'd like to read parts of these logs *from inside same Haskell application*. How do I get around exclusive mode in openFile? -- Gracjan

On 28 June 2011 17:50, Gracjan Polak
It seems I'm not allowed to open same file both for writing and for reading:
This behaviour is part of the Haskell 98 specification (section 21.2.3, http://www.haskell.org/onlinereport/io.html): """ Implementations should enforce as far as possible, at least locally to the Haskell process, multiple-reader single-writer locking on files. That is, there may either be many handles on the same file which manage input, or just one handle on the file which manages output. If any open or semi-closed handle is managing a file for output, no new handle can be allocated for that file. """ I've been bitten by this before and don't like it. It would be possible for GHC to enforce Unix semantics instead (there are appropriate flags to CreateFile that get those semantics on Windows), which would support more use cases. This change would have to be carefully thought through, and the report would have to be amended. Cheers, Max

Max Bolingbroke
This behaviour is part of the Haskell 98 specification (section 21.2.3, http://www.haskell.org/onlinereport/io.html):
Thanks for the explanation. Such sharing behavior should be mentioned in documentation: http://hackage.haskell.org/packages/archive/haskell98/latest/doc/html/IO.htm... What was the rationale behind such strict non-sharing policy? Anyway, where do I find an 'openFileShared' function? Packages unix/Win32 do not have obvious leads...
""" Implementations should enforce as far as possible, at least locally to the Haskell process, multiple-reader single-writer locking on files. That is, there may either be many handles on the same file which manage input, or just one handle on the file which manages output. If any open or semi-closed handle is managing a file for output, no new handle can be allocated for that file. """
I've been bitten by this before and don't like it. It would be possible for GHC to enforce Unix semantics instead (there are appropriate flags to CreateFile that get those semantics on Windows), which would support more use cases. This change would have to be carefully thought through, and the report would have to be amended.
Cheers, Max
-- Gracjan

On Tue, Jun 28, 2011 at 13:56, Gracjan Polak
What was the rationale behind such strict non-sharing policy?
The obvious rationale is that it helps maintain the illusion of referential integrity within the process. (Outside is a lost cause, but operations on different file handles are assumed to not affect each other.) -- brandon s allbery allbery.b@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms

On 28 June 2011 18:56, Gracjan Polak
Anyway, where do I find an 'openFileShared' function? Packages unix/Win32 do not have obvious leads...
Perhaps the functions in System.Posix.IO do what you want? http://hackage.haskell.org/packages/archive/unix/2.4.2.0/doc/html/System-Pos.... The equivalent on the Win32 side is CreateFile: http://hackage.haskell.org/packages/archive/Win32/2.2.0.2/doc/html/System-Wi... There is a way to create a Handle from a Fd (http://hackage.haskell.org/packages/archive/base/latest/doc/html/GHC-IO-Hand...), but I'm not sure if there is an equivalent to build a Handle from a Win32 HANDLE... Hope those pointers help... Max

Max Bolingbroke
http://hackage.haskell.org/packages/archive/unix/2.4.2.0/doc/html/System-Pos.... Thanks for the link. I tried to use it: Prelude System.Posix.IO> fd1 <- openFd "xxx.tmp" WriteOnly (Just 0666) defaultFileFlags Loading package unix-2.4.0.2 ... linking ... done. Prelude System.Posix.IO> fd2 <- openFd "xxx.tmp" WriteOnly (Just 0666) defaultFileFlags Prelude System.Posix.IO> print (fd1,fd2) (5,7) Prelude System.Posix.IO> h1 <- fdToHandle fd1 Prelude System.Posix.IO> h2 <- fdToHandle fd2 *** Exception: openFile: resource busy (file is locked) So I can open file twice. So far so good. Then I convert Fds to Handles and second conversion fails. I'm looking for file locking code in GHC.IO.* modules, but cannot find any. How do I convince fdToHandle to create an independent handle to non-locked file? -- Gracjan

Gracjan Polak
I'm looking for file locking code in GHC.IO.* modules, but cannot find any.
Just for the record: locking code resides in GHC.IO.FD in mkFD which calls lockFile. There is a heavy machinery underneath that is working hard to ensure Report's semantics. Somebody must have spent a lot of effort in this place. Nice!
How do I convince fdToHandle to create an independent handle to non-locked file?
Proper way to handle this is probably to add additional Bool parameter to mkFD, fdToHandle and GHC.IO.FD.openFile that says if Report's semantics should be held or not. Then openFileShared can be build on top of that. (Possibly primed versions of these function will be needed to keep backward compatibility) If this could help anybody else out there beside me I could make this proposal more concrete and follow library change procedure properly. If not I can live with what I have hacked together till now. Is there any interest in such a change? -- Gracjan

On Wed, Jun 29, 2011 at 7:11 PM, Gracjan Polak
Proper way to handle this is probably to add additional Bool parameter to mkFD, fdToHandle and GHC.IO.FD.openFile that says if Report's semantics should be held or not. Then openFileShared can be build on top of that.
(Possibly primed versions of these function will be needed to keep backward compatibility)
If this could help anybody else out there beside me I could make this proposal more concrete and follow library change procedure properly. If not I can live with what I have hacked together till now.
Is there any interest in such a change?
There should be at least something on the docs of openFile. But I think that openFileShared may be handy. Cheers! -- Felipe.
participants (4)
-
Brandon Allbery
-
Felipe Almeida Lessa
-
Gracjan Polak
-
Max Bolingbroke