summaryrefslogtreecommitdiff
path: root/src/cp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cp.c')
-rw-r--r--src/cp.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/src/cp.c b/src/cp.c
index 01d98cc64..a46f900bc 100644
--- a/src/cp.c
+++ b/src/cp.c
@@ -403,28 +403,39 @@ make_dir_parents_private (char const *const_dir, size_t src_offset,
slash++;
while ((slash = strchr (slash, '/')))
{
- int src_errno;
- /* Add this directory to the list of directories whose modes need
- fixing later. */
- struct dir_attr *new = xmalloc (sizeof *new);
- new->slash_offset = slash - dir;
- new->restore_mode = false;
- new->next = *attr_list;
- *attr_list = new;
+ struct dir_attr *new IF_LINT (= NULL);
+ bool missing_dir;
*slash = '\0';
- src_errno = (stat (src, &new->st) != 0
- ? errno
- : S_ISDIR (new->st.st_mode)
- ? 0
- : ENOTDIR);
- if (src_errno)
+ missing_dir = (stat (dir, &stats) != 0);
+
+ if (missing_dir | x->preserve_ownership | x->preserve_mode
+ | x->preserve_timestamps)
{
- error (0, src_errno, _("failed to get attributes of %s"),
- quote (src));
- return false;
+ /* Add this directory to the list of directories whose
+ modes might need fixing later. */
+ struct stat src_st;
+ int src_errno = (stat (src, &src_st) != 0
+ ? errno
+ : S_ISDIR (src_st.st_mode)
+ ? 0
+ : ENOTDIR);
+ if (src_errno)
+ {
+ error (0, src_errno, _("failed to get attributes of %s"),
+ quote (src));
+ return false;
+ }
+
+ new = xmalloc (sizeof *new);
+ new->st = src_st;
+ new->slash_offset = slash - dir;
+ new->restore_mode = false;
+ new->next = *attr_list;
+ *attr_list = new;
}
- if (stat (dir, &stats) != 0)
+
+ if (missing_dir)
{
mode_t src_mode;
mode_t omitted_permissions;