in reply to How does rename() work on read-only files?

For the benefit of everyone else, here's the description of the foo and bar files in the doc:

Look at this.  Assume you are the owner of all files and directories
listed, and that your umask (creation mask) is 022.

    directory           filename        file inode          perms
    ----------          ---------       -----------         ------
    alpha               .               100                 0755
    alpha               foo             101                 0644
    alpha               bar             102                 0444

    beta                .               200                 0555
    beta                foo             201                 0644
    beta                bar             102                 0444

Consider two directories, alpha and beta, each of which have the same
two filenames, foo and bar.  alpha/foo is really file #101, but beta/foo
is really file #201 -- different files.  However, the two bar filenames
both refer to the same file, because both #102.  It's just two links
(filenames) to the same file.

When you run the command on foo, you can write to it (0644) so perl puts a copy in foo.bak and then overwrites what was in foo.*

When you run the command on bar, you cannot write to it (0444) so it requires a different strategy. Instead it renames bar to bar.bak as the backup and then writes to a brand new file bar with what would be the changes.

Does that help at all?

* Edit: having tested this myself it is not what I see for foo. I see that foo.bak has the inode of the old foo. Are you sure of your result?

Edit 2: Both operations proceed in the same way: rename the file to .bak and then create the new file.

Replies are listed 'Best First'.
Re^2: How does rename() work on read-only files?
by j41r (Beadle) on Dec 11, 2018 at 10:30 UTC
    ... having tested this myself it is not what I see for foo. I see that foo.bak has the inode of the old foo. Are you sure of your result?

    Well, maybe I was so tired that I didn't notice it was actually different. Here's what I got:

    [j41r@work perl]$ rm alpha/foo.bak [j41r@work perl]$ stat -c%n:$'\t'%i alpha/foo* alpha/foo: 9353128 [j41r@work perl]$ perl -i.bak -pe 1 alpha/foo [j41r@work perl]$ stat -c%n:$'\t'%i alpha/foo* alpha/foo: 9353126 alpha/foo.bak: 9353128 [j41r@work perl]$ rm alpha/foo.bak [j41r@work perl]$ stat -c%n:$'\t'%i alpha/foo* alpha/foo: 9353126

    Why did we get a different result than the one in file-dir-perms?

      Why did we get a different result

      Perhaps you are running a different Perl version? From perl5280delta:

      Previously in-place editing (perl -i) would delete or rename the input file as soon as you started working on a new file. ... This has changed so that the input file isn't replaced until the output file has been completely written and successfully closed. This works by creating a work file in the same directory, which is renamed over the input file once the output file is complete.

        I didn't know that, thanks.

      I expect that the new inode numbers for alpha/foo* in the linked doc are in error. The textual description in the doc is correct:

      So what happens?  Consider this
      
          perl -i.bak -pe 1 alpha/foo
      
      Perl wants to do this
      
          rename alpha/foo to alpha/foo.bak
          create a new alpha/foo
      
      Now, alpha/foo is permission 0644, which means you can write it, *BUT
      THIS IS IRRELEVANT*.  You are not altering the file.  You moved it out
      of the way and created a new one.  Moving and creating are governed by
      the directory's permissions.  Since alpha is mode 0755, this is allowed ...
      

      The fact that tchrist's file-dir-perms doc is now relegated to a tarball in the olddoc tree does suggest that it is only kept for historical interest, despite the link from perlfaq5.

        The fact that tchrist's file-dir-perms doc is now relegated to a tarball in the olddoc tree does suggest that it is only kept for historical interest, despite the link from perlfaq5.

        Good tidbit hippo! One more question, could you please tell me if that's also a mistake? From file-dir-perms:

        What happens when you try to do this? perl -i.bak -pe 1 alpha/bar Well, you seem to think you shouldn't be able to rename it because it's mode 0555, readonly. But that's irrelevant. It's the diretory that matters. So it succeeds.

        The previous command actually operates on alpha (0755) and on bar (0444). Why did he refer to beta (0555) here?