aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-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.