summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@linbit.com>2011-12-09 00:53:38 +0100
committerAndreas Gruenbacher <agruen@linbit.com>2011-12-09 00:53:38 +0100
commit5ca55b84143a840218bcdc78120b44b02d8ef561 (patch)
tree0195e4d4851446ab08e00d30a0e8bc67b299e1be
parent17086c5cf2656df6f1dd4db7970a20ed519267ea (diff)
downloadpatch-5ca55b84143a840218bcdc78120b44b02d8ef561.tar.gz
Timestamp not set when creating files with --set-time or --set-utc
* src/util.h (enum file_attributes): Add FA_XATTRS flag for extended attributes. * src/patch.c (main): Use set_file_attributes() even when the infile doesn't exist: it may still set the file time (FA_TIMES). Omit all other FA_ flags if infile doesn't exist. Otherwise, add FA_XATTRS as well. * src/util.c (set_file_attributes): Only copy extended attributes if FA_XATTRS is set. Avoid using st where it may be undefined. * tests/preserve-mode-and-timestamp: Add file create test.
-rw-r--r--src/patch.c12
-rw-r--r--src/util.c11
-rw-r--r--src/util.h3
-rw-r--r--tests/preserve-mode-and-timestamp17
4 files changed, 34 insertions, 9 deletions
diff --git a/src/patch.c b/src/patch.c
index d73aaaf..4764e0d 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -471,7 +471,7 @@ main (int argc, char **argv)
if (failed < hunk || diff_type == ED_DIFF || set_mode
|| pch_copy () || pch_rename ())
{
- enum file_attributes attr = FA_IDS | FA_MODE;
+ enum file_attributes attr = 0;
struct timespec new_time = pch_timestamp (! reverse);
mode_t mode = file_type |
((new_mode ? new_mode : instat.st_mode) & S_IRWXUGO);
@@ -496,9 +496,15 @@ main (int argc, char **argv)
attr |= FA_TIMES;
}
- if (! inerrno)
- set_file_attributes (TMPOUTNAME, attr, inname, &instat,
+ if (inerrno)
+ set_file_attributes (TMPOUTNAME, attr, NULL, NULL,
mode, &new_time);
+ else
+ {
+ attr |= FA_IDS | FA_MODE | FA_XATTRS;
+ set_file_attributes (TMPOUTNAME, attr, inname, &instat,
+ mode, &new_time);
+ }
assert (outst.st_size != -1);
move_file (TMPOUTNAME, &TMPOUTNAME_needs_removal, &outst,
diff --git a/src/util.c b/src/util.c
index 89a3f49..6ffc6cc 100644
--- a/src/util.c
+++ b/src/util.c
@@ -203,7 +203,7 @@ set_file_attributes (char const *to, enum file_attributes attr,
}
if (lutimens (to, times) != 0)
pfatal ("Failed to set the timestamps of %s %s",
- S_ISLNK (st->st_mode) ? "symbolic link" : "file",
+ S_ISLNK (mode) ? "symbolic link" : "file",
quotearg (to));
}
if (attr & FA_IDS)
@@ -231,11 +231,12 @@ set_file_attributes (char const *to, enum file_attributes attr,
&& errno != EPERM)))
pfatal ("Failed to set the %s of %s %s",
(uid == -1) ? "owner" : "owning group",
- S_ISLNK (st->st_mode) ? "symbolic link" : "file",
+ S_ISLNK (mode) ? "symbolic link" : "file",
quotearg (to));
}
- if (copy_attr (from, to))
- fatal_exit (0);
+ if (attr & FA_XATTRS)
+ if (copy_attr (from, to))
+ fatal_exit (0);
/* FIXME: There may be other attributes to preserve. */
if (attr & FA_MODE)
{
@@ -248,7 +249,7 @@ set_file_attributes (char const *to, enum file_attributes attr,
if (! S_ISLNK (mode) && chmod (to, mode) != 0)
#endif
pfatal ("Failed to set the permissions of %s %s",
- S_ISLNK (st->st_mode) ? "symbolic link" : "file",
+ S_ISLNK (mode) ? "symbolic link" : "file",
quotearg (to));
}
}
diff --git a/src/util.h b/src/util.h
index a8d0188..26a9a21 100644
--- a/src/util.h
+++ b/src/util.h
@@ -67,7 +67,8 @@ bool file_already_seen (struct stat const *);
enum file_attributes {
FA_TIMES = 1,
FA_IDS = 2,
- FA_MODE = 4
+ FA_MODE = 4,
+ FA_XATTRS = 8
};
void set_file_attributes (char const *, enum file_attributes, char const *,
diff --git a/tests/preserve-mode-and-timestamp b/tests/preserve-mode-and-timestamp
index 9e27955..855d95c 100644
--- a/tests/preserve-mode-and-timestamp
+++ b/tests/preserve-mode-and-timestamp
@@ -102,3 +102,20 @@ EOF
check 'ls -l f.rej | sed "s,\(..........\).*,\1,"' <<EOF
-rw-r-----
EOF
+
+# ==============================================================
+
+cat > f.diff <<EOF
+--- /dev/null
++++ b/f $timestamp2
+@@ -0,0 +1 @@
++one
+EOF
+
+rm -f f
+
+check 'patch -p1 --backup --set-utc < f.diff' <<EOF
+patching file f
+EOF
+
+ncheck 'test ! \( f -ot f.compare -o f -nt f.compare \) || echo "timstamp differs"'