aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2010-02-01 11:44:45 +0200
committerLasse Collin <lasse.collin@tukaani.org>2010-02-01 11:44:45 +0200
commit82220a149015616f75641ee8bbea415137535b9b (patch)
tree38e42353006169fe779c3c2106eedc6dc3ac582d
parentFix a comment. (diff)
downloadxz-82220a149015616f75641ee8bbea415137535b9b.tar.xz
Fix compression of symlinks with --force.
xz --force accepted symlinks, but didn't remove them after successful compression. Instead, an error message was displayed.
-rw-r--r--src/xz/file_io.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/xz/file_io.c b/src/xz/file_io.c
index c1bca196..020f33dd 100644
--- a/src/xz/file_io.c
+++ b/src/xz/file_io.c
@@ -100,7 +100,19 @@ io_unlink(const char *name, const struct stat *known_st)
#else
struct stat new_st;
- if (lstat(name, &new_st)
+ // If --force was used, use stat() instead of lstat(). This way
+ // (de)compressing symlinks works correctly. However, it also means
+ // that xz cannot detect if a regular file foo is renamed to bar
+ // and then a symlink foo -> bar is created. Because of stat()
+ // instead of lstat(), xz will think that foo hasn't been replaced
+ // with another file. Thus, xz will remove foo even though it no
+ // longer is the same file that xz used when it started compressing.
+ // Probably it's not too bad though, so this doesn't need a more
+ // complex fix.
+ const int stat_ret = opt_force
+ ? stat(name, &new_st) : lstat(name, &new_st);
+
+ if (stat_ret
# ifdef __VMS
// st_ino is an array, and we don't want to
// compare st_dev at all.