
Hi, I tried installing Cabal-1.1.4, but a bug from a long time ago is still present. Is it the case that if the new Cabal is in my package database, then it will be used? $ ghc-pkg list /home/frederik/arch/i386//lib/ghc-6.4.2/package.conf: Cabal-1.1.4, GLUT-2.0, HGL-3.1, HUnit-1.1, OpenGL-2.0, QuickCheck-1.0, X11-1.1, base-1.0, (concurrent-1.0), (data-1.0), fgl-5.2, haskell-src-1.0, haskell98-1.0, hsql-1.7, hsql-mysql-1.7, (hssource-1.0), (lang-1.0), mtl-1.0, (net-1.0), network-1.0, parsec-1.0, (posix-1.0), readline-1.0, rts-1.0, stm-1.0, template-haskell-1.0, (text-1.0), unix-1.0, (util-1.0) /home/frederik/.ghc/i386-linux-6.4.2/package.conf: Futility-0.1.8, GSL-0.5 The bug occurs when there is an existing file with the same path as one which Cabal is trying to install - rather than unlinking and creating a new file, it seems that Cabal tries to open the existing file and write to it. ... Skipping Main ( programs/move-spool.hs, dist/build/move-spool/move-spool-tmp/Main.o ) dist/build/move-spool/move-spool is up to date, linking not required. Installing: /home/frederik/lib/Futility-0.1.8/ghc-6.4.2 & /home/frederik/bin Futility-0.1.8... *** Exception: /home/frederik/bin/fssh: copyFile: resource busy (Text file busy) Regards, Frederik -- http://ofb.net/~frederik/

Frederik Eaton wrote:
Hi,
I tried installing Cabal-1.1.4, but a bug from a long time ago is still present. Is it the case that if the new Cabal is in my package database, then it will be used?
$ ghc-pkg list /home/frederik/arch/i386//lib/ghc-6.4.2/package.conf: Cabal-1.1.4, GLUT-2.0, HGL-3.1, HUnit-1.1, OpenGL-2.0, QuickCheck-1.0, X11-1.1, base-1.0, (concurrent-1.0), (data-1.0), fgl-5.2, haskell-src-1.0, haskell98-1.0, hsql-1.7, hsql-mysql-1.7, (hssource-1.0), (lang-1.0), mtl-1.0, (net-1.0), network-1.0, parsec-1.0, (posix-1.0), readline-1.0, rts-1.0, stm-1.0, template-haskell-1.0, (text-1.0), unix-1.0, (util-1.0) /home/frederik/.ghc/i386-linux-6.4.2/package.conf: Futility-0.1.8, GSL-0.5
The bug occurs when there is an existing file with the same path as one which Cabal is trying to install - rather than unlinking and creating a new file, it seems that Cabal tries to open the existing file and write to it.
... Skipping Main ( programs/move-spool.hs, dist/build/move-spool/move-spool-tmp/Main.o ) dist/build/move-spool/move-spool is up to date, linking not required. Installing: /home/frederik/lib/Futility-0.1.8/ghc-6.4.2 & /home/frederik/bin Futility-0.1.8... *** Exception: /home/frederik/bin/fssh: copyFile: resource busy (Text file busy)
I've fixed this in System.Directory.copyFile, although there doesn't seem to be a foolproof way to do it: if you unlink before opening, there's a chance that someone else can create the file in between. Still, this appears to be what install(3) does. Cheers, Simon

Dear bug-coreutils, We are trying to decide what the semantics of the Haskell standard library function 'copyFile' should be. The first incarnation behaved roughly like 'cp', i.e. overwriting destination files without unlinking them first. This isn't suitable for installing stuff, for example, since if an executable is running and we try to overwrite it then there is a "Text file busy" error. We could change the semantics to be the same as 'cp --remove-destination', i.e. unlinking pre-existing destination files. The question is, is there a reason why users wouldn't always want a "copyFile" function to remove the destination first? If there is, then maybe we should have two separate functions, for both situations. The only drawback I can think of for removing the destination first, is a race condition when someone else is trying to create the same file, but how often does that actually become a problem? Thanks, Frederik -- http://ofb.net/~frederik/

Isn't this Unix specific bug? If that is the case then maybe unlinking
should be optional.
Cheers,
Krasimir
On 8/22/06, Frederik Eaton
Dear bug-coreutils,
We are trying to decide what the semantics of the Haskell standard library function 'copyFile' should be. The first incarnation behaved roughly like 'cp', i.e. overwriting destination files without unlinking them first. This isn't suitable for installing stuff, for example, since if an executable is running and we try to overwrite it then there is a "Text file busy" error. We could change the semantics to be the same as 'cp --remove-destination', i.e. unlinking pre-existing destination files.
The question is, is there a reason why users wouldn't always want a "copyFile" function to remove the destination first? If there is, then maybe we should have two separate functions, for both situations. The only drawback I can think of for removing the destination first, is a race condition when someone else is trying to create the same file, but how often does that actually become a problem?
Thanks,
Frederik
-- http://ofb.net/~frederik/ _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Perhaps the "Text file busy" error is Unix-specific, but I can imagine cases where somebody (other than the OS) might open a file with a well-known name and read from various parts of it, and expect it not to change underneath them... Regards, Frederik On Tue, Aug 22, 2006 at 05:19:42PM +0300, Krasimir Angelov wrote:
Isn't this Unix specific bug? If that is the case then maybe unlinking should be optional.
Cheers, Krasimir
On 8/22/06, Frederik Eaton
wrote: Dear bug-coreutils,
We are trying to decide what the semantics of the Haskell standard library function 'copyFile' should be. The first incarnation behaved roughly like 'cp', i.e. overwriting destination files without unlinking them first. This isn't suitable for installing stuff, for example, since if an executable is running and we try to overwrite it then there is a "Text file busy" error. We could change the semantics to be the same as 'cp --remove-destination', i.e. unlinking pre-existing destination files.
The question is, is there a reason why users wouldn't always want a "copyFile" function to remove the destination first? If there is, then maybe we should have two separate functions, for both situations. The only drawback I can think of for removing the destination first, is a race condition when someone else is trying to create the same file, but how often does that actually become a problem?
Thanks,
Frederik
-- http://ofb.net/~frederik/ _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On 8/22/06, Frederik Eaton
Perhaps the "Text file busy" error is Unix-specific, but I can imagine cases where somebody (other than the OS) might open a file with a well-known name and read from various parts of it, and expect it not to change underneath them...
Then he/she may expect that the file will not be suddenly unlinked while he/she is still reading. The documentation for System.IO says that the implementation should provide single writer - multiple readers locking. When that is the case then copyFile should fail if the target fail is open for reading or writing from someone including the OS. The Unix implementation provides only local locking but the Windows implementation provides system wide locking. Cheers, Krasimir

On Tue, Aug 22, 2006 at 06:16:39PM +0300, Krasimir Angelov wrote:
On 8/22/06, Frederik Eaton
wrote: Perhaps the "Text file busy" error is Unix-specific, but I can imagine cases where somebody (other than the OS) might open a file with a well-known name and read from various parts of it, and expect it not to change underneath them...
Then he/she may expect that the file will not be suddenly unlinked while he/she is still reading.
I hardly know anything about Windows. Doesn't it have inodes, so I can open a file, unlink it, and continue to read from and write to it?
The documentation for System.IO says that the implementation should provide single writer - multiple readers locking. When that is the case then copyFile should fail if the target fail is open for reading or writing from someone including the OS. The Unix implementation provides only local locking but the Windows implementation provides system wide locking.

On Tue, Aug 22, 2006 at 06:16:39PM +0300, Krasimir Angelov wrote:
On 8/22/06, Frederik Eaton
wrote: Perhaps the "Text file busy" error is Unix-specific, but I can imagine cases where somebody (other than the OS) might open a file with a well-known name and read from various parts of it, and expect it not to change underneath them...
Then he/she may expect that the file will not be suddenly unlinked while he/she is still reading.
I hardly know anything about Windows. Doesn't it have inodes, so I can open a file, unlink it, and continue to read from and write to it?
The documentation for System.IO says that the implementation should provide single writer - multiple readers locking. When that is the case then copyFile should fail if the target fail is open for reading or writing from someone including the OS. The Unix implementation provides only local locking but the Windows implementation provides system wide locking.
Ah! I understand now. This simply doesn't work under Windows but it makes sense for Unix. I just think that removeFile should be called only on non-Windows OSes.

On Tue, Aug 22, 2006 at 01:20:02PM +0100, Simon Marlow wrote:
I've fixed this in System.Directory.copyFile, although there doesn't seem to be a foolproof way to do it: if you unlink before opening, there's a chance that someone else can create the file in between. Still, this appears to be what install(3) does.
Isn't it standard practice to create a file as a new name in the same directory, then rename(2) it to be the same as the target?, that doesn't introduce any race conditions as rename(2) is atomic. John -- John Meacham - ⑆repetae.net⑆john⑈

I've fixed this in System.Directory.copyFile, although there doesn't seem to be a foolproof way to do it: if you unlink before opening, there's a chance that someone else can create the file in between. Still, this appears to be what install(3) does.
Since there seem to be compelling reasons to want both "unlink" and "overwrite" behaviors available in the standard library, I suggest keeping the current copyFile semantics and moving the new "unlink" behavior to another function. The second function could be called "installFile". Then, Cabal should be changed to use "installFile" instead of "copyFile" (probably via a compatibility library). Summary of behavior differences: - effect on hard, soft links - effect on ACLs, permissions, ownership, inode number - effect on destinations without write permission Regards, Frederik -- http://ofb.net/~frederik/

Frederik Eaton wrote:
I've fixed this in System.Directory.copyFile, although there doesn't seem to be a foolproof way to do it: if you unlink before opening, there's a chance that someone else can create the file in between. Still, this appears to be what install(3) does.
Since there seem to be compelling reasons to want both "unlink" and "overwrite" behaviors available in the standard library, I suggest keeping the current copyFile semantics and moving the new "unlink" behavior to another function. The second function could be called "installFile". Then, Cabal should be changed to use "installFile" instead of "copyFile" (probably via a compatibility library).
Summary of behavior differences: - effect on hard, soft links - effect on ACLs, permissions, ownership, inode number - effect on destinations without write permission
I've copied the useful points from this discussion into a comment in System.Directory, backed out the change I made yesterday, and filed a ticket for doing what you suggest above. Cheers, Simon
participants (4)
-
Frederik Eaton
-
John Meacham
-
Krasimir Angelov
-
Simon Marlow