xz: Always close the file before trying to delete it.

unlink() can return EBUSY in errno for open files on some
operating systems and file systems.
This commit is contained in:
Lasse Collin 2015-11-02 15:19:10 +02:00
parent f59c4183f3
commit d9311647fc
1 changed files with 13 additions and 14 deletions

View File

@ -675,23 +675,22 @@ io_close_src(file_pair *pair, bool success)
#endif #endif
if (pair->src_fd != STDIN_FILENO && pair->src_fd != -1) { if (pair->src_fd != STDIN_FILENO && pair->src_fd != -1) {
#ifdef TUKLIB_DOSLIKE // Close the file before possibly unlinking it. On DOS-like
(void)close(pair->src_fd); // systems this is always required since unlinking will fail
#endif // if the file is open. On POSIX systems it usually works
// to unlink open files, but in some cases it doesn't and
// If we are going to unlink(), do it before closing the file. // one gets EBUSY in errno.
// This way there's no risk that someone replaces the file and
// happens to get same inode number, which would make us
// unlink() wrong file.
// //
// NOTE: DOS-like systems are an exception to this, because // xz 5.2.2 and older unlinked the file before closing it
// they don't allow unlinking files that are open. *sigh* // (except on DOS-like systems). The old code didn't handle
// EBUSY and could fail e.g. on some CIFS shares. The
// advantage of unlinking before closing is negligible
// (avoids a race between close() and stat()/lstat() and
// unlink()), so let's keep this simple.
(void)close(pair->src_fd);
if (success && !opt_keep_original) if (success && !opt_keep_original)
io_unlink(pair->src_name, &pair->src_st); io_unlink(pair->src_name, &pair->src_st);
#ifndef TUKLIB_DOSLIKE
(void)close(pair->src_fd);
#endif
} }
return; return;