xz: Fix use of wrong variable in a fcntl() call.
authorLasse Collin <lasse.collin@tukaani.org>
Fri, 28 Jun 2013 14:36:47 +0000 (17:36 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Fri, 28 Jun 2013 14:36:47 +0000 (17:36 +0300)
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.

src/xz/file_io.c

index 61b10f9..df758fd 100644 (file)
@@ -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 "