]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
xz: Don't fail if stdin doesn't support O_NONBLOCK.
authorLasse Collin <lasse.collin@tukaani.org>
Wed, 7 Jan 2015 17:08:06 +0000 (19:08 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Wed, 7 Jan 2015 17:08:06 +0000 (19:08 +0200)
It's a problem at least on OpenBSD which doesn't support
O_NONBLOCK on e.g. /dev/null. I'm not surprised if it's
a problem on other OSes too since this behavior is allowed
in POSIX-1.2008.

The code relying on this behavior was committed in June 2013
and included in 5.1.3alpha released on 2013-10-26. Clearly
the development releases only get limited testing.

src/xz/file_io.c

index f135cf7cb6bd8d4e4df61eee59a48ef98d377bd9..bf4462d965f5c2537738f51c9c423de8195cfd14 100644 (file)
@@ -393,7 +393,10 @@ io_open_src_real(file_pair *pair)
 #ifdef TUKLIB_DOSLIKE
                setmode(STDIN_FILENO, O_BINARY);
 #else
-               // Enable O_NONBLOCK for stdin.
+               // Try to set stdout to non-blocking mode. It won't work
+               // e.g. on OpenBSD if stdout is e.g. /dev/null. In such
+               // case we proceed as if stdout were non-blocking anyway
+               // (in case of /dev/null it will be in practice).
                stdin_flags = fcntl(STDIN_FILENO, F_GETFL);
                if (stdin_flags == -1) {
                        message_error(_("Error getting the file status flags "
@@ -402,17 +405,10 @@ io_open_src_real(file_pair *pair)
                        return true;
                }
 
-               if ((stdin_flags & O_NONBLOCK) == 0) {
-                       if (fcntl(STDIN_FILENO, F_SETFL,
-                                       stdin_flags | O_NONBLOCK) == -1) {
-                               message_error(_("Error setting O_NONBLOCK "
-                                               "on standard input: %s"),
-                                               strerror(errno));
-                               return true;
-                       }
-
+               if ((stdin_flags & O_NONBLOCK) == 0
+                               && fcntl(STDIN_FILENO, F_SETFL,
+                                       stdin_flags | O_NONBLOCK) != -1)
                        restore_stdin_flags = true;
-               }
 #endif
 #ifdef HAVE_POSIX_FADVISE
                // It will fail if stdin is a pipe and that's fine.