|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r63430 - in trunk: boost/iostreams/device libs/iostreams/build libs/iostreams/doc/classes libs/iostreams/src libs/iostreams/test libs/iostreams/test/detail
From: daniel_james_at_[hidden]
Date: 2010-06-29 10:15:15
Author: danieljames
Date: 2010-06-29 10:15:13 EDT (Tue, 29 Jun 2010)
New Revision: 63430
URL: http://svn.boost.org/trac/boost/changeset/63430
Log:
Try to improve file_descriptor's ownership policies. Refs #3517
* Deprecate the old 'close_on_exit' constructors.
* Introduce new constructors from file handle, taking either
`never_close_handle` or `close_handle`.
* Close current file handle when opening a new file handle,
if it would have been closed in the destructor.
Added:
trunk/libs/iostreams/test/deprecated_file_descriptor_test.cpp (contents, props changed)
trunk/libs/iostreams/test/detail/file_handle.hpp (contents, props changed)
Text files modified:
trunk/boost/iostreams/device/file_descriptor.hpp | 54 +++++++++++++
trunk/libs/iostreams/build/Jamfile.v2 | 1
trunk/libs/iostreams/doc/classes/file_descriptor.html | 152 +++++++++++++++++++++++++++++++++----
trunk/libs/iostreams/src/file_descriptor.cpp | 160 +++++++++++++++++++++++++++++++--------
trunk/libs/iostreams/test/Jamfile.v2 | 24 ++++++
trunk/libs/iostreams/test/file_descriptor_test.cpp | 121 ++++++++++++++++++++++++++++++
6 files changed, 460 insertions(+), 52 deletions(-)
Modified: trunk/boost/iostreams/device/file_descriptor.hpp
==============================================================================
--- trunk/boost/iostreams/device/file_descriptor.hpp (original)
+++ trunk/boost/iostreams/device/file_descriptor.hpp 2010-06-29 10:15:13 EDT (Tue, 29 Jun 2010)
@@ -37,6 +37,12 @@
class file_descriptor_sink;
namespace detail { struct file_descriptor_impl; }
+enum file_descriptor_flags
+{
+ never_close_handle = 0,
+ close_handle = 3
+};
+
class BOOST_IOSTREAMS_DECL file_descriptor {
public:
friend class file_descriptor_source;
@@ -52,10 +58,18 @@
file_descriptor();
// Constructors taking file desciptors
+ file_descriptor(handle_type fd, file_descriptor_flags);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ file_descriptor(int fd, file_descriptor_flags);
+#endif
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
+ // Constructors taking file desciptors
explicit file_descriptor(handle_type fd, bool close_on_exit = false);
#ifdef BOOST_IOSTREAMS_WINDOWS
explicit file_descriptor(int fd, bool close_on_exit = false);
#endif
+#endif
// Constructor taking a std:: string
explicit file_descriptor( const std::string& path,
@@ -81,10 +95,18 @@
file_descriptor(const file_descriptor& other);
// open overloads taking file descriptors
+ void open(handle_type fd, file_descriptor_flags);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ void open(int fd, file_descriptor_flags);
+#endif
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
+ // open overloads taking file descriptors
void open(handle_type fd, bool close_on_exit = false);
#ifdef BOOST_IOSTREAMS_WINDOWS
void open(int fd, bool close_on_exit = false);
#endif
+#endif
// open overload taking a std::string
void open( const std::string& path,
@@ -144,10 +166,18 @@
file_descriptor_source() { }
// Constructors taking file desciptors
+ explicit file_descriptor_source(handle_type fd, file_descriptor_flags);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ explicit file_descriptor_source(int fd, file_descriptor_flags);
+#endif
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
+ // Constructors taking file desciptors
explicit file_descriptor_source(handle_type fd, bool close_on_exit = false);
#ifdef BOOST_IOSTREAMS_WINDOWS
explicit file_descriptor_source(int fd, bool close_on_exit = false);
#endif
+#endif
// Constructor taking a std:: string
explicit file_descriptor_source( const std::string& path,
@@ -166,11 +196,19 @@
// Copy constructor
file_descriptor_source(const file_descriptor_source& other);
+ // Constructors taking file desciptors
+ void open(handle_type fd, file_descriptor_flags);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ void open(int fd, file_descriptor_flags);
+#endif
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
// open overloads taking file descriptors
void open(handle_type fd, bool close_on_exit = false);
#ifdef BOOST_IOSTREAMS_WINDOWS
void open(int fd, bool close_on_exit = false);
#endif
+#endif
// open overload taking a std::string
void open(const std::string& path, BOOST_IOS::openmode mode = BOOST_IOS::in);
@@ -210,10 +248,18 @@
file_descriptor_sink() { }
// Constructors taking file desciptors
+ file_descriptor_sink(handle_type fd, file_descriptor_flags);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ file_descriptor_sink(int fd, file_descriptor_flags);
+#endif
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
+ // Constructors taking file desciptors
explicit file_descriptor_sink(handle_type fd, bool close_on_exit = false);
#ifdef BOOST_IOSTREAMS_WINDOWS
explicit file_descriptor_sink(int fd, bool close_on_exit = false);
#endif
+#endif
// Constructor taking a std:: string
explicit file_descriptor_sink( const std::string& path,
@@ -233,10 +279,18 @@
file_descriptor_sink(const file_descriptor_sink& other);
// open overloads taking file descriptors
+ void open(handle_type fd, file_descriptor_flags);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ void open(int fd, file_descriptor_flags);
+#endif
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
+ // open overloads taking file descriptors
void open(handle_type fd, bool close_on_exit = false);
#ifdef BOOST_IOSTREAMS_WINDOWS
void open(int fd, bool close_on_exit = false);
#endif
+#endif
// open overload taking a std::string
void open( const std::string& path,
Modified: trunk/libs/iostreams/build/Jamfile.v2
==============================================================================
--- trunk/libs/iostreams/build/Jamfile.v2 (original)
+++ trunk/libs/iostreams/build/Jamfile.v2 2010-06-29 10:15:13 EDT (Tue, 29 Jun 2010)
@@ -155,6 +155,7 @@
lib boost_iostreams
: $(sources)
: <link>shared:<define>BOOST_IOSTREAMS_DYN_LINK=1
+ <define>BOOST_IOSTREAMS_USE_DEPRECATED
:
: <link>shared:<define>BOOST_IOSTREAMS_DYN_LINK=1
;
Modified: trunk/libs/iostreams/doc/classes/file_descriptor.html
==============================================================================
--- trunk/libs/iostreams/doc/classes/file_descriptor.html (original)
+++ trunk/libs/iostreams/doc/classes/file_descriptor.html 2010-06-29 10:15:13 EDT (Tue, 29 Jun 2010)
@@ -97,6 +97,11 @@
<PRE CLASS="broken_ie"><SPAN CLASS="keyword">namespace</SPAN> boost { <SPAN CLASS="keyword">namespace</SPAN> iostreams {
+<SPAN CLASS="keyword">enum</SPAN> file_descriptor_flags {
+ never_close_handle,
+ close_handle
+};
+
<SPAN CLASS="keyword">class</SPAN> file_descriptor_source {
<SPAN CLASS="keyword">public</SPAN>:
<SPAN CLASS='keyword'>typedef</SPAN> <SPAN CLASS='keyword'>char</SPAN> char_type;
@@ -107,18 +112,30 @@
<A CLASS="documented" HREF="#file_descriptor_source_ctor">file_descriptor_source</A>( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::in );
- <A CLASS="documented" HREF="#file_descriptor_source_ctor">file_descriptor_source</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ <A CLASS="documented" HREF="#file_descriptor_source_ctor">file_descriptor_source</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
+ <A CLASS="documented" HREF="#file_descriptor_source_ctor">file_descriptor_source</A>( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ <A CLASS="documented" HREF="#file_descriptor_source_ctor">file_descriptor_source</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
<A CLASS="documented" HREF="#file_descriptor_source_ctor">file_descriptor_source</A>( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
<SPAN CLASS="keyword">template</SPAN><<SPAN CLASS="keyword">typename</SPAN> Path>
<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_source_open">open</A>( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::in );
- <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_source_open">open</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_source_open">open</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_source_open">open</A>( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_source_open">open</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_source_open">open</A>( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
<SPAN CLASS="keyword">bool</SPAN> <A CLASS="documented" HREF="#file_descriptor_source_is_open">is_open</A>() <SPAN CLASS="keyword">const</SPAN>;
@@ -136,11 +153,16 @@
file_descriptor_source( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::in );
- file_descriptor_source( <SPAN CLASS="keyword">int </SPAN>fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ file_descriptor_source( <SPAN CLASS="keyword">int </SPAN>fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
- file_descriptor_source( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );</PRE>
+ file_descriptor_source( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ file_descriptor_source( <SPAN CLASS="keyword">int </SPAN>fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
+ file_descriptor_source( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );</PRE>
<P>
The first member constructs an empty <CODE>file_descriptor_source</CODE>.
</P>
@@ -150,11 +172,19 @@
</P>
<P>
- The third member constructs a <CODE>file_descriptor_source</CODE> to access the file with the given operating system or runtime-library file descriptor. If the second argument is <CODE>true</CODE>, the file descriptor is closed when the <CODE>file_descriptor_source</CODE> being constructed — or one of its copies — is closed.
+ The third member constructs a <CODE>file_descriptor_source</CODE> to access the file with the given operating system or runtime-library file descriptor.
+ If the second argument is <CODE>close_handle</CODE>, the file descriptor is closed when the <CODE>file_descriptor_source</CODE> being constructed — or one of its copies — is closed or destructed.
</P>
<P>
- The fourth member is the same as the third, except that it accepts a Windows file handle instead of a file descriptor. If the second argument is <CODE>true</CODE>, the file descriptor is closed when the <CODE>file_descriptor_source</CODE> being constructed — or one of its copies — is closed.
+ The fourth member is the same as the third, except that it accepts a Windows file handle instead of a file descriptor.
+ If the second argument is <CODE>close_handle</CODE>, the file descriptor is closed when the <CODE>file_descriptor_source</CODE> being constructed — or one of its copies — is closed or destructed.
+</P>
+
+<P>
+ The deprecated members are there to provide backwards compatability with old versions.
+ To use them you need to define <CODE>BOOST_IOSTREAMS_USE_DEPRECATED</CODE>.
+ The descriptor is always closed by <CODE>close</CODE> but only closed in destructors if <CODE>close_on_exit</CODE> is <CODE>true</CODE>.
</P>
<A NAME="file_descriptor_source_open"></A>
@@ -164,13 +194,21 @@
<SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::in );
- <SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ <SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> open( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
<SPAN CLASS="keyword">void</SPAN> open( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );</PRE>
<P>
The parameters of <CODE>open</CODE> the same as those of the corresponding constructors.
+ If the file descriptor already holds a file, it'll be closed
+ (unless opened or constructed with <CODE>never_close_handle</CODE>).
</P>
<A NAME="file_descriptor_source_is_open"></A>
@@ -198,6 +236,11 @@
<PRE CLASS="broken_ie"><SPAN CLASS="keyword">namespace</SPAN> boost { <SPAN CLASS="keyword">namespace</SPAN> iostreams {
+<SPAN CLASS="keyword">enum</SPAN> file_descriptor_flags {
+ never_close_handle,
+ close_handle
+};
+
<SPAN CLASS="keyword">class</SPAN> file_descriptor_sink {
<SPAN CLASS="keyword">public</SPAN>:
<SPAN CLASS='keyword'>typedef</SPAN> <SPAN CLASS='keyword'>char</SPAN> char_type;
@@ -213,13 +256,25 @@
<SPAN CLASS='comment'>// Windows-only</SPAN>
<A CLASS="documented" HREF="#file_descriptor_sink_ctor">file_descriptor_sink</A>( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ <A CLASS="documented" HREF="#file_descriptor_sink_ctor">file_descriptor_sink</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
+ <A CLASS="documented" HREF="#file_descriptor_sink_ctor">file_descriptor_sink</A>( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
<SPAN CLASS="keyword">template</SPAN><<SPAN CLASS="keyword">typename</SPAN> Path>
<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_sink_open">open</A>( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::out );
- <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_sink_open">open</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_sink_open">open</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_sink_open">open</A>( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_sink_open">open</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_sink_open">open</A>( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
<SPAN CLASS="keyword">bool</SPAN> <A CLASS="documented" HREF="#file_descriptor_sink_is_open">is_open</A>() <SPAN CLASS="keyword">const</SPAN>;
@@ -240,7 +295,13 @@
file_descriptor_sink( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
- file_descriptor_sink( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );</PRE>
+ file_descriptor_sink( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ file_descriptor_sink( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
+ file_descriptor_sink( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );</PRE>
<P>
The first member constructs an empty <CODE>file_descriptor_sink</CODE>.
@@ -251,11 +312,19 @@
</P>
<P>
- The third member constructs a <CODE>file_descriptor_sink</CODE> to access the file with the given operating system or runtime-library file descriptor. If the second argument is <CODE>true</CODE>, the file descriptor is closed when the new <CODE>file_descriptor_sink</CODE> — or one of its copies — is closed.
+ The third member constructs a <CODE>file_descriptor_sink</CODE> to access the file with the given operating system or runtime-library file descriptor.
+ If the second argument is <CODE>close_handle</CODE>, the file descriptor is closed when the <CODE>file_descriptor_sink</CODE> being constructed — or one of its copies — is closed or destructed.
+</P>
+
+<P>
+ The fourth member is the same as the third, except that it accepts a Windows file handle instead of a file descriptor.
+ If the second argument is <CODE>close_handle</CODE>, the file descriptor is closed when the <CODE>file_descriptor_sink</CODE> being constructed — or one of its copies — is closed or destructed.
</P>
<P>
- The fourth member is the same as the third, except that it accepts a Windows file handle instead of a file descriptor. If the second argument is <CODE>true</CODE>, the file descriptor is closed when the new <CODE>file_descriptor_sink</CODE> — or one of its copies — is closed.
+ The deprecated members are there to provide backwards compatability with old versions.
+ To use them you need to define <CODE>BOOST_IOSTREAMS_USE_DEPRECATED</CODE>.
+ The descriptor is always closed by <CODE>close</CODE> but only closed in destructors if <CODE>close_on_exit</CODE> is <CODE>true</CODE>.
</P>
<A NAME="file_descriptor_sink_open"></A>
@@ -265,13 +334,21 @@
<SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::out );
- <SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ <SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> open( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
<SPAN CLASS="keyword">void</SPAN> open( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );</PRE>
<P>
The parameters of <CODE>open</CODE> the same as those of the corresponding constructors.
+ If the file descriptor already holds a file, it'll be closed
+ (unless opened or constructed with <CODE>never_close_handle</CODE>).
</P>
<A NAME="file_descriptor_sink_is_open"></A>
@@ -299,6 +376,11 @@
<PRE CLASS="broken_ie"><SPAN CLASS="keyword">namespace</SPAN> boost { <SPAN CLASS="keyword">namespace</SPAN> iostreams {
+<SPAN CLASS="keyword">enum</SPAN> file_descriptor_flags {
+ never_close_handle,
+ close_handle
+};
+
<SPAN CLASS="keyword">class</SPAN> file_descriptor {
<SPAN CLASS="keyword">public</SPAN>:
<SPAN CLASS='keyword'>typedef</SPAN> <SPAN CLASS='keyword'>char</SPAN> char_type;
@@ -309,18 +391,30 @@
<A CLASS="documented" HREF="#file_descriptor_constructor">file_descriptor</A>( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::in | std::ios_base::out );
- <A CLASS="documented" HREF="#file_descriptor_constructor">file_descriptor</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ <A CLASS="documented" HREF="#file_descriptor_constructor">file_descriptor</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
+ <A CLASS="documented" HREF="#file_descriptor_constructor">file_descriptor</A>( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ <A CLASS="documented" HREF="#file_descriptor_constructor">file_descriptor</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
<A CLASS="documented" HREF="#file_descriptor_constructor">file_descriptor</A>( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
<SPAN CLASS="keyword">template</SPAN><<SPAN CLASS="keyword">typename</SPAN> Path>
<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_open">open</A>( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::in | std::ios_base::out );
- <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_open">open</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_open">open</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_open">open</A>( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_open">open</A>( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#file_descriptor_open">open</A>( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
<SPAN CLASS="keyword">bool</SPAN> <A CLASS="documented" HREF="#file_descriptor_is_open">is_open</A>() <SPAN CLASS="keyword">const</SPAN>;
@@ -338,9 +432,15 @@
file_descriptor( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::in | std::ios_base::out );
- file_descriptor( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ file_descriptor( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
+ file_descriptor( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ file_descriptor( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
file_descriptor( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );</PRE>
<P>
@@ -352,11 +452,19 @@
</P>
<P>
- The third member constructs a <CODE>file_descriptor</CODE> to access the file with the given operating system or runtime-library file descriptor. If the second argument is <CODE>true</CODE>, the file descriptor is closed when the new <CODE>file_descriptor</CODE> — or one of its copies — is closed.
+ The third member constructs a <CODE>file_descriptor</CODE> to access the file with the given operating system or runtime-library file descriptor.
+ If the second argument is <CODE>close_handle</CODE>, the file descriptor is closed when the <CODE>file_descriptor</CODE> being constructed — or one of its copies — is closed or destructed.
</P>
<P>
- The fourth member is the same as the third, except that it accepts a Windows file handle instead of a file descriptor. If the second argument is <CODE>true</CODE>, the file descriptor is closed when the new <CODE>file_descriptor</CODE> — or one of its copies — is closed.
+ The fourth member is the same as the third, except that it accepts a Windows file handle instead of a file descriptor.
+ If the second argument is <CODE>close_handle</CODE>, the file descriptor is closed when the new <CODE>file_descriptor</CODE> — or one of its copies — is closed or destructed.
+</P>
+
+<P>
+ The deprecated members are there to provide backwards compatability with old versions.
+ To use them you need to define <CODE>BOOST_IOSTREAMS_USE_DEPRECATED</CODE>.
+ The descriptor is always closed by <CODE>close</CODE> but only closed in destructors if <CODE>close_on_exit</CODE> is <CODE>true</CODE>.
</P>
<A NAME="file_descriptor_open"></A>
@@ -366,13 +474,21 @@
<SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">const</SPAN> Path& pathname,
std::ios_base::open_mode mode =
std::ios_base::in | std::ios_base::out );
- <SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+ <SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
<SPAN CLASS='comment'>// Windows-only</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> open( HANDLE hFile, <SPAN CLASS="keyword">file_descriptor_flags</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated</SPAN>
+ <SPAN CLASS="keyword">void</SPAN> open( <SPAN CLASS="keyword">int</SPAN> fd, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );
+
+ <SPAN CLASS='comment'>// Deprecated, Windows-only</SPAN>
<SPAN CLASS="keyword">void</SPAN> open( HANDLE hFile, <SPAN CLASS="keyword">bool</SPAN> close_on_exit = <SPAN CLASS="keyword">false</SPAN> );</PRE>
<P>
The parameters of <CODE>open</CODE> the same as those of the corresponding constructors.
+ If the file descriptor already holds a file, it'll be closed
+ (unless opened or constructed with <CODE>never_close_handle</CODE>).
</P>
<A NAME="file_descriptor_is_open"></A>
Modified: trunk/libs/iostreams/src/file_descriptor.cpp
==============================================================================
--- trunk/libs/iostreams/src/file_descriptor.cpp (original)
+++ trunk/libs/iostreams/src/file_descriptor.cpp 2010-06-29 10:15:13 EDT (Tue, 29 Jun 2010)
@@ -48,22 +48,28 @@
// Contains the platform dependant implementation
struct file_descriptor_impl {
+ // Note: These need to match file_desciptor_flags
+ enum flags {
+ never_close = 0,
+ close_on_exit = 1,
+ close_on_close = 2,
+ close_always = 3
+ };
+
file_descriptor_impl();
~file_descriptor_impl();
- void open(file_handle fd, bool close_on_exit);
+ void open(file_handle fd, flags);
#ifdef BOOST_IOSTREAMS_WINDOWS
- void open(int fd, bool close_on_exit);
+ void open(int fd, flags);
#endif
void open(const detail::path&, BOOST_IOS::openmode);
bool is_open() const;
void close();
+ void close_impl(bool close_flag, bool throw_);
std::streamsize read(char* s, std::streamsize n);
std::streamsize write(const char* s, std::streamsize n);
std::streampos seek(stream_offset off, BOOST_IOS::seekdir way);
static file_handle invalid_handle();
- enum flags {
- close_on_exit = 1
- };
file_handle handle_;
int flags_;
};
@@ -76,30 +82,38 @@
file_descriptor_impl::~file_descriptor_impl()
{
- if (flags_ & close_on_exit) {
- try {
- close();
- } catch (...) { }
- }
+ close_impl(flags_ & close_on_exit, false);
}
-void file_descriptor_impl::open(file_handle fd, bool close_on_exit)
+void file_descriptor_impl::open(file_handle fd, flags f)
{
+ // Using 'close' to close the existing handle so that it will throw an
+ // exception if it fails.
+ //
+ // Only closing after assigning the new handle, so that the class will
+ // take ownership of the handle regardless of whether close throws.
+
+ file_descriptor_impl tmp;
+ tmp.handle_ = handle_;
+ tmp.flags_ = flags_ & close_on_exit ? close_on_close : never_close;
+
handle_ = fd;
- flags_ = close_on_exit ?
- file_descriptor_impl::close_on_exit :
- 0;
+ flags_ = f;
+
+ tmp.close();
}
#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
-void file_descriptor_impl::open(int fd, bool close_on_exit)
-{ open(reinterpret_cast<file_handle>(_get_osfhandle(fd)), close_on_exit); }
+void file_descriptor_impl::open(int fd, flags f)
+{ open(reinterpret_cast<file_handle>(_get_osfhandle(fd)), f); }
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
void file_descriptor_impl::open(const detail::path& p, BOOST_IOS::openmode mode)
{
+ close_impl(flags_ & close_on_exit, true);
+
#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
DWORD dwDesiredAccess;
DWORD dwCreationDisposition;
@@ -157,7 +171,7 @@
NULL ); // hTemplateFile
if (handle != INVALID_HANDLE_VALUE) {
handle_ = handle;
- flags_ |= close_on_exit;
+ flags_ = close_always;
} else {
flags_ = 0;
throw_system_failure("failed opening file");
@@ -214,7 +228,7 @@
boost::throw_exception(system_failure("failed opening file"));
} else {
handle_ = fd;
- flags_ = close_on_exit;
+ flags_ = close_always;
}
#endif // #ifndef BOOST_IOSTREAMS_WINDOWS //----------------------------------//
}
@@ -224,15 +238,21 @@
void file_descriptor_impl::close()
{
+ close_impl(flags_ & close_on_close, true);
+}
+
+void file_descriptor_impl::close_impl(bool close_flag, bool throw_) {
if (handle_ != invalid_handle()) {
- bool success =
- #ifdef BOOST_IOSTREAMS_WINDOWS
- ::CloseHandle(handle_) == 1;
- #else
- BOOST_IOSTREAMS_FD_CLOSE(handle_) != -1;
- #endif
- if (!success)
- throw_system_failure("failed closing file");
+ if (close_flag) {
+ bool success =
+ #ifdef BOOST_IOSTREAMS_WINDOWS
+ ::CloseHandle(handle_) == 1;
+ #else
+ BOOST_IOSTREAMS_FD_CLOSE(handle_) != -1;
+ #endif
+ if (!success && throw_)
+ throw_system_failure("failed closing file");
+ }
handle_ = invalid_handle();
flags_ = 0;
}
@@ -331,15 +351,27 @@
file_descriptor::file_descriptor() : pimpl_(new impl_type) { }
+file_descriptor::file_descriptor(handle_type fd, file_descriptor_flags f)
+ : pimpl_(new impl_type)
+{ open(fd, f); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
file_descriptor::file_descriptor(handle_type fd, bool close_on_exit)
: pimpl_(new impl_type)
{ open(fd, close_on_exit); }
+#endif
#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+file_descriptor::file_descriptor(int fd, file_descriptor_flags f)
+ : pimpl_(new impl_type)
+{ open(fd, f); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
file_descriptor::file_descriptor(int fd, bool close_on_exit)
: pimpl_(new impl_type)
{ open(fd, close_on_exit); }
+#endif
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
@@ -357,13 +389,27 @@
: pimpl_(other.pimpl_)
{ }
+void file_descriptor::open(handle_type fd, file_descriptor_flags f)
+{ pimpl_->open(fd, static_cast<detail::file_descriptor_impl::flags>(f)); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
void file_descriptor::open(handle_type fd, bool close_on_exit)
-{ pimpl_->open(fd, close_on_exit); }
+{ pimpl_->open(fd, close_on_exit ?
+ detail::file_descriptor_impl::close_always :
+ detail::file_descriptor_impl::close_on_close); }
+#endif
#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+void file_descriptor::open(int fd, file_descriptor_flags f)
+{ pimpl_->open(fd, static_cast<detail::file_descriptor_impl::flags>(f)); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
void file_descriptor::open(int fd, bool close_on_exit)
-{ pimpl_->open(fd, close_on_exit); }
+{ pimpl_->open(fd, close_on_exit ?
+ detail::file_descriptor_impl::close_always :
+ detail::file_descriptor_impl::close_on_close); }
+#endif
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
@@ -402,13 +448,24 @@
//------------------Implementation of file_descriptor_source------------------//
file_descriptor_source::file_descriptor_source(
+ handle_type fd, file_descriptor_flags f)
+{ open(fd, f); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
+file_descriptor_source::file_descriptor_source(
handle_type fd, bool close_on_exit)
{ open(fd, close_on_exit); }
+#endif
#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+file_descriptor_source::file_descriptor_source(int fd, file_descriptor_flags f)
+{ open(fd, f); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
file_descriptor_source::file_descriptor_source(int fd, bool close_on_exit)
{ open(fd, close_on_exit); }
+#endif
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
@@ -425,13 +482,25 @@
: file_descriptor(static_cast<const file_descriptor&>(other))
{ }
+void file_descriptor_source::open(handle_type fd, file_descriptor_flags f)
+{ file_descriptor::open(fd, f); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
void file_descriptor_source::open(handle_type fd, bool close_on_exit)
-{ file_descriptor::open(fd, close_on_exit); }
+{ file_descriptor::open(fd, close_on_exit); }
+#endif
#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+void file_descriptor_source::open(int fd, file_descriptor_flags f)
+{ file_descriptor::open(fd, static_cast<detail::file_descriptor_impl::flags>(f)); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
void file_descriptor_source::open(int fd, bool close_on_exit)
-{ file_descriptor::open(fd, close_on_exit); }
+{ file_descriptor::open(fd, close_on_exit ?
+ detail::file_descriptor_impl::close_always :
+ detail::file_descriptor_impl::close_on_close); }
+#endif
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
@@ -454,13 +523,26 @@
//------------------Implementation of file_descriptor_sink--------------------//
file_descriptor_sink::file_descriptor_sink(
+ handle_type fd, file_descriptor_flags f)
+{ open(fd, f); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
+file_descriptor_sink::file_descriptor_sink(
handle_type fd, bool close_on_exit)
{ open(fd, close_on_exit); }
+#endif
#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+file_descriptor_sink::file_descriptor_sink(int fd, file_descriptor_flags f)
+{ open(fd, static_cast<detail::file_descriptor_impl::flags>(f)); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
file_descriptor_sink::file_descriptor_sink(int fd, bool close_on_exit)
-{ open(fd, close_on_exit); }
+{ open(fd, close_on_exit ?
+ detail::file_descriptor_impl::close_always :
+ detail::file_descriptor_impl::close_on_close); }
+#endif
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
@@ -476,13 +558,25 @@
: file_descriptor(static_cast<const file_descriptor&>(other))
{ }
+void file_descriptor_sink::open(handle_type fd, file_descriptor_flags f)
+{ file_descriptor::open(fd, f); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
void file_descriptor_sink::open(handle_type fd, bool close_on_exit)
-{ file_descriptor::open(fd, close_on_exit); }
+{ file_descriptor::open(fd, close_on_exit); }
+#endif
#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+void file_descriptor_sink::open(int fd, file_descriptor_flags f)
+{ file_descriptor::open(fd, static_cast<detail::file_descriptor_impl::flags>(f)); }
+
+#if defined(BOOST_IOSTREAMS_USE_DEPRECATED)
void file_descriptor_sink::open(int fd, bool close_on_exit)
-{ file_descriptor::open(fd, close_on_exit); }
+{ file_descriptor::open(fd, close_on_exit ?
+ detail::file_descriptor_impl::close_always :
+ detail::file_descriptor_impl::close_on_close); }
+#endif
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
Modified: trunk/libs/iostreams/test/Jamfile.v2
==============================================================================
--- trunk/libs/iostreams/test/Jamfile.v2 (original)
+++ trunk/libs/iostreams/test/Jamfile.v2 2010-06-29 10:15:13 EDT (Tue, 29 Jun 2010)
@@ -33,6 +33,24 @@
] ;
}
+rule compile-fail-iostreams ( sources * : requirements * : target-name ? ) {
+ return [
+ compile-fail
+ $(sources)
+ /boost/test//boost_unit_test_framework/<link>static
+ /boost/filesystem//boost_filesystem/<link>static
+ : # build requirements
+ <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
+ <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
+ <toolset>cw-9.3,<os>darwin:<runtime-link>static
+ <define>BOOST_IOSTREAMS_NO_LIB
+ <link>shared:<define>BOOST_IOSTREAMS_DYN_LINK=1
+ $(requirements)
+ : $(target-name)
+ ] ;
+}
+
+
local all-tests =
[ test-iostreams array_test.cpp ]
[ test-iostreams auto_close_test.cpp ]
@@ -52,6 +70,12 @@
[ test-iostreams file_test.cpp ]
[ test-iostreams file_descriptor_test.cpp
../build//boost_iostreams ]
+ [ test-iostreams deprecated_file_descriptor_test.cpp
+ ../build//boost_iostreams
+ : <define>BOOST_IOSTREAMS_USE_DEPRECATED ]
+ [ compile-fail-iostreams deprecated_file_descriptor_test.cpp
+ :
+ : deprecated_file_descriptor_fail ]
[ test-iostreams filtering_stream_test.cpp ]
[ test-iostreams finite_state_filter_test.cpp ]
[ test-iostreams flush_test.cpp ]
Added: trunk/libs/iostreams/test/deprecated_file_descriptor_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/iostreams/test/deprecated_file_descriptor_test.cpp 2010-06-29 10:15:13 EDT (Tue, 29 Jun 2010)
@@ -0,0 +1,235 @@
+#include <boost/iostreams/device/file_descriptor.hpp>
+#include <boost/iostreams/stream.hpp>
+#include <boost/test/unit_test.hpp>
+#include "detail/temp_file.hpp"
+#include "detail/verification.hpp"
+#include "detail/file_handle.hpp"
+
+// Test file_descriptor with the depreacted constructors.
+
+namespace boost_ios = boost::iostreams;
+namespace ios_test = boost::iostreams::test;
+
+void deprecated_file_descriptor_test()
+{
+ typedef boost_ios::stream<boost_ios::file_descriptor_source> fdistream;
+ typedef boost_ios::stream<boost_ios::file_descriptor_sink> fdostream;
+ typedef boost_ios::stream<boost_ios::file_descriptor> fdstream;
+
+ ios_test::test_file test1;
+ ios_test::test_file test2;
+
+ //--------------Deprecated file descriptor constructor--------------------//
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1(handle);
+ BOOST_CHECK(source1.handle() == handle);
+ }
+ BOOST_CHECK_HANDLE_OPEN(handle);
+ ios_test::close_file_handle(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1(handle, false);
+ BOOST_CHECK(source1.handle() == handle);
+ }
+ BOOST_CHECK_HANDLE_OPEN(handle);
+ ios_test::close_file_handle(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1(handle, true);
+ BOOST_CHECK(source1.handle() == handle);
+ }
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ boost_ios::file_descriptor_source source1(handle);
+ BOOST_CHECK(source1.handle() == handle);
+ source1.close();
+ BOOST_CHECK(!source1.is_open());
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ boost_ios::file_descriptor_source source1(handle, false);
+ BOOST_CHECK(source1.handle() == handle);
+ source1.close();
+ BOOST_CHECK(!source1.is_open());
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ boost_ios::file_descriptor_source source1(handle, true);
+ BOOST_CHECK(source1.handle() == handle);
+ source1.close();
+ BOOST_CHECK(!source1.is_open());
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ //--------------Deprecated file descriptor open---------------------------//
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1;
+ source1.open(handle);
+ BOOST_CHECK(source1.handle() == handle);
+ }
+ BOOST_CHECK_HANDLE_OPEN(handle);
+ ios_test::close_file_handle(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1;
+ source1.open(handle, false);
+ BOOST_CHECK(source1.handle() == handle);
+ }
+ BOOST_CHECK_HANDLE_OPEN(handle);
+ ios_test::close_file_handle(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1;
+ source1.open(handle, true);
+ BOOST_CHECK(source1.handle() == handle);
+ }
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ boost_ios::file_descriptor_source source1;
+ source1.open(handle);
+ BOOST_CHECK(source1.handle() == handle);
+ source1.close();
+ BOOST_CHECK(!source1.is_open());
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ boost_ios::file_descriptor_source source1;
+ source1.open(handle, false);
+ BOOST_CHECK(source1.handle() == handle);
+ source1.close();
+ BOOST_CHECK(!source1.is_open());
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = ios_test::open_file_handle(test1.name());
+ boost_ios::file_descriptor_source source1;
+ source1.open(handle, true);
+ BOOST_CHECK(source1.handle() == handle);
+ source1.close();
+ BOOST_CHECK(!source1.is_open());
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ //--------------Deprecated open with existing descriptor------------------//
+
+ {
+ boost_ios::detail::file_handle handle1 = ios_test::open_file_handle(test1.name());
+ boost_ios::detail::file_handle handle2 = ios_test::open_file_handle(test1.name());
+
+ {
+ boost_ios::file_descriptor_source source1(handle1);
+ BOOST_CHECK(source1.handle() == handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ source1.open(handle2);
+ BOOST_CHECK(source1.handle() == handle2);
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ source1.close();
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_CLOSED(handle2);
+ }
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_CLOSED(handle2);
+
+ ios_test::close_file_handle(handle1);
+ }
+
+ {
+ boost_ios::detail::file_handle handle1 = ios_test::open_file_handle(test1.name());
+ boost_ios::detail::file_handle handle2 = ios_test::open_file_handle(test1.name());
+
+ {
+ boost_ios::file_descriptor_source source1(handle1, true);
+ BOOST_CHECK(source1.handle() == handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ source1.open(handle2);
+ BOOST_CHECK(source1.handle() == handle2);
+ BOOST_CHECK_HANDLE_CLOSED(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ source1.close();
+ BOOST_CHECK_HANDLE_CLOSED(handle1);
+ BOOST_CHECK_HANDLE_CLOSED(handle2);
+ }
+ BOOST_CHECK_HANDLE_CLOSED(handle1);
+ BOOST_CHECK_HANDLE_CLOSED(handle2);
+ }
+
+ {
+ boost_ios::detail::file_handle handle1 = ios_test::open_file_handle(test1.name());
+ boost_ios::detail::file_handle handle2 = ios_test::open_file_handle(test1.name());
+
+ {
+ boost_ios::file_descriptor_source source1(handle1, false);
+ BOOST_CHECK(source1.handle() == handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ source1.open(handle2, false);
+ BOOST_CHECK(source1.handle() == handle2);
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ }
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+
+ ios_test::close_file_handle(handle1);
+ ios_test::close_file_handle(handle2);
+ }
+
+ {
+ boost_ios::detail::file_handle handle1 = ios_test::open_file_handle(test1.name());
+ boost_ios::detail::file_handle handle2 = ios_test::open_file_handle(test1.name());
+
+ {
+ boost_ios::file_descriptor_source source1(handle1, true);
+ BOOST_CHECK(source1.handle() == handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ source1.open(handle2, true);
+ BOOST_CHECK(source1.handle() == handle2);
+ BOOST_CHECK_HANDLE_CLOSED(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ }
+ BOOST_CHECK_HANDLE_CLOSED(handle1);
+ BOOST_CHECK_HANDLE_CLOSED(handle2);
+ }
+}
+
+boost::unit_test::test_suite* init_unit_test_suite(int, char* [])
+{
+ boost::unit_test::test_suite* test = BOOST_TEST_SUITE("deprecated file_descriptor test");
+ test->add(BOOST_TEST_CASE(&deprecated_file_descriptor_test));
+ return test;
+}
Added: trunk/libs/iostreams/test/detail/file_handle.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/iostreams/test/detail/file_handle.hpp 2010-06-29 10:15:13 EDT (Tue, 29 Jun 2010)
@@ -0,0 +1,100 @@
+// (C) Copyright 2010 Daniel James
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
+
+// A few methods for getting and manipulating file handles.
+
+#ifndef BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
+#define BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
+
+#include <boost/iostreams/detail/file_handle.hpp>
+#include <boost/iostreams/detail/config/rtl.hpp>
+#include <boost/test/test_tools.hpp>
+#include <fcntl.h>
+#include <string>
+
+namespace boost { namespace iostreams { namespace test {
+
+#ifdef BOOST_IOSTREAMS_WINDOWS
+
+// Windows implementation
+
+boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
+{
+ HANDLE handle =
+ ::CreateFileA( name.c_str(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, // lpSecurityAttributes
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL ); // hTemplateFile
+
+ BOOST_REQUIRE (handle != INVALID_HANDLE_VALUE);
+ return HANDLE;
+}
+
+void close_file_handle(boost::iostreams::detail::file_handle handle)
+{
+ BOOST_REQUIRE(::CloseHandle(handle) == 1);
+}
+
+#define BOOST_CHECK_HANDLE_CLOSED(handle)
+#define BOOST_CHECK_HANDLE_OPEN(handle)
+
+#else // BOOST_IOSTREAMS_WINDOWS
+
+// Non-windows implementation
+
+boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
+{
+ int oflag = O_RDWR;
+
+ #ifdef _LARGEFILE64_SOURCE
+ oflag |= O_LARGEFILE;
+ #endif
+
+ // Calculate pmode argument to open.
+
+ mode_t pmode = S_IRUSR | S_IWUSR |
+ S_IRGRP | S_IWGRP |
+ S_IROTH | S_IWOTH;
+
+ // Open file.
+
+ int fd = BOOST_IOSTREAMS_FD_OPEN(name.c_str(), oflag, pmode);
+ BOOST_REQUIRE (fd != -1);
+
+ return fd;
+}
+
+void close_file_handle(boost::iostreams::detail::file_handle handle)
+{
+ BOOST_REQUIRE(BOOST_IOSTREAMS_FD_CLOSE(handle) != -1);
+}
+
+// This is pretty dubious. First you must make sure that no other
+// operations that could open a descriptor are called before this
+// check, otherwise it's quite likely that a closed descriptor
+// could be used. Secondly, I'm not sure if it's guaranteed that
+// fcntl will know that the descriptor is closed but this seems
+// to work okay, and I can't see any other convenient way to check
+// that a descripter has been closed.
+bool is_handle_open(boost::iostreams::detail::file_handle handle)
+{
+ return ::fcntl(handle, F_GETFD) != -1;
+}
+
+#define BOOST_CHECK_HANDLE_CLOSED(handle) \
+ BOOST_CHECK(!::boost::iostreams::test::is_handle_open(handle))
+#define BOOST_CHECK_HANDLE_OPEN(handle) \
+ BOOST_CHECK(::boost::iostreams::test::is_handle_open(handle))
+
+
+#endif // BOOST_IOSTREAMS_WINDOWS
+
+}}}
+
+#endif // BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
Modified: trunk/libs/iostreams/test/file_descriptor_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/file_descriptor_test.cpp (original)
+++ trunk/libs/iostreams/test/file_descriptor_test.cpp 2010-06-29 10:15:13 EDT (Tue, 29 Jun 2010)
@@ -6,16 +6,19 @@
// See http://www.boost.org/libs/iostreams for documentation.
#include <fstream>
+#include <fcntl.h>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include "detail/temp_file.hpp"
#include "detail/verification.hpp"
+#include "detail/file_handle.hpp"
using namespace boost;
using namespace boost::iostreams;
using namespace boost::iostreams::test;
+namespace boost_ios = boost::iostreams;
using std::ifstream;
using boost::unit_test::test_suite;
@@ -80,7 +83,7 @@
first->close();
BOOST_CHECK(!first->is_open());
}
-
+
// test illegal flag combinations
{
BOOST_CHECK_THROW(
@@ -507,9 +510,125 @@
}
}
+void file_handle_test()
+{
+ test_file test1;
+ test_file test2;
+
+ {
+ boost_ios::detail::file_handle handle = open_file_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1(handle, boost_ios::never_close_handle);
+ BOOST_CHECK(source1.handle() == handle);
+ }
+ BOOST_CHECK_HANDLE_OPEN(handle);
+ close_file_handle(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = open_file_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1(handle, boost_ios::close_handle);
+ BOOST_CHECK(source1.handle() == handle);
+ }
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = open_file_handle(test1.name());
+ boost_ios::file_descriptor_source source1(handle, boost_ios::never_close_handle);
+ BOOST_CHECK(source1.handle() == handle);
+ source1.close();
+ BOOST_CHECK(!source1.is_open());
+ BOOST_CHECK_HANDLE_OPEN(handle);
+ close_file_handle(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = open_file_handle(test1.name());
+ boost_ios::file_descriptor_source source1(handle, boost_ios::close_handle);
+ BOOST_CHECK(source1.handle() == handle);
+ source1.close();
+ BOOST_CHECK(!source1.is_open());
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle1 = open_file_handle(test1.name());
+ boost_ios::detail::file_handle handle2 = open_file_handle(test2.name());
+ {
+ boost_ios::file_descriptor_source source1(handle1, boost_ios::never_close_handle);
+ BOOST_CHECK(source1.handle() == handle1);
+ source1.open(handle2, boost_ios::never_close_handle);
+ BOOST_CHECK(source1.handle() == handle2);
+ }
+ BOOST_CHECK_HANDLE_OPEN(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ close_file_handle(handle1);
+ close_file_handle(handle2);
+ }
+
+ {
+ boost_ios::detail::file_handle handle1 = open_file_handle(test1.name());
+ boost_ios::detail::file_handle handle2 = open_file_handle(test2.name());
+ {
+ boost_ios::file_descriptor_source source1(handle1, boost_ios::close_handle);
+ BOOST_CHECK(source1.handle() == handle1);
+ source1.open(handle2, boost_ios::close_handle);
+ BOOST_CHECK(source1.handle() == handle2);
+ BOOST_CHECK_HANDLE_CLOSED(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ }
+ BOOST_CHECK_HANDLE_CLOSED(handle1);
+ BOOST_CHECK_HANDLE_CLOSED(handle2);
+ }
+
+ {
+ boost_ios::detail::file_handle handle1 = open_file_handle(test1.name());
+ boost_ios::detail::file_handle handle2 = open_file_handle(test2.name());
+ {
+ boost_ios::file_descriptor_source source1(handle1, boost_ios::close_handle);
+ BOOST_CHECK(source1.handle() == handle1);
+ source1.open(handle2, boost_ios::never_close_handle);
+ BOOST_CHECK(source1.handle() == handle2);
+ BOOST_CHECK_HANDLE_CLOSED(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ }
+ BOOST_CHECK_HANDLE_CLOSED(handle1);
+ BOOST_CHECK_HANDLE_OPEN(handle2);
+ close_file_handle(handle2);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = open_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1;
+ BOOST_CHECK(!source1.is_open());
+ source1.open(handle, boost_ios::never_close_handle);
+ BOOST_CHECK(source1.handle() == handle);
+ BOOST_CHECK_HANDLE_OPEN(handle);
+ }
+ BOOST_CHECK_HANDLE_OPEN(handle);
+ close_file_handle(handle);
+ }
+
+ {
+ boost_ios::detail::file_handle handle = open_handle(test1.name());
+ {
+ boost_ios::file_descriptor_source source1;
+ BOOST_CHECK(!source1.is_open());
+ source1.open(handle, boost_ios::close_handle);
+ BOOST_CHECK(source1.handle() == handle);
+ BOOST_CHECK_HANDLE_OPEN(handle);
+ }
+ BOOST_CHECK_HANDLE_CLOSED(handle);
+ }
+}
+
test_suite* init_unit_test_suite(int, char* [])
{
test_suite* test = BOOST_TEST_SUITE("file_descriptor test");
test->add(BOOST_TEST_CASE(&file_descriptor_test));
+ test->add(BOOST_TEST_CASE(&file_handle_test));
return test;
}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk