aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2013-06-28 17:36:47 +0300
committerLasse Collin <lasse.collin@tukaani.org>2013-06-28 17:36:47 +0300
commit4a08a6e4c61c65ab763ab314100a6d7a3bb89298 (patch)
tree99b63393518fc33e3ba40a0c32c36531deb639d5
parentxz: Fix assertion related to posix_fadvise(). (diff)
downloadxz-4a08a6e4c61c65ab763ab314100a6d7a3bb89298.tar.xz
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.
Diffstat (limited to '')
-rw-r--r--src/xz/file_io.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/src/xz/file_io.c b/src/xz/file_io.c
index 61b10f98..df758fdf 100644
--- a/src/xz/file_io.c
+++ b/src/xz/file_io.c
@@ -41,9 +41,10 @@ static bool warn_fchown;
static bool try_sparse = true;
#ifndef TUKLIB_DOSLIKE
-/// File status flags of standard output. This is used by io_open_dest()
-/// and io_close_dest().
-static int stdout_flags = 0;
+/// Original file status flags of standard output. This is used by
+/// io_open_dest() and io_close_dest() to save and restore the flags.
+static int stdout_flags;
+static bool restore_stdout_flags = false;
#endif
@@ -676,11 +677,11 @@ io_open_dest_real(file_pair *pair)
if (!S_ISREG(pair->dest_st.st_mode))
return false;
- const int flags = fcntl(STDOUT_FILENO, F_GETFL);
- if (flags == -1)
+ stdout_flags = fcntl(STDOUT_FILENO, F_GETFL);
+ if (stdout_flags == -1)
return false;
- if (flags & O_APPEND) {
+ if (stdout_flags & O_APPEND) {
// Creating a sparse file is not possible
// when O_APPEND is active (it's used by
// shell's >> redirection). As I understand
@@ -702,9 +703,10 @@ io_open_dest_real(file_pair *pair)
stdout_flags & ~O_APPEND))
return false;
- // Remember the flags so that io_close_dest()
- // can restore them.
- stdout_flags = flags;
+ // Disabling O_APPEND succeeded. Mark
+ // that the flags should be restored
+ // in io_close_dest().
+ restore_stdout_flags = true;
} else if (lseek(STDOUT_FILENO, 0, SEEK_CUR)
!= pair->dest_st.st_size) {
@@ -745,11 +747,11 @@ io_close_dest(file_pair *pair, bool success)
{
#ifndef TUKLIB_DOSLIKE
// 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);
const int fail = fcntl(STDOUT_FILENO, F_SETFL, stdout_flags);
- stdout_flags = 0;
+ restore_stdout_flags = false;
if (fail) {
message_error(_("Error restoring the O_APPEND flag "