From d0294ff3b90430750a631556277c75f1a555dd44 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 3 Apr 2014 09:48:22 -0700 Subject: [PATCH] cp: don't reserve a device number * src/copy.c (copy_internal): Replace dev_t arg DEVICE with struct stat pointer arg PARENT. All callers changed. This removes an unwarranted assumption that dev_t values of 0 cannot occur in file systems. See: http://bugs.gnu.org/17179 --- src/copy.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/copy.c b/src/copy.c index 781cc1e..d471a77 100644 --- a/src/copy.c +++ b/src/copy.c @@ -117,7 +117,7 @@ struct dir_list #define DEST_INFO_INITIAL_CAPACITY 61 static bool copy_internal (char const *src_name, char const *dst_name, - bool new_dst, dev_t device, + bool new_dst, struct stat const *parent, struct dir_list *ancestors, const struct cp_options *x, bool command_line_arg, @@ -621,7 +621,7 @@ copy_dir (char const *src_name_in, char const *dst_name_in, bool new_dst, char *dst_name = file_name_concat (dst_name_in, namep, NULL); bool first_dir_created = *first_dir_created_per_command_line_arg; - ok &= copy_internal (src_name, dst_name, new_dst, src_sb->st_dev, + ok &= copy_internal (src_name, dst_name, new_dst, src_sb, ancestors, &non_command_line_options, false, &first_dir_created, &local_copy_into_self, NULL); @@ -1725,9 +1725,8 @@ should_dereference (const struct cp_options *x, bool command_line_arg) /* Copy the file SRC_NAME to the file DST_NAME. The files may be of any type. NEW_DST should be true if the file DST_NAME cannot exist because its parent directory was just created; NEW_DST should - be false if DST_NAME might already exist. DEVICE is the device - number of the parent directory, or 0 if the parent of this file is - not known. ANCESTORS points to a linked, null terminated list of + be false if DST_NAME might already exist. A nonnull PARENT describes the + parent directory. ANCESTORS points to a linked, null terminated list of devices and inodes of parent directories of SRC_NAME. COMMAND_LINE_ARG is true iff SRC_NAME was specified on the command line. FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG is both input and output. @@ -1737,7 +1736,7 @@ should_dereference (const struct cp_options *x, bool command_line_arg) static bool copy_internal (char const *src_name, char const *dst_name, bool new_dst, - dev_t device, + struct stat const *parent, struct dir_list *ancestors, const struct cp_options *x, bool command_line_arg, @@ -2434,7 +2433,7 @@ copy_internal (char const *src_name, char const *dst_name, } /* Decide whether to copy the contents of the directory. */ - if (x->one_file_system && device != 0 && device != src_sb.st_dev) + if (x->one_file_system && parent && parent->st_dev != src_sb.st_dev) { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -2827,7 +2826,7 @@ copy (char const *src_name, char const *dst_name, top_level_dst_name = dst_name; bool first_dir_created_per_command_line_arg = false; - return copy_internal (src_name, dst_name, nonexistent_dst, 0, NULL, + return copy_internal (src_name, dst_name, nonexistent_dst, NULL, NULL, options, true, &first_dir_created_per_command_line_arg, copy_into_self, rename_succeeded); -- 1.9.1