From: Jim Meyering Date: Mon, 30 Nov 1998 02:10:13 +0000 (+0000) Subject: (copy_internal): Remove earlier (but less effective) X-Git-Tag: FILEUTILS-4_1-b1~80 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=32df3704e41fac85df7e7054678d14d94f4cb153;p=thirdparty%2Fcoreutils.git (copy_internal): Remove earlier (but less effective) test for move/copy-into-self. Instead, deduce the move-into-self condition from errno==EINVAL after a failed rename. --- diff --git a/src/copy.c b/src/copy.c index 1784689b62..3b1acdfe16 100644 --- a/src/copy.c +++ b/src/copy.c @@ -387,14 +387,6 @@ copy_internal (const char *src_path, const char *dst_path, earlier_file = remember_copied (dst_path, src_sb.st_ino, src_sb.st_dev); - /* Did we just create this file? */ - - if (earlier_file == &new_file) - { - *copy_into_self = 1; - return 0; - } - src_mode = src_sb.st_mode; src_type = src_sb.st_mode; @@ -617,13 +609,30 @@ copy_internal (const char *src_path, const char *dst_path, return 0; } - if (move_mode && rename (src_path, dst_path) == 0) + if (move_mode) { - if (x->verbose && S_ISDIR (src_type)) - printf ("%s -> %s\n", src_path, dst_path); - if (rename_succeeded) - *rename_succeeded = 1; - return 0; + if (rename (src_path, dst_path) == 0) + { + if (x->verbose && S_ISDIR (src_type)) + printf ("%s -> %s\n", src_path, dst_path); + if (rename_succeeded) + *rename_succeeded = 1; + return 0; + } + + /* FIXME: someday, consider what to do when moving a directory into + itself but when source and destination are on different devices. */ + + /* This happens when attempting to rename a directory to a + subdirectory of itself. */ + if (errno == EINVAL) + { + /* FIXME: this is a little fragile in that it relies on rename(2) + returning a specific errno (EINVAL). Expect problems on + non-POSIX systems. */ + *copy_into_self = 1; + return 0; + } } if (S_ISDIR (src_type))