file_descriptor_sink vs. pclose
I've been having difficulty using iostreams::file_descriptor_sink with popen in Linux. The problem is that popen() requires a matching pclose() rather than a close(). Now, file_descriptor_sink has a close_on_exit flag that, when set to false, supposedly prevents it from calling close() on the underlying file descriptor, but it calls close() anyway. Is this a bug in boost or am I doing it wrong? As a workaround I can call flush () on the iostream and then pclose() on the filehandle, but it seems like it would be better to actually close the iostream. I've tested the example below using boost 1.39 and using 1.43 from subversion. The result in both cases is: pclose returned error (test A): Bad file descriptor pclose returned error (test B): Bad file descriptor Hello Hello ------------------------- #include <stdexcept> #include <iostream> #include <boost/iostreams/device/file_descriptor.hpp> #include <boost/iostreams/stream.hpp> #include <stdio.h> #include <string.h> #include <errno.h> typedef boost::iostreams::stream<boost::iostreams::file_descriptor_sink> boost_stream; int main() { bool close_on_exit = false; FILE *pout = popen("cat", "w"); { boost_stream bs(fileno(pout), close_on_exit); bs << "Hello\n"; // destructor calls close(fileno(pout)) } if(pclose(pout)) { char *err = strerror(errno); std::cerr << "pclose returned error (test A): " << err << std::endl; } pout = popen("cat", "w"); boost_stream bs(fileno(pout), close_on_exit); bs << "Hello\n"; // bs.close() calls close(fileno(pout)) // without the bs.close(), there would be no pclose() error bs.close(); // If bs.close() is not used, bs.flush() can be used to flush data to // pipe before calling pclose(). //bs.flush(); if(pclose(pout)) { char *err = strerror(errno); std::cerr << "pclose returned error (test B): " << err << std::endl; } }
De : Dan Stahlke
I've been having difficulty using iostreams::file_descriptor_sink with popen in Linux. The problem is that popen() requires a matching pclose() rather than a close(). Now, file_descriptor_sink has a close_on_exit flag that, when set to false, supposedly prevents it from calling close() on the underlying file descriptor, but it calls close() anyway. Is this a bug in boost or am I doing it wrong? As a workaround I can call flush () on the iostream and then pclose() on the filehandle, but it seems like it would be better to actually close the iostream.
That looks a lot like this ticket: https://svn.boost.org/trac/boost/ticket/3517 A workaround is to explicitly call set_auto_close(false).
On Thu, 06 May 2010 09:26:35 -0400, Eric MALENFANT wrote:
De : Dan Stahlke
I've been having difficulty using iostreams::file_descriptor_sink with popen in Linux. The problem is that popen() requires a matching pclose() rather than a close(). Now, file_descriptor_sink has a close_on_exit flag that, when set to false, supposedly prevents it from calling close() on the underlying file descriptor, but it calls close() anyway. Is this a bug in boost or am I doing it wrong? As a workaround I can call flush () on the iostream and then pclose() on the filehandle, but it seems like it would be better to actually close the iostream.
That looks a lot like this ticket: https://svn.boost.org/trac/boost/ticket/3517 A workaround is to explicitly call set_auto_close(false).
Calling set_auto_close(false) fixes the first case (involving the destructor) but not the second (in which file_descriptor_sink::close is explicitly called by me). Is there a way that file_descriptor_sink::close can be made to not call close(int fd)?
participants (2)
-
Dan Stahlke
-
Eric MALENFANT