1*0a6a1f1dSLionel Sambuc // 2*0a6a1f1dSLionel Sambuc // Automated Testing Framework (atf) 3*0a6a1f1dSLionel Sambuc // 4*0a6a1f1dSLionel Sambuc // Copyright (c) 2007 The NetBSD Foundation, Inc. 5*0a6a1f1dSLionel Sambuc // All rights reserved. 6*0a6a1f1dSLionel Sambuc // 7*0a6a1f1dSLionel Sambuc // Redistribution and use in source and binary forms, with or without 8*0a6a1f1dSLionel Sambuc // modification, are permitted provided that the following conditions 9*0a6a1f1dSLionel Sambuc // are met: 10*0a6a1f1dSLionel Sambuc // 1. Redistributions of source code must retain the above copyright 11*0a6a1f1dSLionel Sambuc // notice, this list of conditions and the following disclaimer. 12*0a6a1f1dSLionel Sambuc // 2. Redistributions in binary form must reproduce the above copyright 13*0a6a1f1dSLionel Sambuc // notice, this list of conditions and the following disclaimer in the 14*0a6a1f1dSLionel Sambuc // documentation and/or other materials provided with the distribution. 15*0a6a1f1dSLionel Sambuc // 16*0a6a1f1dSLionel Sambuc // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17*0a6a1f1dSLionel Sambuc // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18*0a6a1f1dSLionel Sambuc // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19*0a6a1f1dSLionel Sambuc // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20*0a6a1f1dSLionel Sambuc // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21*0a6a1f1dSLionel Sambuc // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*0a6a1f1dSLionel Sambuc // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23*0a6a1f1dSLionel Sambuc // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24*0a6a1f1dSLionel Sambuc // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25*0a6a1f1dSLionel Sambuc // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26*0a6a1f1dSLionel Sambuc // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27*0a6a1f1dSLionel Sambuc // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*0a6a1f1dSLionel Sambuc // 29*0a6a1f1dSLionel Sambuc 30*0a6a1f1dSLionel Sambuc #if !defined(TOOLS_IO_HPP) 31*0a6a1f1dSLionel Sambuc #define TOOLS_IO_HPP 32*0a6a1f1dSLionel Sambuc 33*0a6a1f1dSLionel Sambuc #include <istream> 34*0a6a1f1dSLionel Sambuc #include <ostream> 35*0a6a1f1dSLionel Sambuc #include <streambuf> 36*0a6a1f1dSLionel Sambuc 37*0a6a1f1dSLionel Sambuc #include "auto_array.hpp" 38*0a6a1f1dSLionel Sambuc #include "fs.hpp" 39*0a6a1f1dSLionel Sambuc 40*0a6a1f1dSLionel Sambuc namespace tools { 41*0a6a1f1dSLionel Sambuc namespace io { 42*0a6a1f1dSLionel Sambuc 43*0a6a1f1dSLionel Sambuc // ------------------------------------------------------------------------ 44*0a6a1f1dSLionel Sambuc // The "file_handle" class. 45*0a6a1f1dSLionel Sambuc // ------------------------------------------------------------------------ 46*0a6a1f1dSLionel Sambuc 47*0a6a1f1dSLionel Sambuc //! 48*0a6a1f1dSLionel Sambuc //! \brief Simple RAII model for system file handles. 49*0a6a1f1dSLionel Sambuc //! 50*0a6a1f1dSLionel Sambuc //! The \a file_handle class is a simple RAII model for native system file 51*0a6a1f1dSLionel Sambuc //! handles. This class wraps one of such handles grabbing its ownership, 52*0a6a1f1dSLionel Sambuc //! and automaticaly closes it upon destruction. It is basically used 53*0a6a1f1dSLionel Sambuc //! inside the library to avoid leaking open file handles, shall an 54*0a6a1f1dSLionel Sambuc //! unexpected execution trace occur. 55*0a6a1f1dSLionel Sambuc //! 56*0a6a1f1dSLionel Sambuc //! A \a file_handle object can be copied but doing so invalidates the 57*0a6a1f1dSLionel Sambuc //! source object. There can only be a single valid \a file_handle object 58*0a6a1f1dSLionel Sambuc //! for a given system file handle. This is similar to std::auto_ptr\<\>'s 59*0a6a1f1dSLionel Sambuc //! semantics. 60*0a6a1f1dSLionel Sambuc //! 61*0a6a1f1dSLionel Sambuc //! This class also provides some convenience methods to issue special file 62*0a6a1f1dSLionel Sambuc //! operations under their respective platforms. 63*0a6a1f1dSLionel Sambuc //! 64*0a6a1f1dSLionel Sambuc class file_handle 65*0a6a1f1dSLionel Sambuc { 66*0a6a1f1dSLionel Sambuc public: 67*0a6a1f1dSLionel Sambuc //! 68*0a6a1f1dSLionel Sambuc //! \brief Opaque name for the native handle type. 69*0a6a1f1dSLionel Sambuc //! 70*0a6a1f1dSLionel Sambuc //! Each operating system identifies file handles using a specific type. 71*0a6a1f1dSLionel Sambuc //! The \a handle_type type is used to transparently refer to file 72*0a6a1f1dSLionel Sambuc //! handles regarless of the operating system in which this class is 73*0a6a1f1dSLionel Sambuc //! used. 74*0a6a1f1dSLionel Sambuc //! 75*0a6a1f1dSLionel Sambuc //! If this class is used in a POSIX system, \a NativeSystemHandle is 76*0a6a1f1dSLionel Sambuc //! an integer type while it is a \a HANDLE in a Win32 system. 77*0a6a1f1dSLionel Sambuc //! 78*0a6a1f1dSLionel Sambuc typedef int handle_type; 79*0a6a1f1dSLionel Sambuc 80*0a6a1f1dSLionel Sambuc //! 81*0a6a1f1dSLionel Sambuc //! \brief Constructs an invalid file handle. 82*0a6a1f1dSLionel Sambuc //! 83*0a6a1f1dSLionel Sambuc //! This constructor creates a new \a file_handle object that represents 84*0a6a1f1dSLionel Sambuc //! an invalid file handle. An invalid file handle can be copied but 85*0a6a1f1dSLionel Sambuc //! cannot be manipulated in any way (except checking for its validity). 86*0a6a1f1dSLionel Sambuc //! 87*0a6a1f1dSLionel Sambuc //! \see is_valid() 88*0a6a1f1dSLionel Sambuc //! 89*0a6a1f1dSLionel Sambuc file_handle(void); 90*0a6a1f1dSLionel Sambuc 91*0a6a1f1dSLionel Sambuc //! 92*0a6a1f1dSLionel Sambuc //! \brief Constructs a new file handle from a native file handle. 93*0a6a1f1dSLionel Sambuc //! 94*0a6a1f1dSLionel Sambuc //! This constructor creates a new \a file_handle object that takes 95*0a6a1f1dSLionel Sambuc //! ownership of the given \a h native file handle. The user must not 96*0a6a1f1dSLionel Sambuc //! close \a h on his own during the lifetime of the new object. 97*0a6a1f1dSLionel Sambuc //! Ownership can be reclaimed using disown(). 98*0a6a1f1dSLionel Sambuc //! 99*0a6a1f1dSLionel Sambuc //! \pre The native file handle must be valid; a close operation must 100*0a6a1f1dSLionel Sambuc //! succeed on it. 101*0a6a1f1dSLionel Sambuc //! 102*0a6a1f1dSLionel Sambuc //! \see disown() 103*0a6a1f1dSLionel Sambuc //! 104*0a6a1f1dSLionel Sambuc file_handle(handle_type h); 105*0a6a1f1dSLionel Sambuc 106*0a6a1f1dSLionel Sambuc //! 107*0a6a1f1dSLionel Sambuc //! \brief Copy constructor; invalidates the source handle. 108*0a6a1f1dSLionel Sambuc //! 109*0a6a1f1dSLionel Sambuc //! This copy constructor creates a new file handle from a given one. 110*0a6a1f1dSLionel Sambuc //! Ownership of the native file handle is transferred to the new 111*0a6a1f1dSLionel Sambuc //! object, effectively invalidating the source file handle. This 112*0a6a1f1dSLionel Sambuc //! avoids having two live \a file_handle objects referring to the 113*0a6a1f1dSLionel Sambuc //! same native file handle. The source file handle need not be 114*0a6a1f1dSLionel Sambuc //! valid in the name of simplicity. 115*0a6a1f1dSLionel Sambuc //! 116*0a6a1f1dSLionel Sambuc //! \post The source file handle is invalid. 117*0a6a1f1dSLionel Sambuc //! \post The new file handle owns the source's native file handle. 118*0a6a1f1dSLionel Sambuc //! 119*0a6a1f1dSLionel Sambuc file_handle(const file_handle& fh); 120*0a6a1f1dSLionel Sambuc 121*0a6a1f1dSLionel Sambuc //! 122*0a6a1f1dSLionel Sambuc //! \brief Releases resources if the handle is valid. 123*0a6a1f1dSLionel Sambuc //! 124*0a6a1f1dSLionel Sambuc //! If the file handle is valid, the destructor closes it. 125*0a6a1f1dSLionel Sambuc //! 126*0a6a1f1dSLionel Sambuc //! \see is_valid() 127*0a6a1f1dSLionel Sambuc //! 128*0a6a1f1dSLionel Sambuc ~file_handle(void); 129*0a6a1f1dSLionel Sambuc 130*0a6a1f1dSLionel Sambuc //! 131*0a6a1f1dSLionel Sambuc //! \brief Assignment operator; invalidates the source handle. 132*0a6a1f1dSLionel Sambuc //! 133*0a6a1f1dSLionel Sambuc //! This assignment operator transfers ownership of the RHS file 134*0a6a1f1dSLionel Sambuc //! handle to the LHS one, effectively invalidating the source file 135*0a6a1f1dSLionel Sambuc //! handle. This avoids having two live \a file_handle objects 136*0a6a1f1dSLionel Sambuc //! referring to the same native file handle. The source file 137*0a6a1f1dSLionel Sambuc //! handle need not be valid in the name of simplicity. 138*0a6a1f1dSLionel Sambuc //! 139*0a6a1f1dSLionel Sambuc //! \post The RHS file handle is invalid. 140*0a6a1f1dSLionel Sambuc //! \post The LHS file handle owns RHS' native file handle. 141*0a6a1f1dSLionel Sambuc //! \return A reference to the LHS file handle. 142*0a6a1f1dSLionel Sambuc //! 143*0a6a1f1dSLionel Sambuc file_handle& operator=(const file_handle& fh); 144*0a6a1f1dSLionel Sambuc 145*0a6a1f1dSLionel Sambuc //! 146*0a6a1f1dSLionel Sambuc //! \brief Checks whether the file handle is valid or not. 147*0a6a1f1dSLionel Sambuc //! 148*0a6a1f1dSLionel Sambuc //! Returns a boolean indicating whether the file handle is valid or 149*0a6a1f1dSLionel Sambuc //! not. If the file handle is invalid, no other applications can be 150*0a6a1f1dSLionel Sambuc //! executed other than the destructor. 151*0a6a1f1dSLionel Sambuc //! 152*0a6a1f1dSLionel Sambuc //! \return True if the file handle is valid; false otherwise. 153*0a6a1f1dSLionel Sambuc //! 154*0a6a1f1dSLionel Sambuc bool is_valid(void) const; 155*0a6a1f1dSLionel Sambuc 156*0a6a1f1dSLionel Sambuc //! 157*0a6a1f1dSLionel Sambuc //! \brief Closes the file handle. 158*0a6a1f1dSLionel Sambuc //! 159*0a6a1f1dSLionel Sambuc //! Explicitly closes the file handle, which must be valid. Upon 160*0a6a1f1dSLionel Sambuc //! exit, the handle is not valid any more. 161*0a6a1f1dSLionel Sambuc //! 162*0a6a1f1dSLionel Sambuc //! \pre The file handle is valid. 163*0a6a1f1dSLionel Sambuc //! \post The file handle is invalid. 164*0a6a1f1dSLionel Sambuc //! \post The native file handle is closed. 165*0a6a1f1dSLionel Sambuc //! 166*0a6a1f1dSLionel Sambuc void close(void); 167*0a6a1f1dSLionel Sambuc 168*0a6a1f1dSLionel Sambuc //! 169*0a6a1f1dSLionel Sambuc //! \brief Reclaims ownership of the native file handle. 170*0a6a1f1dSLionel Sambuc //! 171*0a6a1f1dSLionel Sambuc //! Explicitly reclaims ownership of the native file handle contained 172*0a6a1f1dSLionel Sambuc //! in the \a file_handle object, returning the native file handle. 173*0a6a1f1dSLionel Sambuc //! The caller is responsible of closing it later on. 174*0a6a1f1dSLionel Sambuc //! 175*0a6a1f1dSLionel Sambuc //! \pre The file handle is valid. 176*0a6a1f1dSLionel Sambuc //! \post The file handle is invalid. 177*0a6a1f1dSLionel Sambuc //! \return The native file handle. 178*0a6a1f1dSLionel Sambuc //! 179*0a6a1f1dSLionel Sambuc handle_type disown(void); 180*0a6a1f1dSLionel Sambuc 181*0a6a1f1dSLionel Sambuc //! 182*0a6a1f1dSLionel Sambuc //! \brief Gets the native file handle. 183*0a6a1f1dSLionel Sambuc //! 184*0a6a1f1dSLionel Sambuc //! Returns the native file handle for the \a file_handle object. 185*0a6a1f1dSLionel Sambuc //! The caller can issue any operation on it except closing it. 186*0a6a1f1dSLionel Sambuc //! If closing is required, disown() shall be used. 187*0a6a1f1dSLionel Sambuc //! 188*0a6a1f1dSLionel Sambuc //! \pre The file handle is valid. 189*0a6a1f1dSLionel Sambuc //! \return The native file handle. 190*0a6a1f1dSLionel Sambuc //! 191*0a6a1f1dSLionel Sambuc handle_type get(void) const; 192*0a6a1f1dSLionel Sambuc 193*0a6a1f1dSLionel Sambuc //! 194*0a6a1f1dSLionel Sambuc //! \brief Changes the native file handle to the given one. 195*0a6a1f1dSLionel Sambuc //! 196*0a6a1f1dSLionel Sambuc //! Given a new native file handle \a h, this operation assigns this 197*0a6a1f1dSLionel Sambuc //! handle to the current object, closing its old native file handle. 198*0a6a1f1dSLionel Sambuc //! In other words, it first calls dup2() to remap the old handle to 199*0a6a1f1dSLionel Sambuc //! the new one and then closes the old handle. 200*0a6a1f1dSLionel Sambuc //! 201*0a6a1f1dSLionel Sambuc //! If \a h matches the current value of the handle, this is a no-op. 202*0a6a1f1dSLionel Sambuc //! This is done for simplicity, to avoid the caller having to check 203*0a6a1f1dSLionel Sambuc //! this condition on its own. 204*0a6a1f1dSLionel Sambuc //! 205*0a6a1f1dSLionel Sambuc //! If \a h is open, it is automatically closed by dup2(). 206*0a6a1f1dSLionel Sambuc //! 207*0a6a1f1dSLionel Sambuc //! This operation is only available in POSIX systems. 208*0a6a1f1dSLionel Sambuc //! 209*0a6a1f1dSLionel Sambuc //! \pre The file handle is valid. 210*0a6a1f1dSLionel Sambuc //! \pre The native file handle \a h is valid; i.e., it must be 211*0a6a1f1dSLionel Sambuc //! closeable. 212*0a6a1f1dSLionel Sambuc //! \post The file handle's native file handle is \a h. 213*0a6a1f1dSLionel Sambuc //! \throw system_error If the internal remapping operation fails. 214*0a6a1f1dSLionel Sambuc //! 215*0a6a1f1dSLionel Sambuc void posix_remap(handle_type h); 216*0a6a1f1dSLionel Sambuc 217*0a6a1f1dSLionel Sambuc private: 218*0a6a1f1dSLionel Sambuc //! 219*0a6a1f1dSLionel Sambuc //! \brief Internal handle value. 220*0a6a1f1dSLionel Sambuc //! 221*0a6a1f1dSLionel Sambuc //! This variable holds the native handle value for the file handle 222*0a6a1f1dSLionel Sambuc //! hold by this object. It is interesting to note that this needs 223*0a6a1f1dSLionel Sambuc //! to be mutable because the copy constructor and the assignment 224*0a6a1f1dSLionel Sambuc //! operator invalidate the source object. 225*0a6a1f1dSLionel Sambuc //! 226*0a6a1f1dSLionel Sambuc mutable handle_type m_handle; 227*0a6a1f1dSLionel Sambuc 228*0a6a1f1dSLionel Sambuc //! 229*0a6a1f1dSLionel Sambuc //! \brief Constant function representing an invalid handle value. 230*0a6a1f1dSLionel Sambuc //! 231*0a6a1f1dSLionel Sambuc //! Returns the platform-specific handle value that represents an 232*0a6a1f1dSLionel Sambuc //! invalid handle. This is a constant function rather than a regular 233*0a6a1f1dSLionel Sambuc //! constant because, in the latter case, we cannot define it under 234*0a6a1f1dSLionel Sambuc //! Win32 due to the value being of a complex type. 235*0a6a1f1dSLionel Sambuc //! 236*0a6a1f1dSLionel Sambuc static handle_type invalid_value(void); 237*0a6a1f1dSLionel Sambuc }; 238*0a6a1f1dSLionel Sambuc 239*0a6a1f1dSLionel Sambuc // ------------------------------------------------------------------------ 240*0a6a1f1dSLionel Sambuc // The "systembuf" class. 241*0a6a1f1dSLionel Sambuc // ------------------------------------------------------------------------ 242*0a6a1f1dSLionel Sambuc 243*0a6a1f1dSLionel Sambuc //! 244*0a6a1f1dSLionel Sambuc //! \brief std::streambuf implementation for system file handles. 245*0a6a1f1dSLionel Sambuc //! 246*0a6a1f1dSLionel Sambuc //! systembuf provides a std::streambuf implementation for system file 247*0a6a1f1dSLionel Sambuc //! handles. Contrarywise to file_handle, this class does \b not take 248*0a6a1f1dSLionel Sambuc //! ownership of the native file handle; this should be taken care of 249*0a6a1f1dSLionel Sambuc //! somewhere else. 250*0a6a1f1dSLionel Sambuc //! 251*0a6a1f1dSLionel Sambuc //! This class follows the expected semantics of a std::streambuf object. 252*0a6a1f1dSLionel Sambuc //! However, it is not copyable to avoid introducing inconsistences with 253*0a6a1f1dSLionel Sambuc //! the on-disk file and the in-memory buffers. 254*0a6a1f1dSLionel Sambuc //! 255*0a6a1f1dSLionel Sambuc class systembuf : public std::streambuf 256*0a6a1f1dSLionel Sambuc { 257*0a6a1f1dSLionel Sambuc // Non-copyable. 258*0a6a1f1dSLionel Sambuc systembuf(const systembuf&); 259*0a6a1f1dSLionel Sambuc systembuf& operator=(const systembuf&); 260*0a6a1f1dSLionel Sambuc 261*0a6a1f1dSLionel Sambuc public: 262*0a6a1f1dSLionel Sambuc typedef int handle_type; 263*0a6a1f1dSLionel Sambuc 264*0a6a1f1dSLionel Sambuc //! 265*0a6a1f1dSLionel Sambuc //! \brief Constructs a new systembuf for the given file handle. 266*0a6a1f1dSLionel Sambuc //! 267*0a6a1f1dSLionel Sambuc //! This constructor creates a new systembuf object that reads or 268*0a6a1f1dSLionel Sambuc //! writes data from/to the \a h native file handle. This handle 269*0a6a1f1dSLionel Sambuc //! is \b not owned by the created systembuf object; the code 270*0a6a1f1dSLionel Sambuc //! should take care of it externally. 271*0a6a1f1dSLionel Sambuc //! 272*0a6a1f1dSLionel Sambuc //! This class buffers input and output; the buffer size may be 273*0a6a1f1dSLionel Sambuc //! tuned through the \a bufsize parameter, which defaults to 8192 274*0a6a1f1dSLionel Sambuc //! bytes. 275*0a6a1f1dSLionel Sambuc //! 276*0a6a1f1dSLionel Sambuc //! \see pistream. 277*0a6a1f1dSLionel Sambuc //! 278*0a6a1f1dSLionel Sambuc explicit systembuf(handle_type h, std::size_t bufsize = 8192); 279*0a6a1f1dSLionel Sambuc ~systembuf(void); 280*0a6a1f1dSLionel Sambuc 281*0a6a1f1dSLionel Sambuc private: 282*0a6a1f1dSLionel Sambuc //! 283*0a6a1f1dSLionel Sambuc //! \brief Native file handle used by the systembuf object. 284*0a6a1f1dSLionel Sambuc //! 285*0a6a1f1dSLionel Sambuc handle_type m_handle; 286*0a6a1f1dSLionel Sambuc 287*0a6a1f1dSLionel Sambuc //! 288*0a6a1f1dSLionel Sambuc //! \brief Internal buffer size used during read and write operations. 289*0a6a1f1dSLionel Sambuc //! 290*0a6a1f1dSLionel Sambuc std::size_t m_bufsize; 291*0a6a1f1dSLionel Sambuc 292*0a6a1f1dSLionel Sambuc //! 293*0a6a1f1dSLionel Sambuc //! \brief Internal buffer used during read operations. 294*0a6a1f1dSLionel Sambuc //! 295*0a6a1f1dSLionel Sambuc char* m_read_buf; 296*0a6a1f1dSLionel Sambuc 297*0a6a1f1dSLionel Sambuc //! 298*0a6a1f1dSLionel Sambuc //! \brief Internal buffer used during write operations. 299*0a6a1f1dSLionel Sambuc //! 300*0a6a1f1dSLionel Sambuc char* m_write_buf; 301*0a6a1f1dSLionel Sambuc 302*0a6a1f1dSLionel Sambuc protected: 303*0a6a1f1dSLionel Sambuc //! 304*0a6a1f1dSLionel Sambuc //! \brief Reads new data from the native file handle. 305*0a6a1f1dSLionel Sambuc //! 306*0a6a1f1dSLionel Sambuc //! This operation is called by input methods when there are no more 307*0a6a1f1dSLionel Sambuc //! data in the input buffer. The function fills the buffer with new 308*0a6a1f1dSLionel Sambuc //! data, if available. 309*0a6a1f1dSLionel Sambuc //! 310*0a6a1f1dSLionel Sambuc //! \pre All input positions are exhausted (gptr() >= egptr()). 311*0a6a1f1dSLionel Sambuc //! \post The input buffer has new data, if available. 312*0a6a1f1dSLionel Sambuc //! \returns traits_type::eof() if a read error occurrs or there are 313*0a6a1f1dSLionel Sambuc //! no more data to be read. Otherwise returns 314*0a6a1f1dSLionel Sambuc //! traits_type::to_int_type(*gptr()). 315*0a6a1f1dSLionel Sambuc //! 316*0a6a1f1dSLionel Sambuc virtual int_type underflow(void); 317*0a6a1f1dSLionel Sambuc 318*0a6a1f1dSLionel Sambuc //! 319*0a6a1f1dSLionel Sambuc //! \brief Makes room in the write buffer for additional data. 320*0a6a1f1dSLionel Sambuc //! 321*0a6a1f1dSLionel Sambuc //! This operation is called by output methods when there is no more 322*0a6a1f1dSLionel Sambuc //! space in the output buffer to hold a new element. The function 323*0a6a1f1dSLionel Sambuc //! first flushes the buffer's contents to disk and then clears it to 324*0a6a1f1dSLionel Sambuc //! leave room for more characters. The given \a c character is 325*0a6a1f1dSLionel Sambuc //! stored at the beginning of the new space. 326*0a6a1f1dSLionel Sambuc //! 327*0a6a1f1dSLionel Sambuc //! \pre All output positions are exhausted (pptr() >= epptr()). 328*0a6a1f1dSLionel Sambuc //! \post The output buffer has more space if no errors occurred 329*0a6a1f1dSLionel Sambuc //! during the write to disk. 330*0a6a1f1dSLionel Sambuc //! \post *(pptr() - 1) is \a c. 331*0a6a1f1dSLionel Sambuc //! \returns traits_type::eof() if a write error occurrs. Otherwise 332*0a6a1f1dSLionel Sambuc //! returns traits_type::not_eof(c). 333*0a6a1f1dSLionel Sambuc //! 334*0a6a1f1dSLionel Sambuc virtual int_type overflow(int c); 335*0a6a1f1dSLionel Sambuc 336*0a6a1f1dSLionel Sambuc //! 337*0a6a1f1dSLionel Sambuc //! \brief Flushes the output buffer to disk. 338*0a6a1f1dSLionel Sambuc //! 339*0a6a1f1dSLionel Sambuc //! Synchronizes the systembuf buffers with the contents of the file 340*0a6a1f1dSLionel Sambuc //! associated to this object through the native file handle. The 341*0a6a1f1dSLionel Sambuc //! output buffer is flushed to disk and cleared to leave new room 342*0a6a1f1dSLionel Sambuc //! for more data. 343*0a6a1f1dSLionel Sambuc //! 344*0a6a1f1dSLionel Sambuc //! \returns 0 on success, -1 if an error occurred. 345*0a6a1f1dSLionel Sambuc //! 346*0a6a1f1dSLionel Sambuc virtual int sync(void); 347*0a6a1f1dSLionel Sambuc }; 348*0a6a1f1dSLionel Sambuc 349*0a6a1f1dSLionel Sambuc // ------------------------------------------------------------------------ 350*0a6a1f1dSLionel Sambuc // The "pistream" class. 351*0a6a1f1dSLionel Sambuc // ------------------------------------------------------------------------ 352*0a6a1f1dSLionel Sambuc 353*0a6a1f1dSLionel Sambuc //! 354*0a6a1f1dSLionel Sambuc //! \brief Child process' output stream. 355*0a6a1f1dSLionel Sambuc //! 356*0a6a1f1dSLionel Sambuc //! The pistream class represents an output communication channel with the 357*0a6a1f1dSLionel Sambuc //! child process. The child process writes data to this stream and the 358*0a6a1f1dSLionel Sambuc //! parent process can read it through the pistream object. In other 359*0a6a1f1dSLionel Sambuc //! words, from the child's point of view, the communication channel is an 360*0a6a1f1dSLionel Sambuc //! output one, but from the parent's point of view it is an input one; 361*0a6a1f1dSLionel Sambuc //! hence the confusing pistream name. 362*0a6a1f1dSLionel Sambuc //! 363*0a6a1f1dSLionel Sambuc //! pistream objects cannot be copied because they own the file handle 364*0a6a1f1dSLionel Sambuc //! they use to communicate with the child and because they buffer data 365*0a6a1f1dSLionel Sambuc //! that flows through the communication channel. 366*0a6a1f1dSLionel Sambuc //! 367*0a6a1f1dSLionel Sambuc //! A pistream object behaves as a std::istream stream in all senses. 368*0a6a1f1dSLionel Sambuc //! The class is only provided because it must provide a method to let 369*0a6a1f1dSLionel Sambuc //! the caller explicitly close the communication channel. 370*0a6a1f1dSLionel Sambuc //! 371*0a6a1f1dSLionel Sambuc //! \remark <b>Blocking remarks</b>: Functions that read data from this 372*0a6a1f1dSLionel Sambuc //! stream can block if the associated file handle blocks during the read. 373*0a6a1f1dSLionel Sambuc //! As this class is used to communicate with child processes through 374*0a6a1f1dSLionel Sambuc //! anonymous pipes, the most typical blocking condition happens when the 375*0a6a1f1dSLionel Sambuc //! child has no more data to send to the pipe's system buffer. When 376*0a6a1f1dSLionel Sambuc //! this happens, the buffer eventually empties and the system blocks 377*0a6a1f1dSLionel Sambuc //! until the writer generates some data. 378*0a6a1f1dSLionel Sambuc //! 379*0a6a1f1dSLionel Sambuc class pistream : public std::istream 380*0a6a1f1dSLionel Sambuc { 381*0a6a1f1dSLionel Sambuc // Non-copyable. 382*0a6a1f1dSLionel Sambuc pistream(const pistream&); 383*0a6a1f1dSLionel Sambuc pistream& operator=(const pistream&); 384*0a6a1f1dSLionel Sambuc 385*0a6a1f1dSLionel Sambuc //! 386*0a6a1f1dSLionel Sambuc //! \brief The systembuf object used to manage this stream's data. 387*0a6a1f1dSLionel Sambuc //! 388*0a6a1f1dSLionel Sambuc systembuf m_systembuf; 389*0a6a1f1dSLionel Sambuc 390*0a6a1f1dSLionel Sambuc public: 391*0a6a1f1dSLionel Sambuc //! 392*0a6a1f1dSLionel Sambuc //! \brief Creates a new process' output stream. 393*0a6a1f1dSLionel Sambuc //! 394*0a6a1f1dSLionel Sambuc //! Given a file handle, this constructor creates a new pistream 395*0a6a1f1dSLionel Sambuc //! object that owns the given file handle \a fh. Ownership of 396*0a6a1f1dSLionel Sambuc //! \a fh is transferred to the created pistream object. 397*0a6a1f1dSLionel Sambuc //! 398*0a6a1f1dSLionel Sambuc //! \pre \a fh is valid. 399*0a6a1f1dSLionel Sambuc //! \post \a fh is invalid. 400*0a6a1f1dSLionel Sambuc //! \post The new pistream object owns \a fh. 401*0a6a1f1dSLionel Sambuc //! 402*0a6a1f1dSLionel Sambuc explicit pistream(const int); 403*0a6a1f1dSLionel Sambuc }; 404*0a6a1f1dSLionel Sambuc 405*0a6a1f1dSLionel Sambuc // ------------------------------------------------------------------------ 406*0a6a1f1dSLionel Sambuc // The "muxer" class. 407*0a6a1f1dSLionel Sambuc // ------------------------------------------------------------------------ 408*0a6a1f1dSLionel Sambuc 409*0a6a1f1dSLionel Sambuc class muxer { 410*0a6a1f1dSLionel Sambuc // Non-copyable. 411*0a6a1f1dSLionel Sambuc muxer(const muxer&); 412*0a6a1f1dSLionel Sambuc muxer& operator=(const muxer&); 413*0a6a1f1dSLionel Sambuc 414*0a6a1f1dSLionel Sambuc const int* m_fds; 415*0a6a1f1dSLionel Sambuc const size_t m_nfds; 416*0a6a1f1dSLionel Sambuc 417*0a6a1f1dSLionel Sambuc const size_t m_bufsize; 418*0a6a1f1dSLionel Sambuc tools::auto_array< std::string > m_buffers; 419*0a6a1f1dSLionel Sambuc 420*0a6a1f1dSLionel Sambuc protected: 421*0a6a1f1dSLionel Sambuc virtual void line_callback(const size_t, const std::string&) = 0; 422*0a6a1f1dSLionel Sambuc 423*0a6a1f1dSLionel Sambuc size_t read_one(const size_t, const int, std::string&, const bool); 424*0a6a1f1dSLionel Sambuc 425*0a6a1f1dSLionel Sambuc public: 426*0a6a1f1dSLionel Sambuc muxer(const int*, const size_t, const size_t bufsize = 1024); 427*0a6a1f1dSLionel Sambuc virtual ~muxer(void); 428*0a6a1f1dSLionel Sambuc 429*0a6a1f1dSLionel Sambuc void mux(volatile const bool&); 430*0a6a1f1dSLionel Sambuc void flush(void); 431*0a6a1f1dSLionel Sambuc }; 432*0a6a1f1dSLionel Sambuc 433*0a6a1f1dSLionel Sambuc } // namespace io 434*0a6a1f1dSLionel Sambuc } // namespace tools 435*0a6a1f1dSLionel Sambuc 436*0a6a1f1dSLionel Sambuc #endif // !defined(TOOLS_IO_HPP) 437