]> Dogcows Code - chaz/tar/blobdiff - src/incremen.c
* src/compare.c (diff_dumpdir): Omit useless 'stat'.
[chaz/tar] / src / incremen.c
index afd19af66ae7e67db457669f3c1e4d1579d345ad..04b946f62bdc07f65cc3f48210978b59551b57c8 100644 (file)
@@ -300,6 +300,24 @@ dirlist_replace_prefix (const char *pref, const char *repl)
     replace_prefix (&dp->name, pref, pref_len, repl, repl_len);
 }
 
+void
+clear_directory_table (void)
+{
+  struct directory *dp;
+
+  if (directory_table)
+    hash_clear (directory_table);
+  if (directory_meta_table)
+    hash_clear (directory_meta_table);
+  for (dp = dirhead; dp; )
+    {
+      struct directory *next = dp->next;
+      free_directory (dp);
+      dp = next;
+    }
+  dirhead = dirtail = NULL;
+}
+
 /* Create and link a new directory entry for directory NAME, having a
    device number DEV and an inode number INO, with NFS indicating
    whether it is an NFS device and FOUND indicating whether we have
@@ -327,7 +345,8 @@ note_directory (char const *name, struct timespec mtime,
   if (! ((directory_table
          || (directory_table = hash_initialize (0, 0,
                                                 hash_directory_canonical_name,
-                                                compare_directory_canonical_names, 0)))
+                                                compare_directory_canonical_names,
+                                                0)))
         && hash_insert (directory_table, directory)))
     xalloc_die ();
 
@@ -408,7 +427,7 @@ update_parent_directory (struct tar_stat_info *parent)
   if (directory)
     {
       struct stat st;
-      if (fstatat (parent->fd, ".", &st, fstatat_flags) != 0)
+      if (fstat (parent->fd, &st) != 0)
        stat_diag (directory->name);
       else
        directory->mtime = get_stat_mtime (&st);
@@ -426,8 +445,6 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
 {
   struct directory *directory;
   struct stat *stat_data = &st->stat;
-  int fd = st->fd;
-  dev_t device = st->parent ? st->parent->stat.st_dev : 0;
   bool nfs = NFS_FILE_STAT (*stat_data);
 
   if ((directory = find_directory (name_buffer)) != NULL)
@@ -541,11 +558,8 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
        }
     }
 
-  /* If the directory is on another device and --one-file-system was given,
-     omit it... */
-  if (one_file_system_option && device != stat_data->st_dev
-      /* ... except if it was explicitely given in the command line */
-      && !is_individual_file (name_buffer))
+  if (one_file_system_option && st->parent
+      && stat_data->st_dev != st->parent->stat.st_dev)
     /* FIXME:
        WARNOPT (WARN_XDEV,
                 (0, 0,
@@ -566,7 +580,7 @@ procdir (const char *name_buffer, struct tar_stat_info *st,
     {
       const char *tag_file_name;
 
-      switch (check_exclusion_tags (fd, &tag_file_name))
+      switch (check_exclusion_tags (st, &tag_file_name))
        {
        case exclusion_tag_all:
          /* This warning can be duplicated by code in dump_file0, but only
@@ -680,8 +694,7 @@ struct directory *
 scan_directory (struct tar_stat_info *st)
 {
   char const *dir = st->orig_file_name;
-  int fd = st->fd;
-  char *dirp = 0;
+  char *dirp = get_directory_entries (st);
   dev_t device = st->stat.st_dev;
   bool cmdline = ! st->parent;
   namebuf_t nbuf;
@@ -689,18 +702,6 @@ scan_directory (struct tar_stat_info *st)
   struct directory *directory;
   char ch;
 
-  int dupfd = dup (fd);
-  if (0 <= dupfd)
-    {
-      dirp = fdsavedir (dupfd);
-      if (! dirp)
-       {
-         int e = errno;
-         close (dupfd);
-         errno = e;
-       }
-    }
-
   if (! dirp)
     savedir_error (dir);
 
@@ -734,19 +735,29 @@ scan_directory (struct tar_stat_info *st)
            *entry = 'N';
          else
            {
+             int fd = st->fd;
              void (*diag) (char const *) = 0;
              struct tar_stat_info stsub;
              tar_stat_init (&stsub);
 
-             if (fstatat (fd, entry + 1, &stsub.stat, fstatat_flags) != 0)
+             if (fd < 0)
+               {
+                 errno = - fd;
+                 diag = open_diag;
+               }
+             else if (fstatat (fd, entry + 1, &stsub.stat, fstatat_flags) != 0)
                diag = stat_diag;
              else if (S_ISDIR (stsub.stat.st_mode))
                {
-                 stsub.fd = openat (fd, entry + 1, open_read_flags);
-                 if (stsub.fd < 0)
+                 int subfd = subfile_open (st, entry + 1, open_read_flags);
+                 if (subfd < 0)
                    diag = open_diag;
-                 else if (fstat (stsub.fd, &stsub.stat) != 0)
-                   diag = stat_diag;
+                 else
+                   {
+                     stsub.fd = subfd;
+                     if (fstat (subfd, &stsub.stat) != 0)
+                       diag = stat_diag;
+                   }
                }
 
              if (diag)
@@ -762,7 +773,10 @@ scan_directory (struct tar_stat_info *st)
                  else if (directory->children == ALL_CHILDREN)
                    pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
                  *entry = 'D';
+
+                 stsub.parent = st;
                  procdir (full_name, &stsub, pd_flag, entry);
+                 restore_parent_fd (&stsub);
                }
              else if (one_file_system_option && device != stsub.stat.st_dev)
                *entry = 'N';
@@ -784,8 +798,7 @@ scan_directory (struct tar_stat_info *st)
 
   namebuf_free (nbuf);
 
-  if (dirp)
-    free (dirp);
+  free (dirp);
 
   return directory;
 }
@@ -835,7 +848,7 @@ store_rename (struct directory *dir, struct obstack *stk)
         are ignored when hit by this function next time.
         If the chain forms a cycle, prev points to the entry DIR is renamed
         from. In this case it still retains DIRF_RENAMED flag, which will be
-        cleared in the `else' branch below */
+        cleared in the 'else' branch below */
       for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
        DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
 
@@ -891,7 +904,8 @@ append_incremental_renames (struct directory *dir)
   for (dp = dirhead; dp; dp = dp->next)
     store_rename (dp, &stk);
 
-  if (obstack_object_size (&stk) != size)
+  /* FIXME: Is this the right thing to do when DIR is null?  */
+  if (dir && obstack_object_size (&stk) != size)
     {
       obstack_1grow (&stk, 0);
       dumpdir_free (dir->dump);
@@ -1352,8 +1366,7 @@ read_directory_file (void)
 
   if (ferror (listed_incremental_stream))
     read_error (listed_incremental_option);
-  if (buf)
-    free (buf);
+  free (buf);
 }
 
 /* Output incremental data for the directory ENTRY to the file DATA.
@@ -1664,11 +1677,10 @@ try_purge_directory (char const *directory_name)
     {
       const char *entry;
       struct stat st;
-      if (p)
-       free (p);
+      free (p);
       p = new_name (directory_name, cur);
 
-      if (deref_stat (false, p, &st))
+      if (deref_stat (p, &st) != 0)
        {
          if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed
                                  dirs and check it here? */
This page took 0.025287 seconds and 4 git commands to generate.