From 57c2124d68aa65843548feef9d226fb025503258 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 8 Nov 2005 07:20:02 +0000 Subject: [PATCH] * src/tar.c (NS_PRECISION_FORMAT_MASK): New macro. (tar_timespec_cmp): New function. Wrapper over timespec_cmp using the timespec precision provided by the current archive format. * src/common.h (tar_timespec_cmp): New declaration. * src/compare.c (diff_file): Use tar_timespec_cmp. * src/extract.c (file_newer_p): Likewise. * src/update.c (update_archive): Likewise. * tests/truncate.at: Reverted changes * tests/update.at: Reverted changes --- ChangeLog | 20 +++++++++++++++++--- src/common.h | 1 + src/compare.c | 3 ++- src/extract.c | 2 +- src/tar.c | 26 ++++++++++++++++++++------ src/update.c | 6 +++--- tests/truncate.at | 1 - tests/update.at | 1 - 8 files changed, 44 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9666868..088f85a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,22 @@ +2005-11-07 Sergey Poznyakoff + and Paul Eggert + + * src/tar.c (NS_PRECISION_FORMAT_MASK): New macro. + (tar_timespec_cmp): New function. Wrapper over + timespec_cmp using the timespec precision provided by the + current archive format. + * src/common.h (tar_timespec_cmp): New declaration. + * src/compare.c (diff_file): Use tar_timespec_cmp. + * src/extract.c (file_newer_p): Likewise. + * src/update.c (update_archive): Likewise. + * tests/truncate.at: Reverted changes + * tests/update.at: Reverted changes + 2005-11-07 Sergey Poznyakoff Support for incremental formats in pax archives. Fixed POSIX compatibility of `sparse' extended header keywords. - + * src/common.h (dumpdir_size,get_gnu_dumpdir) (xheader_string_begin,xheader_string_add) (xheader_string_end): New functions. @@ -39,14 +53,14 @@ (xheader_finish): Do not rely om strlen to compute the length of the collected string: it can contain embedded nulls (xheader_string_begin,xheader_string_add,xheader_string_end): New - functions. + functions. (sparse_map_decoder,dumpdir_coder,dumpdir_decoder): New functions. Handle GNU.sparse.map and GNU.dumpdir variables. (xhdr_tab): Add new variables. * tests/incr01.at: Test gnu, oldgnu, and posix formats * tests/incremental.at: Likewise - + 2005-11-06 Paul Eggert * src/xheader.c (strtoimax, strtoumax): Remove decls; now done diff --git a/src/common.h b/src/common.h index 4ac5d62..c1effd4 100644 --- a/src/common.h +++ b/src/common.h @@ -600,6 +600,7 @@ void request_stdin (const char *); void tar_stat_init (struct tar_stat_info *st); void tar_stat_destroy (struct tar_stat_info *st); void usage (int) __attribute__ ((noreturn)); +int tar_timespec_cmp (struct timespec a, struct timespec b); /* Module update.c. */ diff --git a/src/compare.c b/src/compare.c index 70d7251..0173363 100644 --- a/src/compare.c +++ b/src/compare.c @@ -224,7 +224,8 @@ diff_file (void) if (!sys_compare_gid (&stat_data, ¤t_stat_info.stat)) report_difference (¤t_stat_info, _("Gid differs")); - if (timespec_cmp (get_stat_mtime (&stat_data), current_stat_info.mtime)) + if (tar_timespec_cmp (get_stat_mtime (&stat_data), + current_stat_info.mtime)) report_difference (¤t_stat_info, _("Mod time differs")); if (current_header->header.typeflag != GNUTYPE_SPARSE && stat_data.st_size != current_stat_info.stat.st_size) diff --git a/src/extract.c b/src/extract.c index 2689f54..fbb93ed 100644 --- a/src/extract.c +++ b/src/extract.c @@ -469,7 +469,7 @@ file_newer_p (const char *file_name, struct tar_stat_info *tar_stat) return errno != ENOENT; } if (!S_ISDIR (st.st_mode) - && timespec_cmp (tar_stat->mtime, get_stat_mtime (&st)) <= 0) + && tar_timespec_cmp (tar_stat->mtime, get_stat_mtime (&st)) <= 0) { return true; } diff --git a/src/tar.c b/src/tar.c index a25f2ce..7736993 100644 --- a/src/tar.c +++ b/src/tar.c @@ -162,7 +162,7 @@ archive_format_string (enum archive_format fmt) static void assert_format(unsigned fmt_mask) { - if ((FORMAT_MASK(archive_format) & fmt_mask) == 0) + if ((FORMAT_MASK (archive_format) & fmt_mask) == 0) USAGE_ERROR ((0, 0, _("GNU features wanted on incompatible archive format"))); } @@ -314,7 +314,7 @@ static struct argp_option options[] = { {"occurrence", OCCURRENCE_OPTION, N_("NUMBER"), OPTION_ARG_OPTIONAL, N_("process only the NUMBERth occurrence of each file in the archive. This option is valid only in conjunction with one of the subcommands --delete, --diff, --extract or --list and when a list of files is given either on the command line or via -T option. NUMBER defaults to 1."), 21 }, {"seek", 'n', NULL, 0, - N_("archive is seekable"), 21 }, + N_("archive is seekable"), 21 }, {NULL, 0, NULL, 0, N_("Overwrite control:"), 30}, @@ -557,7 +557,7 @@ static struct argp_option options[] = { {"show-stored-names", SHOW_STORED_NAMES_OPTION, 0, 0, N_("When creating archive in verbose mode, list member names as stored in the archive"), 102 }, - + {NULL, 0, NULL, 0, N_("Compatibility options:"), 110 }, @@ -1047,7 +1047,7 @@ parse_opt (int key, char *arg, struct argp_state *state) set_subcommand_option (LIST_SUBCOMMAND); test_label_option = true; break; - + case 'T': update_argv (arg, state); /* Indicate we've been given -T option. This is for backward @@ -1323,7 +1323,7 @@ parse_opt (int key, char *arg, struct argp_state *state) case SHOW_STORED_NAMES_OPTION: show_stored_names_option = true; break; - + case SUFFIX_OPTION: backup_option = true; args->backup_suffix_string = arg; @@ -1679,7 +1679,7 @@ decode_options (int argc, char **argv) if (multi_volume_option) assert_format (FORMAT_MASK (OLDGNU_FORMAT) | FORMAT_MASK (GNU_FORMAT)); - + if (sparse_option) assert_format (FORMAT_MASK (OLDGNU_FORMAT) | FORMAT_MASK (GNU_FORMAT) @@ -1981,3 +1981,17 @@ tar_stat_destroy (struct tar_stat_info *st) free (st->dumpdir); memset (st, 0, sizeof (*st)); } + +/* Format mask for all available formats that support nanosecond + timestamp resolution. */ +#define NS_PRECISION_FORMAT_MASK FORMAT_MASK (POSIX_FORMAT) + +/* Same as timespec_cmp, but ignore nanoseconds if current archive + format does not provide sufficient resolution. */ +int +tar_timespec_cmp (struct timespec a, struct timespec b) +{ + if (!(FORMAT_MASK (current_format) & NS_PRECISION_FORMAT_MASK)) + a.tv_nsec = b.tv_nsec = 0; + return timespec_cmp (a, b); +} diff --git a/src/update.c b/src/update.c index f28c6dc..6546b03 100644 --- a/src/update.c +++ b/src/update.c @@ -1,7 +1,7 @@ /* Update a tar archive. Copyright (C) 1988, 1992, 1994, 1996, 1997, 1999, 2000, 2001, 2003, - 2004 Free Software Foundation, Inc. + 2004, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -138,8 +138,8 @@ update_archive (void) chdir_do (name->change_dir); if (deref_stat (dereference_option, current_stat_info.file_name, &s) == 0 - && (timespec_cmp (get_stat_mtime (&s), - current_stat_info.mtime) + && (tar_timespec_cmp (get_stat_mtime (&s), + current_stat_info.mtime) <= 0)) add_avoided_name (current_stat_info.file_name); } diff --git a/tests/truncate.at b/tests/truncate.at index 676d794..561d103 100644 --- a/tests/truncate.at +++ b/tests/truncate.at @@ -31,7 +31,6 @@ AT_KEYWORDS([truncated files]) AT_TAR_CHECK([ genfile --file foo --length 50000k genfile --file baz -touch -t 197001030000 baz # avoid subsecond resolution genfile --run 'tar -vcf bar foo baz' --checkpoint 10 --length 49995k --truncate foo echo separator sleep 1 diff --git a/tests/update.at b/tests/update.at index 56aecf7..067c634 100644 --- a/tests/update.at +++ b/tests/update.at @@ -31,7 +31,6 @@ AT_TAR_CHECK([ mkdir directory genfile --length 10240 --pattern zeros --file directory/file1 genfile --length 10240 --pattern default --file directory/file2 -touch -t 197001030000 directory directory/* # avoid subsecond resolution tar cf archive directory || exit 1 echo separator -- 2.44.0