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:
parent
b790b435da
commit
4a08a6e4c6
|
@ -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 "
|
||||||
|
|
Loading…
Reference in New Issue