[Top][All Lists]
[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)