I've looked at traces of both Solaris mv and the cut and paste GUI operation on windows for behavior when a directory is moved. In both cases, if the rename of the directory failed, then it is copied and then the entries are moved across one by one. Both approaches try a move and not a copy.
In the GNU mv, if the directory rename fails, then the entries are all copied and no attempt is made to move them across. As an optimization, I see why that would be there. However, it does yield different behavior than other platforms. In NetApp's NFS file servers, we have the concept of a quota tree, qtree, which is a combination of a logical partition and quotas on a rooted subtree of a volume. In the past, we disallowed moving files across qtrees. In our next release, we are going to allow moving files, but not directories, across qtrees. With the typical client implementation of mv, the rename of the directory fails, so it gets copied to the new qtree, and then recursion tries to rename the files. They get renamed and finally the original directory gets deleted. This will not work with the 4.1 version of fileutils. If I look in the source, I see: int copy (const char *src_path, const char *dst_path, int nonexistent_dst, const struct cp_options *options, int *copy_into_self, int *rename_succeeded) { /* move_mode is set to the value from the `options' parameter for the first copy_internal call. For all subsequent calls (if any), it must be zero. */ int move_mode = options->move_mode; assert (valid_options (options)); /* Record the file names: they're used in case of error, when copying a directory into itself. I don't like to make these tools do *any* extra work in the common case when that work is solely to handle exceptional cases, but in this case, I don't see a way to derive the top level source and destination directory names where they're used. An alternative is to use COPY_INTO_SELF and print the diagnostic from every caller -- but I don't wan't to do that. */ top_level_src_path = src_path; top_level_dst_path = dst_path; return copy_internal (src_path, dst_path, nonexistent_dst, 0, NULL, options, move_mode, copy_into_self, rename_succeeded); } Later, inside copy_dir: ret |= copy_internal (src_path, dst_path, new_dst, src_sb->st_dev, ancestors, &non_command_line_options, 0, &local_copy_into_self, NULL); One solution is to pass move_mode to copy_dir and let it follow the recursion. The second is to change all references to move_mode to be to options->move_mode and remove the move_mode parameter. I can provide network trace files of the different client mvs. -- Tom Haynes, cfb [EMAIL PROTECTED] _______________________________________________ Bug-fileutils mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-fileutils