bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-tar] BUG: incorrectly creates hard links in archive


From: Paul Eggert
Subject: Re: [Bug-tar] BUG: incorrectly creates hard links in archive
Date: Fri, 09 Jul 2004 23:18:12 -0700
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

Toby Peterson <address@hidden> writes:

> I'm not sure what the best solution is

How about if 'tar' doesn't report an error when it tries to create a
hard link that already exists?  I installed the following patch into
GNU tar CVS to do this.  Thanks for reporting the problem.

I should mention that if you're trying to write portable scripts, you
shouldn't rely on this solution, as traditional tar behaves in the
same way that you're objecting to.

2004-07-09  Paul Eggert  <address@hidden>

        * src/extract.c (extract_archive): Do not report an error
        when hard-linking X to X when X exists.  Problem reported by
        Toby Peterson.

--- extract.c.~1.62.~   2004-06-29 03:11:13 -0700
+++ extract.c   2004-07-09 23:08:21 -0700
@@ -925,11 +925,12 @@ extract_archive (void)
        /* MSDOS does not implement links.  However, djgpp's link() actually
           copies the file.  */
        status = link (link_name, file_name);
+       e = errno;
 
        if (status == 0)
          {
            struct delayed_symlink *ds = delayed_symlink_head;
-           if (ds && stat (link_name, &st1) == 0)
+           if (ds && lstat (link_name, &st1) == 0)
              for (; ds; ds = ds->next)
                if (ds->dev == st1.st_dev
                    && ds->ino == st1.st_ino
@@ -945,17 +946,20 @@ extract_archive (void)
                  }
            break;
          }
+
+       if ((e == EEXIST && strcmp (link_name, file_name) == 0)
+           || (lstat (link_name, &st1) == 0
+               && lstat (file_name, &st2) == 0
+               && st1.st_dev == st2.st_dev
+               && st1.st_ino == st2.st_ino))
+         break;
+
+       errno = e;
        if (maybe_recoverable (file_name, &interdir_made))
          goto again_link;
 
        if (incremental_option && errno == EEXIST)
          break;
-       e = errno;
-       if (stat (link_name, &st1) == 0
-           && stat (file_name, &st2) == 0
-           && st1.st_dev == st2.st_dev
-           && st1.st_ino == st2.st_ino)
-         break;
 
        link_error (link_name, file_name);
        if (backup_option)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]