summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2022-08-14 23:16:42 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2022-08-15 00:07:39 -0700
commite49537dcdf0b35f2425402f3b5d77669c9b4aed9 (patch)
tree04c07e5ec63e8fd4c9a1a8bcce506874cb7a2fef
parent66be5a789e70f911170017754fc51e499998f90e (diff)
downloadtar-e49537dcdf0b35f2425402f3b5d77669c9b4aed9.tar.gz
Improve performance a bit on non-birthtime hosts
* src/extract.c (HAVE_BIRTHTIME, BIRTHTIME_EQ): New macros. (struct delayed_link, create_placeholder_file, extract_link) (apply_delayed_links): Avoid unnecessary work on platforms like GNU/Linux that lack birthtime.
-rw-r--r--src/extract.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/extract.c b/src/extract.c
index 6d2543f0..93ad719e 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -41,6 +41,21 @@ static mode_t current_umask; /* current umask (which is set to 0 if -p) */
# define fchown(fd, uid, gid) (errno = ENOSYS, -1)
#endif
+#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
+ || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC \
+ || defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC \
+ || (defined _WIN32 && ! defined __CYGWIN__))
+# define HAVE_BIRTHTIME 1
+#else
+# define HAVE_BIRTHTIME 0
+#endif
+
+#if HAVE_BIRTHTIME
+# define BIRTHTIME_EQ(a, b) (timespec_cmp (a, b) == 0)
+#else
+# define BIRTHTIME_EQ(a, b) true
+#endif
+
/* Return true if an error number ERR means the system call is
supported in this case. */
static bool
@@ -127,7 +142,9 @@ struct delayed_link
when restoring hard-linked symlinks. */
dev_t dev;
ino_t ino;
+#if HAVE_BIRTHTIME
struct timespec birthtime;
+#endif
/* True if the link is symbolic. */
bool is_symlink;
@@ -1434,7 +1451,9 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made,
}
p->dev = st.st_dev;
p->ino = st.st_ino;
+#if HAVE_BIRTHTIME
p->birthtime = get_stat_birthtime (&st);
+#endif
p->is_symlink = is_symlink;
if (is_symlink)
{
@@ -1500,8 +1519,7 @@ extract_link (char *file_name, int typeflag)
if (ds->change_dir == chdir_current
&& ds->dev == st1.st_dev
&& ds->ino == st1.st_ino
- && (timespec_cmp (ds->birthtime, get_stat_birthtime (&st1))
- == 0))
+ && BIRTHTIME_EQ (ds->birthtime, get_stat_birthtime (&st1)))
{
struct string_list *p = xmalloc (offsetof (struct string_list, string)
+ strlen (file_name) + 1);
@@ -1859,7 +1877,7 @@ apply_delayed_links (void)
if (fstatat (chdir_fd, source, &st, AT_SYMLINK_NOFOLLOW) == 0
&& st.st_dev == ds->dev
&& st.st_ino == ds->ino
- && timespec_cmp (get_stat_birthtime (&st), ds->birthtime) == 0)
+ && BIRTHTIME_EQ (get_stat_birthtime (&st), ds->birthtime))
{
/* Unlink the placeholder, then create a hard link if possible,
a symbolic link otherwise. */