Boost C++ Libraries: Ticket #2557: iostreams filtering_stream w/ gzip infinite loop when writing to a full drive https://svn.boost.org/trac10/ticket/2557 <p> When a filtering_stream with a gzip_compressor is used to write to a full hard drive (i.e. insufficient free space), boost enters an infinite loop in /boost/iostreams/detail/adapter/non_blocking_adapter.hpp:41 because the write function keeps returning zero. This loop happens during the destruction of the stream. I can't seem to find a client-side workaround. </p> <p> Attached is a test case, point it to a volume with zero space and give some large number of bytes. If there's insufficient space, execution hangs. Tested on mingw/winxp/gcc4.2 but seems to fail on linux/gcc as well. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/2557 Trac 1.4.3 Tomasz Śniatowski <kailoran@…> Mon, 01 Dec 2008 19:27:47 GMT attachment set https://svn.boost.org/trac10/ticket/2557 https://svn.boost.org/trac10/ticket/2557 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost-bug.cpp</span> </li> </ul> Ticket Jonathan Turkanis Mon, 01 Dec 2008 19:58:56 GMT status changed https://svn.boost.org/trac10/ticket/2557#comment:1 https://svn.boost.org/trac10/ticket/2557#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket michal-slizak@… Fri, 29 Oct 2010 11:47:16 GMT <link>https://svn.boost.org/trac10/ticket/2557#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2557#comment:2</guid> <description> <p> Has this been fixed? If so, which version of the library contains the fix? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Sat, 30 Oct 2010 12:41:12 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2557#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2557#comment:3</guid> <description> <p> No, it hasn't been fixed. </p> </description> <category>Ticket</category> </item> <item> <author>michal-slizak@…</author> <pubDate>Wed, 03 Nov 2010 15:23:36 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2557#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2557#comment:4</guid> <description> <p> The gzip file consists of a sequence of compressed chunks. </p> <p> You can manually compress data chunks and append them to a file: </p> <pre class="wiki">class StreamSink { public: typedef char char_type; typedef boost::iostreams::sink_tag category; StreamSink(); StreamSink(std::ostream * stream); std::streamsize write(const char * ptr, std::streamsize n); void close(); bool isOpen() const; private: bool opened; std::ostream * stream; }; StreamSink::StreamSink(): opened(false), stream(NULL) { } StreamSink::StreamSink(std::ostream * stream): opened(true), stream(stream) { assert(stream != NULL, "StreamSink constructed from NULL"); } std::streamsize StreamSink::write(const char * ptr, std::streamsize n) { assert(this-&gt;stream != NULL, "Writing to NULL stream"); this-&gt;stream-&gt;write(ptr, n); return n; } void StreamSink::close() { this-&gt;opened = false; this-&gt;stream = NULL; } bool StreamSink::isOpen() const { return this-&gt;opened; } void writeGzippedSection(string const &amp; filename, ios_base::openmode mode, string const &amp; data) { try { std::ofstream out(filename.c_str(), mode | ios::binary); out.exceptions(std::ios_base::badbit | std::ios_base::failbit); StreamSink sink(&amp;out); boost::iostreams::gzip_compressor compressor; compressor.write(sink, data.c_str(), data.length()); compressor.close(sink, BOOST_IOS::out); } catch (boost::iostreams::gzip_error const &amp; e) { std::cerr &lt;&lt; "gzip error: " &lt;&lt; e.error() &lt;&lt; ", zlib error: " &lt;&lt; e.zlib_error_code() &lt;&lt; std::endl; throw; } catch (ofstream::failure const &amp; e) { std::cerr &lt;&lt; "ofstream::failure: " &lt;&lt; e.what() &lt;&lt; std::endl; throw; } } </pre><p> The code above produces decompressable files (tested with zcat, zless and gunzip). Also, when out-of-space occurs, chunks that were written successfully can be recovered. </p> <p> The code may not be pretty, but it works. </p> </description> <category>Ticket</category> </item> <item> <author>leyaya_1999@…</author> <pubDate>Wed, 15 Jan 2014 15:45:58 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2557#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2557#comment:5</guid> <description> <p> The same infinite loop happens if user does not have write access on the file that is being written to. In that case the variable amt receives value -1 in </p> <p> /include/boost/iostreams/detail/adapter/non_blocking_adapter.hpp line 42 </p> <p> this bug is still here in boost 1.55 </p> </description> <category>Ticket</category> </item> <item> <author>leyaya_1999@…</author> <pubDate>Wed, 15 Jan 2014 15:46:47 GMT</pubDate> <title>version changed https://svn.boost.org/trac10/ticket/2557#comment:6 https://svn.boost.org/trac10/ticket/2557#comment:6 <ul> <li><strong>version</strong> <span class="trac-field-old">Boost 1.37.0</span> → <span class="trac-field-new">Boost 1.55.0</span> </li> </ul> Ticket anonymous Thu, 24 Apr 2014 23:20:18 GMT <link>https://svn.boost.org/trac10/ticket/2557#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2557#comment:7</guid> <description> <p> And the same issue happens on Windows if the "filename" is longer then <code></code><code>MAX_PATH</code><code></code> and not prefixed with <code></code><code>"\\?\"</code><code></code>. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Tue, 18 Apr 2017 13:57:47 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2557#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2557#comment:8</guid> <description> <p> There are also hangs if a file_sink could not be opened (though that is at least possible to check manually by calling is_open() before). Also, the "hangs" are not just hangs but infinite loops with 100% CPU usage. It feels like the whole iostream was written without any consideration for error handling at all. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Mon, 03 Jul 2017 13:11:20 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2557#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2557#comment:9</guid> <description> <p> Submitted a pull request with fix and test-case: <a class="ext-link" href="https://github.com/boostorg/iostreams/pull/36"><span class="icon">​</span>https://github.com/boostorg/iostreams/pull/36</a> </p> <p> It doesn't check or ensure that the error is properly propagated (I am not sure there even is a proper way to do that), but at least no more infinite loop. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 12 Jul 2017 12:45:47 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2557#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2557#comment:10</guid> <description> <p> Change has been merged, so hopefully the next release will finally have the fix. </p> </description> <category>Ticket</category> </item> </channel> </rss>