Unix rename behaviour
BrowserUk
created: 2006-05-02 22:01:01

Under *nix, if two concurrent (Perl) processes have open handles to filea and one of the processes renames fileb over filea, when the second process next reads via it's open handle, does it read

  1. The original contents?
  2. Or the new contents?

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Unix rename behaviour
created: 2006-05-02 22:09:03

Presuming the second process has an open handle it should still see the original contents. It's similar to how processes with open descriptors can still read the file's contents even after the last link in the filesystem has been unlink'd (i.e. the way you get truly anonymous tmp files). Once that descriptor's closed (and presuming no other hard links to the original filea exist) the blocks for filea would go back on the free list and it's completely inaccessible (unless one really wants to grobble through a raw block device with dd or a filesystem debugger, of course :).

Additionally: it shouldn't matter if it's one of the owners of an open descriptor or not that does the rename call; so long as anyone's got an open descriptor it all should point to the same blocks on disk.

Reaped: Re^2: Unix rename behaviour
created: 2006-05-02 22:41:12
This node was taken out by the NodeReaper on 2006-05-02 22-44-53
Reason: [kutsu]: reap: obvious troll, gibberish

You may view the original node and the consideration vote tally.

Re: Unix rename behaviour
created: 2006-05-02 22:11:07

The original contents. The original file is held open, nameless, and does not disappear until closed by the last process which held it open. That's why race conditions on file writing are so critical to avoid. A process has no way to know when thay occur without some form of file locking.

Once a process has an open file descriptor, it no longer cares about the name on disk.

After Compline,
Zaxo

Re: Unix rename behaviour
created: 2006-05-02 22:18:59
I don't think that the previous two posters are correct. I'm going to stick my neck out here and say that the rename of fileb over filea reuses the inode of filea and thus modifies the exact disk contents that were used by filea. I believe that a rm is different - it removes the accessibility of the inode and this explains why the original contents remain available. Please correct me. ,welchavw
Re^2: Unix rename behaviour
created: 2006-05-02 22:48:46

It's fairly simple to demonstrate that this is not true...

jasonk@critter% cat foo.pl

#!/usr/bin/perl -w
##################
open(OUT,">/tmp/testfileA");
print OUT "This is testfileA\n";
close(OUT);

open(OUT,">/tmp/testfileB");
print OUT "This is testfileB\n";
close(OUT);

open(IN,"/tmp/testfileA");
system("mv /tmp/testfileB /tmp/testfileA");

print ;                                                                     

jasonk@critter% ./foo.pl

This is testfileA

We're not surrounded, we're in a target-rich environment!
Re^3: Unix rename behaviour
created: 2006-05-02 22:54:25
Ok, I stand corrected. I have no access to a box to test with, so I was guessing.

I suppose that the rename is just changing the directory entry. I believe that a /bin/cp will give the exact semantics that I supposed earlier? Maybe someone will check for me.

Or maybe I'll just get downvoted.

,welchavw

Re^2: Unix rename behaviour
created: 2006-05-03 01:34:22
No it reuses the inode of fileb, just changes the name of it assuning they are on the same partition. If they are on diffrent partitions it vill copy the content to the new file and then delete the first file , in this case it will be given a new inode.
Re^2: Unix rename behaviour
created: 2006-05-03 02:14:28
True, but I think the OP meant "cp" and not "mv" when refering to the rename(?) command. Although the cp(1) command will create a new inode, the already opened filehandles are pointing to older inodes.
Re^3: Unix rename behaviour
created: 2006-05-03 05:46:01
Well, he meant "rename" when he said "rename"?! (it's linked to perl rename)

-> Code should look like this

$ cat foo.pl 
#!/usr/bin/perl -w
##################
open(OUT,">testfileA");
print OUT "This is testfileA\n";
close(OUT);

open(OUT,">testfileB");
print OUT "This is testfileB\n";
close(OUT);

open(IN,"/tmp/testfileA");

rename ("testfileB", "testfileA");

print ;
close IN;

Yields:
$ ./foo.pl 
readline() on closed filehandle IN at ./foo.pl line 15.
So the answer is "neither - rename closes the filehandle". I.
Re^4: Unix rename behaviour
created: 2006-05-03 06:04:52
So the answer is "neither - rename closes the filehandle".

I think you missed the bit about "... two concurrent (Perl) processes ..." and "... when the second process next reads via it's open handle ..."

A better test would be

#!/usr/bin/perl
use strict;
use warnings;

open OUT, '>', 'junk.1' or die $!;
print OUT 'X'x 20 . "$_\n" for 1 .. 20;
close OUT;

open OUT, '>', 'junk.2' or die $!;
print OUT 'Y'x 20 . "$_\n" for 1 .. 20;
close OUT;

open IO, '+<', 'junk.1' or die $!;
seek IO, 0, 0;
print scalar ;

system $^X, '-le', q[ print rename( 'junk.2', 'junk.1' ) ? 'worked' : 'failed'];

print scalar ;

seek IO, 0, 0;

print scalar ;

close IO;

unlink 'junk.1';

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Unix rename behaviour
created: 2006-05-03 07:12:53
The behaviour depends upon when the filehandle is closed. Here's my test :
$ echo "hello" > toto
$ cat toto
hello
$ perl -e 'open F, "'

At the same time I launch in another terminal:
$ perl -e 'open F, ">toto"; print F 'goodbye'; close F; sleep 30'
The output in the first shell is "goodbye". If I change the second one liner to rename the file :
perl -e 'open F, ">toto"; system ("mv toto tata"); print F 'goodbye'; close F; sleep 30'
The output remains goodbye. However, if I change the second one-liner to:
perl -e 'open F, ">toto"; system ("mv toto tata"); print F 'goodbye'; sleep 30'
So to close the file last, then the first oneliner reads nothing at all.

perlmonks.org content © perlmonks.org and Anonymous Monk, BrowserUk, Fletch, ioannis, jasonk, lidden, NodeReaper, wazoox, welchavw, Zaxo

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03