dmitri has asked for the wisdom of the Perl Monks concerning the following question:

I apologize for this question being off-topic, but I know someone will be able to give me an answer on this forum. This is probably more of a system-specific (Linux 2.4) programming question.

rename(2) (and, therefore, Perl's own rename function) does not report an error when a file is renamed to itself. What is even more interesting, mtime of parent directory is not changed, either. So, nothing happens, but no error is reported? Why?

Some code:

perl -e '$s = rename("tags", "tags"); print STDOUT ($s ? "OK" : "FAIL" +), "\n";'

C code:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> int main (int argc, char **argv) { int rs; rs = rename(argv[1], argv[1]); if (-1 == rs) { fprintf(stderr, "Error renaming %s: %s\n", argv[1], strerror(e +rrno)); } else { printf("Rename of %s is OK\n", argv[1]); } exit(0); }

Replies are listed 'Best First'.
•Re: [OT] rename(2) -- renaming file to itself produces no error.
by merlyn (Sage) on Jan 07, 2004 at 22:43 UTC
      I feel that if I call a function that should modify the filesystem and the filesystem is not modified, an error should be reported. Maybe an ENOOP.

        Your text leads me to believe that you were attempting this operation merely for the side-effect of updating the mtime on the directory that the file is in. Is this true? If so, shame on you! :)

        Otherwise it strikes me as a violation of the principle of least surprise that rename would produce an error when asked to do something that is easy enough to do by doing nothing (principle of least action there)

Re: [OT] rename(2) -- renaming file to itself produces no error.
by ysth (Canon) on Jan 08, 2004 at 00:05 UTC
    SUSv3 says (under rename Rationale):
    The specification that if old and new refer to the same file is intended to guarantee that:

    rename("x", "x");

    does not remove the file.

    Seems a little lame to me (the given rationale, not necessarily the behaviour).

    All of the special handling for when the new file already exists is a POSIX extension of the ISO C standard.

      I don't know, the rationale seems quite reasonable to me. I don't know the technical aspects of rename, but I assume that the file is copied and then the one that was copied is removed, making it so that a copy of this file is guaranteed to exist in full somewhere on the filesystem. If this is indeed the method used, how would you go about moving a file to the same path? You'd have to hold the entire file contents in memory, delete the original file, then create the "new" file and place the in-memory contents back in. (Or you could use a temp file rather than memory). This would leave somewhat of an undesirable race condition in which a file we are renaming doesn't exist on the filesystem at all.

      This doesn't answer the "why is there no error" question, but I don't see why there should be.

Re: [OT] rename(2) -- renaming file to itself produces no error.
by Plankton (Vicar) on Jan 07, 2004 at 23:20 UTC
    I guess you have two choices here:

    1) rewrite the rename function.
    2) check to see if the file exist before you rename it.

    As to why it does NOT report an error ... I guess who ever wrote the rename function did NOT feel like this is an error.

    Plankton: 1% Evil, 99% Hot Gas.
    NOTs added after dmitri pointed out my mistake. Kinda of ironic ain't it. :/
      You mean, s/does/does not/ && s/did/did not/, right?
Re: [OT] rename(2) -- renaming file to itself produces no error.
by kutsu (Priest) on Jan 07, 2004 at 23:03 UTC

    Actually, in KDE, rename doesn't give many errors at all, not for permission issues, if the file doesn't exist, or if your renaming a file to the same name. For the why question if your doing this in a shell, esp. one run by nightly/daily operators, you don't want errors like "couldn't rename so and so" displaying if these files are only created on certain days. If you want an error code use mv or add some manual checking to your script.

    "Pain is weakness leaving the body, I find myself in pain everyday" -me

      Umm, I am talking C code here. A project in which a logical error crept up and was not detected because of this weird (to me) behavior. A production system. With junk code in it, which should not be there.