From 347db9ce77cbb6af0f90db00a10cc061fe181047 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Fri, 13 Mar 1998 23:37:42 +0000 Subject: (copy_dir): Add new parameter, copy_into_self, and set it. (copy_internal): Likewise. (copy): Likewise. Update all callers. --- src/copy.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/copy.c b/src/copy.c index 1a762df85..c98923a88 100644 --- a/src/copy.c +++ b/src/copy.c @@ -43,7 +43,8 @@ int yesno (); static int copy_internal PARAMS ((const char *src_path, const char *dst_path, int new_dst, dev_t device, struct dir_list *ancestors, - const struct cp_options *x)); + const struct cp_options *x, + int *copy_into_self)); /* The invocation name of this program. */ extern char *program_name; @@ -64,17 +65,17 @@ is_ancestor (const struct stat *sb, const struct dir_list *ancestors) copy the contents to DST_PATH_IN. NEW_DST is nonzero if DST_PATH_IN is a directory that was created previously in the recursion. SRC_SB and ANCESTORS describe SRC_PATH_IN. + Set *COPY_INTO_SELF to nonzero if SRC_PATH_IN is a parent of + (or the same as) DST_PATH_IN; otherwise, set it to zero. Return 0 if successful, -1 if an error occurs. */ static int copy_dir (const char *src_path_in, const char *dst_path_in, int new_dst, const struct stat *src_sb, struct dir_list *ancestors, - const struct cp_options *x) + const struct cp_options *x, int *copy_into_self) { char *name_space; char *namep; - char *src_path; - char *dst_path; int ret = 0; errno = 0; @@ -93,13 +94,16 @@ copy_dir (const char *src_path_in, const char *dst_path_in, int new_dst, namep = name_space; while (*namep != '\0') { - src_path = path_concat (src_path_in, namep, NULL); - dst_path = path_concat (dst_path_in, namep, NULL); + int local_copy_into_self; + char *src_path = path_concat (src_path_in, namep, NULL); + char *dst_path = path_concat (dst_path_in, namep, NULL); + if (dst_path == NULL || src_path == NULL) error (1, 0, _("virtual memory exhausted")); ret |= copy_internal (src_path, dst_path, new_dst, src_sb->st_dev, - ancestors, x); + ancestors, x, &local_copy_into_self); + *copy_into_self |= local_copy_into_self; /* Free the memory for `src_path'. The memory for `dst_path' cannot be deallocated, since it is used to create multiple @@ -301,12 +305,14 @@ ret2: 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 devices and inodes of parent directories of SRC_PATH. + Set *COPY_INTO_SELF to nonzero if SRC_PATH is a parent of (or the + same as) DST_PATH; otherwise, set it to zero. Return 0 if successful, 1 if an error occurs. */ static int copy_internal (const char *src_path, const char *dst_path, int new_dst, dev_t device, struct dir_list *ancestors, - const struct cp_options *x) + const struct cp_options *x, int *copy_into_self) { struct stat src_sb; struct stat dst_sb; @@ -316,6 +322,7 @@ copy_internal (const char *src_path, const char *dst_path, char *dst_backup = NULL; int fix_mode = 0; + *copy_into_self = 0; if ((*(x->xstat)) (src_path, &src_sb)) { error (0, errno, "%s", src_path); @@ -335,7 +342,10 @@ copy_internal (const char *src_path, const char *dst_path, /* Did we just create this file? */ if (earlier_file == &new_file) - return 0; + { + *copy_into_self = 1; + return 0; + } src_mode = src_sb.st_mode; src_type = src_sb.st_mode; @@ -552,7 +562,8 @@ copy_internal (const char *src_path, const char *dst_path, /* Copy the contents of the directory. */ - if (copy_dir (src_path, dst_path, new_dst, &src_sb, dir, x)) + if (copy_dir (src_path, dst_path, new_dst, &src_sb, dir, x, + copy_into_self)) return 1; } #ifdef S_ISLNK @@ -771,12 +782,16 @@ valid_options (const struct cp_options *co) is known not to exist (e.g., because its parent directory was just created); NONEXISTENT_DST should be zero if DST_PATH might already exist. OPTIONS is ... FIXME-describe + Set *COPY_INTO_SELF to nonzero if SRC_PATH is a parent of (or the + same as) DST_PATH; otherwise, set it to zero. Return 0 if successful, 1 if an error occurs. */ int copy (const char *src_path, const char *dst_path, - int nonexistent_dst, const struct cp_options *options) + int nonexistent_dst, const struct cp_options *options, + int *copy_into_self) { assert (valid_options (options)); - return copy_internal (src_path, dst_path, nonexistent_dst, 0, NULL, options); + return copy_internal (src_path, dst_path, nonexistent_dst, 0, NULL, + options, copy_into_self); } -- cgit v1.2.3-70-g09d2