diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-12-09 00:53:38 +0100 |
---|---|---|
committer | Andreas Gruenbacher <agruen@linbit.com> | 2011-12-09 00:53:38 +0100 |
commit | 5ca55b84143a840218bcdc78120b44b02d8ef561 (patch) | |
tree | 0195e4d4851446ab08e00d30a0e8bc67b299e1be | |
parent | 17086c5cf2656df6f1dd4db7970a20ed519267ea (diff) | |
download | patch-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.c | 12 | ||||
-rw-r--r-- | src/util.c | 11 | ||||
-rw-r--r-- | src/util.h | 3 | ||||
-rw-r--r-- | tests/preserve-mode-and-timestamp | 17 |
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, @@ -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)); } } @@ -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"' |