install: When preserving timestamps, also copy the nanoseconds part.

Now that we have utimensat in -legacy, install(1) can use it.

This is a revert of r299942 which is itself a revert of r299850.
This commit is contained in:
Jilles Tjoelker
2016-06-09 21:59:35 +00:00
parent 932a6e432d
commit 649a3a5626
2 changed files with 20 additions and 17 deletions
+7
View File
@@ -64,6 +64,12 @@ copy_to_nonexistent_backup_safe_body() {
copy_to_nonexistent_with_opts -b -B.bak -S copy_to_nonexistent_with_opts -b -B.bak -S
} }
atf_test_case copy_to_nonexistent_preserving
copy_to_nonexistent_preserving_body() {
copy_to_nonexistent_with_opts -p
[ ! testf -ot copyf ] || atf_fail "bad timestamp 2"
}
copy_self_with_opts() { copy_self_with_opts() {
printf 'test\n123\r456\r\n789\0z' >testf printf 'test\n123\r456\r\n789\0z' >testf
printf 'test\n123\r456\r\n789\0z' >testf2 printf 'test\n123\r456\r\n789\0z' >testf2
@@ -307,6 +313,7 @@ atf_init_test_cases() {
atf_add_test_case copy_to_nonexistent_safe_comparing atf_add_test_case copy_to_nonexistent_safe_comparing
atf_add_test_case copy_to_nonexistent_backup atf_add_test_case copy_to_nonexistent_backup
atf_add_test_case copy_to_nonexistent_backup_safe atf_add_test_case copy_to_nonexistent_backup_safe
atf_add_test_case copy_to_nonexistent_preserving
atf_add_test_case copy_self atf_add_test_case copy_self
atf_add_test_case copy_self_safe atf_add_test_case copy_self_safe
atf_add_test_case copy_self_comparing atf_add_test_case copy_self_comparing
+13 -17
View File
@@ -131,7 +131,7 @@ static void do_symlink(const char *, const char *, const struct stat *);
static void makelink(const char *, const char *, const struct stat *); static void makelink(const char *, const char *, const struct stat *);
static void install(const char *, const char *, u_long, u_int); static void install(const char *, const char *, u_long, u_int);
static void install_dir(char *); static void install_dir(char *);
static void metadata_log(const char *, const char *, struct timeval *, static void metadata_log(const char *, const char *, struct timespec *,
const char *, const char *, off_t); const char *, const char *, off_t);
static int parseid(const char *, id_t *); static int parseid(const char *, id_t *);
static void strip(const char *); static void strip(const char *);
@@ -722,7 +722,7 @@ static void
install(const char *from_name, const char *to_name, u_long fset, u_int flags) install(const char *from_name, const char *to_name, u_long fset, u_int flags)
{ {
struct stat from_sb, temp_sb, to_sb; struct stat from_sb, temp_sb, to_sb;
struct timeval tvb[2]; struct timespec tsb[2];
int devnull, files_match, from_fd, serrno, target; int devnull, files_match, from_fd, serrno, target;
int tempcopy, temp_fd, to_fd; int tempcopy, temp_fd, to_fd;
char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN]; char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN];
@@ -857,11 +857,9 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
* Need to preserve target file times, though. * Need to preserve target file times, though.
*/ */
if (to_sb.st_nlink != 1) { if (to_sb.st_nlink != 1) {
tvb[0].tv_sec = to_sb.st_atime; tsb[0] = to_sb.st_atim;
tvb[0].tv_usec = 0; tsb[1] = to_sb.st_mtim;
tvb[1].tv_sec = to_sb.st_mtime; (void)utimensat(AT_FDCWD, tempfile, tsb, 0);
tvb[1].tv_usec = 0;
(void)utimes(tempfile, tvb);
} else { } else {
files_match = 1; files_match = 1;
(void)unlink(tempfile); (void)unlink(tempfile);
@@ -916,11 +914,9 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
* Preserve the timestamp of the source file if necessary. * Preserve the timestamp of the source file if necessary.
*/ */
if (dopreserve && !files_match && !devnull) { if (dopreserve && !files_match && !devnull) {
tvb[0].tv_sec = from_sb.st_atime; tsb[0] = from_sb.st_atim;
tvb[0].tv_usec = 0; tsb[1] = from_sb.st_mtim;
tvb[1].tv_sec = from_sb.st_mtime; (void)utimensat(AT_FDCWD, to_name, tsb, 0);
tvb[1].tv_usec = 0;
(void)utimes(to_name, tvb);
} }
if (fstat(to_fd, &to_sb) == -1) { if (fstat(to_fd, &to_sb) == -1) {
@@ -989,7 +985,7 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
if (!devnull) if (!devnull)
(void)close(from_fd); (void)close(from_fd);
metadata_log(to_name, "file", tvb, NULL, digestresult, to_sb.st_size); metadata_log(to_name, "file", tsb, NULL, digestresult, to_sb.st_size);
free(digestresult); free(digestresult);
} }
@@ -1301,7 +1297,7 @@ install_dir(char *path)
* or to allow integrity checks to be performed. * or to allow integrity checks to be performed.
*/ */
static void static void
metadata_log(const char *path, const char *type, struct timeval *tv, metadata_log(const char *path, const char *type, struct timespec *ts,
const char *slink, const char *digestresult, off_t size) const char *slink, const char *digestresult, off_t size)
{ {
static const char extra[] = { ' ', '\t', '\n', '\\', '#', '\0' }; static const char extra[] = { ' ', '\t', '\n', '\\', '#', '\0' };
@@ -1355,9 +1351,9 @@ metadata_log(const char *path, const char *type, struct timeval *tv,
} }
if (*type == 'f') /* type=file */ if (*type == 'f') /* type=file */
fprintf(metafp, " size=%lld", (long long)size); fprintf(metafp, " size=%lld", (long long)size);
if (tv != NULL && dopreserve) if (ts != NULL && dopreserve)
fprintf(metafp, " time=%lld.%ld", fprintf(metafp, " time=%lld.%09ld",
(long long)tv[1].tv_sec, (long)tv[1].tv_usec); (long long)ts[1].tv_sec, ts[1].tv_nsec);
if (digestresult && digest) if (digestresult && digest)
fprintf(metafp, " %s=%s", digest, digestresult); fprintf(metafp, " %s=%s", digest, digestresult);
if (fflags) if (fflags)