diff options
author | Jim Meyering <jim@meyering.net> | 1998-05-10 12:18:21 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 1998-05-10 12:18:21 +0000 |
commit | 8a0a50e6b014c64fdd9eb7b9a9a162be83529e3d (patch) | |
tree | fd5f77480f2a4d6d51bdf90eaecd2a0cd9ddab59 | |
parent | a42054dd574b80f59f82068d052f255e2acf2231 (diff) | |
download | coreutils-8a0a50e6b014c64fdd9eb7b9a9a162be83529e3d.tar.xz |
(new_nondir_mode): New function. Use where appropriate.
Use more-specific preserve_* members in place of removed `preserve'.
(copy_internal): Honor failed_unlink_is_fatal.
-rw-r--r-- | src/copy.c | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/src/copy.c b/src/copy.c index 2a5419235..f93f92587 100644 --- a/src/copy.c +++ b/src/copy.c @@ -68,6 +68,26 @@ static int copy_internal PARAMS ((const char *src_path, const char *dst_path, /* The invocation name of this program. */ extern char *program_name; +/* Encapsulate selection of the file mode to be applied to + new non-directories. */ + +static mode_t +new_nondir_mode (const struct cp_options *option, mode_t mode) +{ + /* In some applications (e.g., install), use precisely the + specified mode. */ + if (option->set_mode) + return option->mode; + + /* In others (e.g., cp, mv), apply the user's umask. */ + return mode & option->umask_kill; +} + +/* FIXME: describe */ +/* FIXME: rewrite this to use a hash table so we avoid the quadratic + performance hit that's probably noticeable only on trees deeper + than a few hundred levels. See use of active_dir_map in remove.c */ + static int is_ancestor (const struct stat *sb, const struct dir_list *ancestors) { @@ -508,9 +528,13 @@ copy_internal (const char *src_path, const char *dst_path, { error (0, errno, _("cannot remove old link to `%s'"), dst_path); - return 1; + if (x->failed_unlink_is_fatal) + return 1; + } + else + { + new_dst = 1; } - new_dst = 1; } } } @@ -632,7 +656,7 @@ copy_internal (const char *src_path, const char *dst_path, #ifdef S_ISFIFO if (S_ISFIFO (src_type)) { - if (mkfifo (dst_path, src_mode & x->umask_kill)) + if (mkfifo (dst_path, new_nondir_mode (x, src_mode))) { error (0, errno, _("cannot create fifo `%s'"), dst_path); goto un_backup; @@ -646,7 +670,7 @@ copy_internal (const char *src_path, const char *dst_path, #endif ) { - if (mknod (dst_path, src_mode & x->umask_kill, src_sb.st_rdev)) + if (mknod (dst_path, new_nondir_mode (x, src_mode), src_sb.st_rdev)) { error (0, errno, _("cannot create special file `%s'"), dst_path); goto un_backup; @@ -674,7 +698,7 @@ copy_internal (const char *src_path, const char *dst_path, goto un_backup; } - if (x->preserve) + if (x->preserve_owner_and_group) { /* Preserve the owner and group of the just-`copied' symbolic link, if possible. */ @@ -729,7 +753,7 @@ copy_internal (const char *src_path, const char *dst_path, chown turns off set[ug]id bits for non-root, so do the chmod last. */ - if (x->preserve) + if (x->preserve_timestamps) { struct utimbuf utb; @@ -742,7 +766,10 @@ copy_internal (const char *src_path, const char *dst_path, if (x->require_preserve) return 1; } + } + if (x->preserve_owner_and_group) + { if (DO_CHOWN (chown, dst_path, src_sb.st_uid, src_sb.st_gid)) { error (0, errno, _("preserving ownership for %s"), dst_path); @@ -751,8 +778,17 @@ copy_internal (const char *src_path, const char *dst_path, } } - if ((x->preserve || new_dst) - && (x->copy_as_regular || S_ISREG (src_type) || S_ISDIR (src_type))) + if (x->set_mode) + { + /* This is so install's -m MODE option works. */ + if (chmod (dst_path, x->mode)) + { + error (0, errno, _("setting permissions for %s"), dst_path); + return 1; + } + } + else if ((x->preserve_chmod_bits || new_dst) + && (x->copy_as_regular || S_ISREG (src_type) || S_ISDIR (src_type))) { if (chmod (dst_path, src_mode & x->umask_kill)) { @@ -789,10 +825,15 @@ valid_options (const struct cp_options *co) assert (VALID_BACKUP_TYPE (co->backup_type)); - /* FIXME: make sure xstat and dereference are consistent. */ - assert (co->xstat); + /* FIXME: for some reason this assertion always fails, + at least on Solaris2.5.1. Just disable it for now. */ + /* assert (co->xstat == lstat || co->xstat == stat); */ + + /* Make sure xstat and dereference are consistent. */ + /* FIXME */ assert (VALID_SPARSE_MODE (co->sparse_mode)); + return 1; } |