xz: Fix use of wrong variable in a fcntl() call.

Due to a wrong variable name, when writing a sparse file
to standard output, *all* file status flags were cleared
(to the extent the operating system allowed it) instead of
only clearing the O_APPEND flag. In practice this worked
fine in the common situations on GNU/Linux, but I didn't
check how it behaved elsewhere.

The original flags were still restored correctly. I still
changed the code to use a separate boolean variable to
indicate when the flags should be restored instead of
relying on a special value in stdout_flags.
This commit is contained in:
Lasse Collin 2013-06-28 17:36:47 +03:00
parent b790b435da
commit 4a08a6e4c6
1 changed files with 13 additions and 11 deletions

View File

@ -41,9 +41,10 @@ static bool warn_fchown;
static bool try_sparse = true; static bool try_sparse = true;
#ifndef TUKLIB_DOSLIKE #ifndef TUKLIB_DOSLIKE
/// File status flags of standard output. This is used by io_open_dest() /// Original file status flags of standard output. This is used by
/// and io_close_dest(). /// io_open_dest() and io_close_dest() to save and restore the flags.
static int stdout_flags = 0; static int stdout_flags;
static bool restore_stdout_flags = false;
#endif #endif
@ -676,11 +677,11 @@ io_open_dest_real(file_pair *pair)
if (!S_ISREG(pair->dest_st.st_mode)) if (!S_ISREG(pair->dest_st.st_mode))
return false; return false;
const int flags = fcntl(STDOUT_FILENO, F_GETFL); stdout_flags = fcntl(STDOUT_FILENO, F_GETFL);
if (flags == -1) if (stdout_flags == -1)
return false; return false;
if (flags & O_APPEND) { if (stdout_flags & O_APPEND) {
// Creating a sparse file is not possible // Creating a sparse file is not possible
// when O_APPEND is active (it's used by // when O_APPEND is active (it's used by
// shell's >> redirection). As I understand // shell's >> redirection). As I understand
@ -702,9 +703,10 @@ io_open_dest_real(file_pair *pair)
stdout_flags & ~O_APPEND)) stdout_flags & ~O_APPEND))
return false; return false;
// Remember the flags so that io_close_dest() // Disabling O_APPEND succeeded. Mark
// can restore them. // that the flags should be restored
stdout_flags = flags; // in io_close_dest().
restore_stdout_flags = true;
} else if (lseek(STDOUT_FILENO, 0, SEEK_CUR) } else if (lseek(STDOUT_FILENO, 0, SEEK_CUR)
!= pair->dest_st.st_size) { != pair->dest_st.st_size) {
@ -745,11 +747,11 @@ io_close_dest(file_pair *pair, bool success)
{ {
#ifndef TUKLIB_DOSLIKE #ifndef TUKLIB_DOSLIKE
// If io_open_dest() has disabled O_APPEND, restore it here. // If io_open_dest() has disabled O_APPEND, restore it here.
if (stdout_flags != 0) { if (restore_stdout_flags) {
assert(pair->dest_fd == STDOUT_FILENO); assert(pair->dest_fd == STDOUT_FILENO);
const int fail = fcntl(STDOUT_FILENO, F_SETFL, stdout_flags); const int fail = fcntl(STDOUT_FILENO, F_SETFL, stdout_flags);
stdout_flags = 0; restore_stdout_flags = false;
if (fail) { if (fail) {
message_error(_("Error restoring the O_APPEND flag " message_error(_("Error restoring the O_APPEND flag "