head	1.2;
access;
symbols
	perseant-exfatfs-base-20250801:1.2
	perseant-exfatfs-base-20240630:1.2
	perseant-exfatfs:1.2.0.6
	perseant-exfatfs-base:1.2
	cjep_sun2x:1.2.0.4
	cjep_sun2x-base:1.2
	cjep_staticlib_x-base1:1.2
	cjep_staticlib_x:1.2.0.2
	cjep_staticlib_x-base:1.2
	phil-wifi-20200421:1.2
	phil-wifi-20200411:1.2
	phil-wifi-20200406:1.2
	pgoyette-compat-merge-20190127:1.1.1.1.2.2
	pgoyette-compat-20190127:1.1.1.1
	pgoyette-compat-20190118:1.1.1.1
	pgoyette-compat-1226:1.1.1.1
	pgoyette-compat-1126:1.1.1.1
	pgoyette-compat-1020:1.1.1.1
	pgoyette-compat-0930:1.1.1.1
	pgoyette-compat-0906:1.1.1.1
	pgoyette-compat-0728:1.1.1.1
	phil-wifi:1.1.1.1.0.4
	phil-wifi-base:1.1.1.1
	pgoyette-compat-0625:1.1.1.1
	pgoyette-compat-0521:1.1.1.1
	pgoyette-compat-0502:1.1.1.1
	pgoyette-compat-0422:1.1.1.1
	pgoyette-compat:1.1.1.1.0.2
	pgoyette-compat-0415:1.1.1.1
	bind-9-10-7:1.1.1.1
	ISC:1.1.1;
locks; strict;
comment	@// @;


1.2
date	2019.05.10.09.15.04;	author wiz;	state dead;
branches;
next	1.1;
commitid	SEgY3sFTlDvvDDmB;

1.1
date	2018.04.07.21.44.15;	author christos;	state Exp;
branches
	1.1.1.1;
next	;
commitid	oNwftHLrbKKUxyxA;

1.1.1.1
date	2018.04.07.21.44.15;	author christos;	state Exp;
branches
	1.1.1.1.2.1
	1.1.1.1.4.1;
next	;
commitid	oNwftHLrbKKUxyxA;

1.1.1.1.2.1
date	2018.04.07.21.44.15;	author pgoyette;	state dead;
branches;
next	1.1.1.1.2.2;
commitid	qk3nktk0szmTIByA;

1.1.1.1.2.2
date	2018.04.16.01.58.06;	author pgoyette;	state Exp;
branches;
next	;
commitid	qk3nktk0szmTIByA;

1.1.1.1.4.1
date	2019.06.10.21.44.38;	author christos;	state dead;
branches;
next	;
commitid	jtc8rnCzWiEEHGqB;


desc
@@


1.2
log
@Remove src/external/bsd/bind - latest version is in src/external/mpl/bind

This directory was already unhooked from the build (in August 2018).

ok christos@@
@
text
@//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#if !defined(TOOLS_IO_HPP)
#define TOOLS_IO_HPP

#include <istream>
#include <ostream>
#include <streambuf>

#include "auto_array.hpp"
#include "fs.hpp"

namespace tools {
namespace io {

// ------------------------------------------------------------------------
// The "file_handle" class.
// ------------------------------------------------------------------------

//!
//! \brief Simple RAII model for system file handles.
//!
//! The \a file_handle class is a simple RAII model for native system file
//! handles.  This class wraps one of such handles grabbing its ownership,
//! and automaticaly closes it upon destruction.  It is basically used
//! inside the library to avoid leaking open file handles, shall an
//! unexpected execution trace occur.
//!
//! A \a file_handle object can be copied but doing so invalidates the
//! source object.  There can only be a single valid \a file_handle object
//! for a given system file handle.  This is similar to std::auto_ptr\<\>'s
//! semantics.
//!
//! This class also provides some convenience methods to issue special file
//! operations under their respective platforms.
//!
class file_handle
{
public:
    //!
    //! \brief Opaque name for the native handle type.
    //!
    //! Each operating system identifies file handles using a specific type.
    //! The \a handle_type type is used to transparently refer to file
    //! handles regarless of the operating system in which this class is
    //! used.
    //!
    //! If this class is used in a POSIX system, \a NativeSystemHandle is
    //! an integer type while it is a \a HANDLE in a Win32 system.
    //!
    typedef int handle_type;

    //!
    //! \brief Constructs an invalid file handle.
    //!
    //! This constructor creates a new \a file_handle object that represents
    //! an invalid file handle.  An invalid file handle can be copied but
    //! cannot be manipulated in any way (except checking for its validity).
    //!
    //! \see is_valid()
    //!
    file_handle(void);

    //!
    //! \brief Constructs a new file handle from a native file handle.
    //!
    //! This constructor creates a new \a file_handle object that takes
    //! ownership of the given \a h native file handle.  The user must not
    //! close \a h on his own during the lifetime of the new object.
    //! Ownership can be reclaimed using disown().
    //!
    //! \pre The native file handle must be valid; a close operation must
    //!      succeed on it.
    //!
    //! \see disown()
    //!
    file_handle(handle_type h);

    //!
    //! \brief Copy constructor; invalidates the source handle.
    //!
    //! This copy constructor creates a new file handle from a given one.
    //! Ownership of the native file handle is transferred to the new
    //! object, effectively invalidating the source file handle.  This
    //! avoids having two live \a file_handle objects referring to the
    //! same native file handle.  The source file handle need not be
    //! valid in the name of simplicity.
    //!
    //! \post The source file handle is invalid.
    //! \post The new file handle owns the source's native file handle.
    //!
    file_handle(const file_handle& fh);

    //!
    //! \brief Releases resources if the handle is valid.
    //!
    //! If the file handle is valid, the destructor closes it.
    //!
    //! \see is_valid()
    //!
    ~file_handle(void);

    //!
    //! \brief Assignment operator; invalidates the source handle.
    //!
    //! This assignment operator transfers ownership of the RHS file
    //! handle to the LHS one, effectively invalidating the source file
    //! handle.  This avoids having two live \a file_handle objects
    //! referring to the same native file handle.  The source file
    //! handle need not be valid in the name of simplicity.
    //!
    //! \post The RHS file handle is invalid.
    //! \post The LHS file handle owns RHS' native file handle.
    //! \return A reference to the LHS file handle.
    //!
    file_handle& operator=(const file_handle& fh);

    //!
    //! \brief Checks whether the file handle is valid or not.
    //!
    //! Returns a boolean indicating whether the file handle is valid or
    //! not.  If the file handle is invalid, no other applications can be
    //! executed other than the destructor.
    //!
    //! \return True if the file handle is valid; false otherwise.
    //!
    bool is_valid(void) const;

    //!
    //! \brief Closes the file handle.
    //!
    //! Explicitly closes the file handle, which must be valid.  Upon
    //! exit, the handle is not valid any more.
    //!
    //! \pre The file handle is valid.
    //! \post The file handle is invalid.
    //! \post The native file handle is closed.
    //!
    void close(void);

    //!
    //! \brief Reclaims ownership of the native file handle.
    //!
    //! Explicitly reclaims ownership of the native file handle contained
    //! in the \a file_handle object, returning the native file handle.
    //! The caller is responsible of closing it later on.
    //!
    //! \pre The file handle is valid.
    //! \post The file handle is invalid.
    //! \return The native file handle.
    //!
    handle_type disown(void);

    //!
    //! \brief Gets the native file handle.
    //!
    //! Returns the native file handle for the \a file_handle object.
    //! The caller can issue any operation on it except closing it.
    //! If closing is required, disown() shall be used.
    //!
    //! \pre The file handle is valid.
    //! \return The native file handle.
    //!
    handle_type get(void) const;

    //!
    //! \brief Changes the native file handle to the given one.
    //!
    //! Given a new native file handle \a h, this operation assigns this
    //! handle to the current object, closing its old native file handle.
    //! In other words, it first calls dup2() to remap the old handle to
    //! the new one and then closes the old handle.
    //!
    //! If \a h matches the current value of the handle, this is a no-op.
    //! This is done for simplicity, to avoid the caller having to check
    //! this condition on its own.
    //!
    //! If \a h is open, it is automatically closed by dup2().
    //!
    //! This operation is only available in POSIX systems.
    //!
    //! \pre The file handle is valid.
    //! \pre The native file handle \a h is valid; i.e., it must be
    //!      closeable.
    //! \post The file handle's native file handle is \a h.
    //! \throw system_error If the internal remapping operation fails.
    //!
    void posix_remap(handle_type h);

private:
    //!
    //! \brief Internal handle value.
    //!
    //! This variable holds the native handle value for the file handle
    //! hold by this object.  It is interesting to note that this needs
    //! to be mutable because the copy constructor and the assignment
    //! operator invalidate the source object.
    //!
    mutable handle_type m_handle;

    //!
    //! \brief Constant function representing an invalid handle value.
    //!
    //! Returns the platform-specific handle value that represents an
    //! invalid handle.  This is a constant function rather than a regular
    //! constant because, in the latter case, we cannot define it under
    //! Win32 due to the value being of a complex type.
    //!
    static handle_type invalid_value(void);
};

// ------------------------------------------------------------------------
// The "systembuf" class.
// ------------------------------------------------------------------------

//!
//! \brief std::streambuf implementation for system file handles.
//!
//! systembuf provides a std::streambuf implementation for system file
//! handles.  Contrarywise to file_handle, this class does \b not take
//! ownership of the native file handle; this should be taken care of
//! somewhere else.
//!
//! This class follows the expected semantics of a std::streambuf object.
//! However, it is not copyable to avoid introducing inconsistences with
//! the on-disk file and the in-memory buffers.
//!
class systembuf : public std::streambuf
{
    // Non-copyable.
    systembuf(const systembuf&);
    systembuf& operator=(const systembuf&);

public:
    typedef int handle_type;

    //!
    //! \brief Constructs a new systembuf for the given file handle.
    //!
    //! This constructor creates a new systembuf object that reads or
    //! writes data from/to the \a h native file handle.  This handle
    //! is \b not owned by the created systembuf object; the code
    //! should take care of it externally.
    //!
    //! This class buffers input and output; the buffer size may be
    //! tuned through the \a bufsize parameter, which defaults to 8192
    //! bytes.
    //!
    //! \see pistream.
    //!
    explicit systembuf(handle_type h, std::size_t bufsize = 8192);
    ~systembuf(void);

private:
    //!
    //! \brief Native file handle used by the systembuf object.
    //!
    handle_type m_handle;

    //!
    //! \brief Internal buffer size used during read and write operations.
    //!
    std::size_t m_bufsize;

    //!
    //! \brief Internal buffer used during read operations.
    //!
    char* m_read_buf;

    //!
    //! \brief Internal buffer used during write operations.
    //!
    char* m_write_buf;

protected:
    //!
    //! \brief Reads new data from the native file handle.
    //!
    //! This operation is called by input methods when there are no more
    //! data in the input buffer.  The function fills the buffer with new
    //! data, if available.
    //!
    //! \pre All input positions are exhausted (gptr() >= egptr()).
    //! \post The input buffer has new data, if available.
    //! \returns traits_type::eof() if a read error occurrs or there are
    //!          no more data to be read.  Otherwise returns
    //!          traits_type::to_int_type(*gptr()).
    //!
    virtual int_type underflow(void);

    //!
    //! \brief Makes room in the write buffer for additional data.
    //!
    //! This operation is called by output methods when there is no more
    //! space in the output buffer to hold a new element.  The function
    //! first flushes the buffer's contents to disk and then clears it to
    //! leave room for more characters.  The given \a c character is
    //! stored at the beginning of the new space.
    //!
    //! \pre All output positions are exhausted (pptr() >= epptr()).
    //! \post The output buffer has more space if no errors occurred
    //!       during the write to disk.
    //! \post *(pptr() - 1) is \a c.
    //! \returns traits_type::eof() if a write error occurrs.  Otherwise
    //!          returns traits_type::not_eof(c).
    //!
    virtual int_type overflow(int c);

    //!
    //! \brief Flushes the output buffer to disk.
    //!
    //! Synchronizes the systembuf buffers with the contents of the file
    //! associated to this object through the native file handle.  The
    //! output buffer is flushed to disk and cleared to leave new room
    //! for more data.
    //!
    //! \returns 0 on success, -1 if an error occurred.
    //!
    virtual int sync(void);
};

// ------------------------------------------------------------------------
// The "pistream" class.
// ------------------------------------------------------------------------

//!
//! \brief Child process' output stream.
//!
//! The pistream class represents an output communication channel with the
//! child process.  The child process writes data to this stream and the
//! parent process can read it through the pistream object.  In other
//! words, from the child's point of view, the communication channel is an
//! output one, but from the parent's point of view it is an input one;
//! hence the confusing pistream name.
//!
//! pistream objects cannot be copied because they own the file handle
//! they use to communicate with the child and because they buffer data
//! that flows through the communication channel.
//!
//! A pistream object behaves as a std::istream stream in all senses.
//! The class is only provided because it must provide a method to let
//! the caller explicitly close the communication channel.
//!
//! \remark <b>Blocking remarks</b>: Functions that read data from this
//! stream can block if the associated file handle blocks during the read.
//! As this class is used to communicate with child processes through
//! anonymous pipes, the most typical blocking condition happens when the
//! child has no more data to send to the pipe's system buffer.  When
//! this happens, the buffer eventually empties and the system blocks
//! until the writer generates some data.
//!
class pistream : public std::istream
{
    // Non-copyable.
    pistream(const pistream&);
    pistream& operator=(const pistream&);

    //!
    //! \brief The systembuf object used to manage this stream's data.
    //!
    systembuf m_systembuf;

public:
    //!
    //! \brief Creates a new process' output stream.
    //!
    //! Given a file handle, this constructor creates a new pistream
    //! object that owns the given file handle \a fh.  Ownership of
    //! \a fh is transferred to the created pistream object.
    //!
    //! \pre \a fh is valid.
    //! \post \a fh is invalid.
    //! \post The new pistream object owns \a fh.
    //!
    explicit pistream(const int);
};

// ------------------------------------------------------------------------
// The "muxer" class.
// ------------------------------------------------------------------------

class muxer {
    // Non-copyable.
    muxer(const muxer&);
    muxer& operator=(const muxer&);

    const int* m_fds;
    const size_t m_nfds;

    const size_t m_bufsize;
    tools::auto_array< std::string > m_buffers;

protected:
    virtual void line_callback(const size_t, const std::string&) = 0;

    size_t read_one(const size_t, const int, std::string&, const bool);

public:
    muxer(const int*, const size_t, const size_t bufsize = 1024);
    virtual ~muxer(void);

    void mux(volatile const bool&);
    void flush(void);
};

} // namespace io
} // namespace tools

#endif // !defined(TOOLS_IO_HPP)
@


1.1
log
@Initial revision
@
text
@@


1.1.1.1
log
@Changes since 9.10.5-P2:

	--- 9.10.7 released ---
	--- 9.10.7rc2 released ---

4904.	[bug]		Temporarily revert change #4859. [GL #124]

	--- 9.10.7rc1 released ---

4889.	[func]		Warn about the use of old root keys without the new
			root key being present.  Warn about dlv.isc.org's
			key being present. Warn about both managed and
			trusted root keys being present. [RT #43670]

4888.	[test]		Initialize sockets correctly in sample-update so
			that the nsupdate system test will run on Windows.
			[RT #47097]

4886.	[doc]		Document dig -u in manpage. [RT #47150]

4885.	[security]	update-policy rules that otherwise ignore the name
			field now require that it be set to "." to ensure
			that any type list present is properly interpreted.
			[RT #47126]

4882.	[bug]		Address potential memory leak in
			dns_update_signaturesinc. [RT #47084]

4881.	[bug]		Only include dst_openssl.h when OpenSSL is required.
			[RT #47068]

4879.	[bug]		dns_rdata_caa:value_len field was too small.
			[RT #47086]

	--- 9.10.7b1 released ---

4876.	[bug]		Address deadlock with accessing a keytable. [RT #47000]

4874.	[bug]		Wrong time display when reporting new keywarntime.
			[RT #47042]

4872.	[bug]		Don't permit loading meta RR types such as TKEY
			from master files. [RT #47009]

4871.	[bug]		Fix configure glitch in detecting stdatomic.h
			support on systems with multiple compilers.
			[RT #46959]

4870.	[test]		Update included ATF library to atf-0.21 preserving
			the ATF tool. [RT #46967]

4869.	[bug]		Address some cases where NULL with zero length could
			be passed to memmove which is undefined behaviour and
			can lead to bad optimisation. [RT #46888]

4867.	[cleanup]	Normalize rndc on/off commands (validation and
			querylog) so they accept the same synonyms
			for on/off (yes/no, true/false, enable/disable).
			Thanks to Tony Finch. [RT #47022]

4866.	[port]		DST library initialization verifies MD5 (when MD5
			was not disabled) and SHA-1 hash and HMAC support.
			[RT #46764]

4863.	[bug]		Fix various other bugs reported by Valgrind's
			memcheck tool. [RT #46978]

4862.	[bug]		The rdata flags for RRSIG were not being properly set
			when constructing a rdataslab. [RT #46978]

4861.	[bug]		The isc_crc64 unit test was not endian independent.
			[RT #46973]

4860.	[bug]		isc_int8_t should be signed char.  [RT #46973]

4859.	[bug]		A loop was possible when attempting to validate
			unsigned CNAME responses from secure zones;
			this caused a delay in returning SERVFAIL and
			also increased the chances of encountering
			CVE-2017-3145. [RT #46839]

4858.	[security]	Addresses could be referenced after being freed
			in resolver.c, causing an assertion failure.
			(CVE-2017-3145) [RT #46839]

4857.	[bug]		Maintain attach/detach semantics for event->db,
			event->node, event->rdataset and event->sigrdataset
			in query.c. [RT #46891]

4856.	[bug]		'rndc zonestatus' reported the wrong underlying type
			for a inline slave zone. [RT #46875]

4852.	[bug]		Add REQUIRE's and INSIST's to isc_time_formattimestamp,
			isc_time_formathttptimestamp, isc_time_formatISO8601.
			[RT #46892]

4851.	[port]		Support using kyua as well as atf-run to run the unit
			tests. [RT #46853]

4846.	[test]		Adjust timing values in runtime system test. Address
			named.pid removal races in runtime system test.
			[RT #46800]

4844.	[test]		Address memory leaks in libatf-c. [RT #46798]

4843.	[bug]		dnssec-signzone free hashlist on exit. [RT #46791]

4842.	[bug]		Conditionally compile opensslecdsa_link.c to avoid
			warnings about unused function. [RT #46790]

4841.	[bug]		Address -fsanitize=undefined warnings. [RT #46786]

4840.	[test]		Add tests to cover fallback to using ZSK on inactive
			KSK. [RT #46787]

4839.	[bug]		zone.c:zone_sign was not properly determining
			if there were active KSK and ZSK keys for
			a algorithm when update-check-ksk is true
			(default) leaving records unsigned with one or
			more DNSKEY algorithms. [RT #46774]

4838.	[bug]		zone.c:add_sigs was not properly determining
			if there were active KSK and ZSK keys for
			a algorithm when update-check-ksk is true
			(default) leaving records unsigned with one or
			more DNSKEY algorithms. [RT #46754]

4837.	[bug]		dns_update_signatures{inc} (add_sigs) was not
			properly determining if there were active KSK and
			ZSK keys for a algorithm when update-check-ksk is
			true (default) leaving records unsigned when there
			were multiple DNSKEY algorithms for the zone.
			[RT #46743]

4836.	[bug]		Zones created using "rndc addzone" could
			temporarily fail to inherit an "allow-transfer"
			ACL that had been configured in the options
			statement. [RT #46603]

4833.	[bug]		isc_event_free should check that the event is not
			linked when called. [RT #46725]

4832.	[bug]		Events were not being removed from zone->rss_events.
			[RT #46725]

4831.	[bug]		Convert the RRSIG expirytime to 64 bits for
			comparisions in diff.c:resign. [RT #46710]

4830.	[bug]		Failure to configure ATF when requested did not cause
			an error in top-level configure script. [RT #46655]

4829.	[bug]		isc_heap_delete did not zero the index value when
			the heap was created with a callback to do that.
			[RT #46709]

4827.	[misc]		Add a precommit check script util/checklibs.sh
			[RT #46215]

4826.	[cleanup]	Prevent potential build failures in bin/confgen/ and
			bin/named/ when using parallel make. [RT #46648]

4823.	[test]		Refactor reclimit system test to improve its
			reliability and speed. [RT #46632]

4822.	[bug]		Use resign_sooner in dns_db_setsigningtime. [RT #46473]

4821.	[bug]		When resigning ensure that the SOA's expire time is
			always later that the resigning time of other records.
			[RT #46473]

4820.	[bug]		dns_db_subtractrdataset should transfer the resigning
			information to the new header. [RT #46473]

4819.	[bug]		Fully backout the transaction when adding a RRset
			to the resigning / removal heaps fails. [RT #46473]

4818.	[test]		The logfileconfig system test could intermittently
			report false negatives on some platforms. [RT #46615]

4817.	[cleanup]	Use DNS_NAME_INITABSOLUTE and DNS_NAME_INITNONABSOLUTE.
			[RT #45433]

4816.	[bug]		Don't use a common array for storing EDNS options
			in DiG as it could fill up. [RT #45611]

4815.	[bug]		rbt_test.c:insert_and_delete needed to call
			dns_rbt_addnode instead of dns_rbt_addname. [RT #46553]

4814.	[cleanup]	Use AS_HELP_STRING for consistent help text. [RT #46521]

4812.	[bug]		Minor improvements to stability and consistency of code
			handling managed keys. [RT #46468]

4810.	[test]		The chain system test failed if the IPv6 interfaces
			were not configured. [RT #46508]

4809.	[port]		Check at configure time whether -latomic is needed
			for stdatomic.h. [RT #46324]

4805.	[bug]		TCP4Active and TCP6Active weren't being updated
			correctly. [RT #46454]

4804.	[port]		win32: access() does not work on directories as
			required by POSIX.  Supply a alternative in
			isc_file_isdirwritable. [RT #46394]

4803.   [bug]		Backport fix for RT #46055 from RT #46267. [RT #46430]

4792.	[bug]		Fix map file header correctness check. [RT #38418]

4791.	[doc]		Fixed outdated documentation about export libraries.
			[RT #46341]

4790.	[bug]		nsupdate could trigger a require when sending a
			update to the second address of the server.
			[RT #45731]

4788.	[cleanup]	When using "update-policy local", log a warning
			when an update matching the session key is received
			from a remote host. [RT #46213]

4787.	[cleanup]	Turn nsec3param_salt_totext() into a public function,
			dns_nsec3param_salttotext(), and add unit tests for it.
			[RT #46289]

4783.	[test]		dnssec: 'check that NOTIFY is sent at the end of
			NSEC3 chain generation failed' required more time
			on some machines for the IXFR to complete. [RT #46388]

4781.	[maint]		B.ROOT-SERVERS.NET is now 199.9.14.201. [RT #45889]

4780.	[bug]		When answering ANY queries, don't include the NS
			RRset in the authority section if it was already
			in the answer section. [RT #44543]

4777.	[cleanup]	Removed a redundant call to configure_view_acl().
			[RT #46369]

4774.	[bug]		<isc/util.h> was incorrectly included in several
			header files. [RT #46311]

4773.	[doc]		Fixed generating Doxygen documentation for functions
			annotated using certain macros.  Miscellaneous
			Doxygen-related cleanups. [RT #46276]

4771.	[bug]		When sending RFC 5011 refresh queries, disregard
			cached DNSKEY rrsets. [RT #46251]

4770.	[bug]		Cache additional data from priming queries as glue.
			Previously they were ignored as unsigned
			non-answer data from a secure zone, and never
			actually got added to the cache, causing hints
			to be used frequently for root-server
			addresses, which triggered re-priming. [RT #45241]

4769.	[bug]		Enforce the requirement that the managed keys
			directory (specified by "managed-keys-directory",
			and defaulting to the working directory if not
			specified) must be writable. [RT #46077]

4766.	[cleanup]	Addresss Coverity warnings. [RT #46150]

4762.	[func]		"update-policy local" is now restricted to updates
			from local addresses. (Previously, other addresses
			were allowed so long as updates were signed by the
			local session key.) [RT #45492]

4761.	[protocol]	Add support for DOA. [RT #45612]

4759.	[func]		Add logging channel "trust-anchor-telementry" to
			record trust-anchor-telementry in incoming requests.
			Both _ta-XXXX.<anchor>/NULL and EDNS KEY-TAG options
			are logged.  [RT #46124]

4758.	[doc]		Remove documentation of unimplemented "topology".
			[RT #46161]

4756.	[bug]		Interrupting dig could lead to an INSIST failure after
			certain errors were encountered while querying a host
			whose name resolved to more than one address.  Change
			4537 increased the odds of triggering this issue by
			causing dig to hang indefinitely when certain error
			paths were evaluated.  dig now also retries TCP queries
			(once) if the server gracefully closes the connection
			before sending a response. [RT #42832, #45159]

4754.	[bug]		dns_zone_setview needs a two stage commit to properly
			handle errors. [RT #45841]

4753.	[contrib]	Software obtainable from known upstream locations
			(i.e., zkt, nslint, query-loc) has been removed.
			Links to these and other packages can be found at
			https://www.isc.org/community/tools [RT #46182]

4752.	[test]		Add unit test for isc_net_pton. [RT #46171]

4749.	[func]		The ISC DLV service has been shut down, and all
			DLV records have been removed from dlv.isc.org.
			- Removed references to ISC DLV in documentation
			- Removed DLV key from bind.keys
			- No longer use ISC DLV by default in delv
			[RT #46155]

4748.	[cleanup]	Sprintf to snprintf coversions. [RT #46132]

4746.	[cleanup]	Add configured prefixes to configure summary
			output. [RT #46153]

4745.	[test]		Add color-coded pass/fail messages to system
			tests when running on terminals that support them.
			[RT #45977]

4744.	[bug]		Suppress trust-anchor-telementry queries if
			validation is disabled. [RT #46131]

4741.	[bug]		Make isc_refcount_current() atomically read the
			counter value. [RT #46074]

4739.	[cleanup]	Address clang static analysis warnings. [RT #45952]

4738.	[port]		win32: strftime mishandles %Z. [RT #46039]

4737.	[cleanup]	Address Coverity warnings. [RT #46012]

4736.	[cleanup]	(a) Added comments to NSEC3-related functions in
			lib/dns/zone.c.  (b) Refactored NSEC3 salt formatting
			code.  (c) Minor tweaks to lock and result handling.
			[RT #46053]

4735.	[bug]		Add @@ISC_OPENSSL_LIBS@@ to isc-config. [RT #46078]

4734.	[contrib]	Added sample configuration for DNS-over-TLS in
			contrib/dnspriv.

4730.	[bug]		Fix out of bounds access in DHCID totext() method.
			[RT #46001]

4729.	[bug]		Don't use memset() to wipe memory, as it may be
			removed by compiler optimizations when the
			memset() occurs on automatic stack allocation
			just before function return. [RT #45947]

4728.	[func]		Use C11's stdatomic.h instead of isc_atomic
			where available. [RT #40668]

4727.	[bug]		Retransferring an inline-signed slave using NSEC3
			around the time its NSEC3 salt was changed could result
			in an infinite signing loop. [RT #45080]

4725.	[bug]		Nsupdate: "recvsoa" was incorrectly reported for
			failures in sending the update message.  The correct
			location to be reported is "update_completed".
			[RT #46014]

4722.	[cleanup]	Clean up uses of strcpy() and strcat() in favor of
			strlcpy() and strlcat() for safety. [RT #45981]

4719.	[bug]		Address PVS static analyzer warnings. [RT #45946]

4717.	[bug]		Treat replies with QCOUNT=0 as truncated if TC=1,
			FORMERR if TC=0, and log the error correctly.
			[RT #45836]

4715.	[bug]		TreeMemMax was mis-identified as a second HeapMemMax
			in the Json cache statistics. [RT #45980]

4714.	[port]		openbsd/libressl: add support for building with
			--enable-openssl-hash. [RT #45982]

4713.	[cleanup]	Minor revisions to RPZ code to reduce
			differences with the development branch. [RT #46037]

4712.	[bug]		"dig +domain" and "dig +search" didn't retain the
			search domain when retrying with TCP. [RT #45547]

4711.	[test]		Some RR types were missing from genzones.sh.
			[RT #45782]

4709.	[cleanup]	Use dns_name_fullhash() to hash names for RRL.
			[RT #45435]

4703.	[bug]		BINDInstall.exe was missing some buffer length checks.
			[RT #45898]

4698.	[port]		Add --with-python-install-dir configure option to allow
			specifying a nonstandard installation directory for
			Python modules. [RT #45407]

4696.	[port]		Enable filter-aaaa support by default on Windows
			builds. [RT #45883]

4692.	[bug]		Fix build failures with libressl introduced in 4676.
			[RT #45879]

4690.	[bug]		Command line options -4/-6 were handled inconsistently
			between tools. [RT #45632]

4689.	[cleanup]	Turn on minimal responses for CDNSKEY and CDS in
			addition to DNSKEY and DS. Thanks to Tony Finch.
			[RT #45690]

4688.	[protocol]	Check and display EDNS KEY TAG options (RFC 8145) in
			messages. [RT #44804]

4686.	[bug]		dnssec-settime -p could print a bogus warning about
			key deletion scheduled before its inactivation when a
			key had an inactivation date set but no deletion date
			set. [RT #45807]

4685.	[bug]		dnssec-settime incorrectly calculated publication and
			activation dates for a successor key. [RT #45806]

4684.	[bug]		delv could send bogus DNS queries when an explicit
			server address was specified on the command line along
			with -4/-6. [RT #45804]

4683.	[bug]		Prevent nsupdate from immediately exiting on invalid
			user input in interactive mode. [RT #28194]

4682.	[bug]		Don't report errors on records below a DNAME.
			[RT #44880]

4680.	[bug]		Fix failing over to another master server address when
			nsupdate is used with GSS-API. [RT #45380]

4679.	[cleanup]	Suggest using -o when dnssec-verify finds a SOA record
			not at top of zone and -o is not used. [RT #45519]

4677.	[cleanup]	Split up the main function in dig to better support
			the iOS app version. [RT #45508]

4676.	[cleanup]	Allow BIND to be built using OpenSSL 1.0.X with
			deprecated functions removed. [RT #45706]

4675.	[cleanup]	Don't use C++ keyword class. [RT #45726]

4673.	[port]		Silence GCC 7 warnings. [RT #45592]

4672.	[bug]		Fix a regression introduced by change 3938 (when
			--enable-fetchlimit is NOT in use), where named
			as resolver would, upon fetch timeout, repeat
			fetching from the same nameserver address. This
			also broke "forward first;" configurations (as
			forwarders are also treated as nameservers when
			fetching). [RT #45321]

4671.	[bug]		Fix a race condition that could cause the
			resolver to crash with assertion failure when
			chasing DS in specific conditions with a very
			short RTT to the upstream nameserver. [RT #45168]

4670.	[cleanup]	Ensure that a request MAC is never sent back
			in an XFR response unless the signature was
			verified. [RT #45494]

4668.	[bug]		Use localtime_r and gmtime_r for thread safety.
			[RT #45664]

4667.	[cleanup]	Refactor RDATA unit tests. [RT #45610]

4665.	[protocol]	Added support for ED25519 and ED448 DNSSEC signing
			algorithms (RFC 8080). (Note: these algorithms
			depend on code currently in the development branch
			of OpenSSL which has not yet been released.)
			[RT #44696]

4663.	[cleanup]	Clarify error message printed by dnssec-dsfromkey.
			[RT #21731]

4662.	[performance]	Improve cache memory cleanup of zero TTL records
			by putting them at the tail of LRU header lists.
			[RT #45274]

4661.	[bug]		A race condition could occur if a zone was reloaded
			while resigning, triggering a crash in
			rbtdb.c:closeversion(). [RT #45276]

4660.	[bug]		Remove spurious "peer" from Windows socket log
			messages. [RT #45617]

4658.	[bug]		Clean up build directory created by "setup.py install"
			immediately.  [RT #45628]

4657.	[bug]		rrchecker system test result could be improperly
			determined. [RT #45602]

4655.	[bug]		Lack of seccomp could be falsely reported. [RT #45599]

4654.	[cleanup]	Don't use C++ keywords delete, new and namespace.
			[RT #45538]

4652.	[bug]		Nsupdate could attempt to use a zeroed address on
			server timeout. [RT #45417]

4651.	[test]		Silence coverity warnings in tsig_test.c. [RT #45528]

	--- 9.10.6 released ---

	--- 9.10.6rc2 released ---

4653.	[bug]		Reorder includes to move @@DST_OPENSSL_INC@@ and
			@@ISC_OPENSSL_INC@@ after shipped include directories.
			[RT #45581]

	--- 9.10.6rc1 released ---

4647.	[bug]		Change 4643 broke verification of TSIG signed TCP
			message sequences where not all the messages contain
			TSIG records.  These may be used in AXFR and IXFR
			responses. [RT #45509]

4645.	[bug]		Fix PKCS#11 RSA parsing when MD5 is disabled.
			[RT #45300]

	--- 9.10.6b1 released ---

4643.	[security]	An error in TSIG handling could permit unauthorized
			zone transfers or zone updates. (CVE-2017-3142)
			(CVE-2017-3143) [RT #45383]

4642.	[cleanup]	Add more logging of RFC 5011 events affecting the
			status of managed keys: newly observed keys,
			deletion of revoked keys, etc. [RT #45354]

4641.	[cleanup]	Parallel builds (make -j) could fail with --with-atf /
			--enable-developer. [RT #45373]

4640.	[bug]		If query_findversion failed in query_getdb due to
			memory failure the error status was incorrectly
			discarded. [RT #45331]

4636.	[bug]		Normalize rpz policy zone names when checking for
			existence. [RT #45358]

4635.	[bug]		Fix RPZ NSDNAME logging that was logging
			failures as NSIP. [RT #45052]

4634.	[contrib]	check5011.pl needs to handle optional space before
			semi-colon in +multi-line output. [RT #45352]

4633.	[maint]		Updated AAAA (2001:500:200::b) for B.ROOT-SERVERS.NET.

4632.	[security]	The BIND installer on Windows used an unquoted
			service path, which can enable privilege escalation.
			(CVE-2017-3141) [RT #45229]

4631.	[security]	Some RPZ configurations could go into an infinite
			query loop when encountering responses with TTL=0.
			(CVE-2017-3140) [RT #45181]

4629.	[bug]		dns_client_startupdate could not be called with a
			running client. [RT #45277]

4628.	[bug]		Fixed a potential reference leak in query_getdb().
			[RT #45247]

4627.	[func]		Deprecate 'dig +sit', it is replaced by 'dig +cookie'.
			[RT #45245]

4626.	[test]		Added more tests for handling of different record
			ordering in CNAME and DNAME responses. [QA #430]

4624.	[bug]		Check isc_mem_strdup results in dns_view_setnewzones.
			[RT #45210]

4622.	[bug]		Remove unnecessary escaping of semicolon in CAA and
			URI records. [RT #45216]

4621.	[port]		Force alignment of oid arrays to silence loader
			warnings. [RT #45131]

4620.	[port]		Handle EPFNOSUPPORT being returned when probing
			to see if a socket type is supported. [RT #45214]

4617.	[test]		Update rndc system test to be more delay tolerant.
			[RT #45177]

4615.	[bug]		AD could be set on truncated answer with no records
			present in the answer and authority sections.
			[RT #45140]

4614.	[test]		Fixed an error in the sockaddr unit test. [RT #45146]

4612.	[bug]		Silence 'may be use uninitalised' warning and simplify
			the code in lwres/getaddinfo:process_answer.
			[RT #45158]

4609.	[cleanup]	Rearrange makefiles to enable parallel execution
			(i.e. "make -j"). [RT #45078]

4608.	[func]		DiG now warns about .local queries which are reserved
			for Multicast DNS. [RT #44783]

4606.	[port]		Stop using experimental "Experimental keys on scalar"
			feature of perl as it has been removed. [RT #45012]

4604.	[bug]		Don't use ERR_load_crypto_strings() when building
			with OpenSSL 1.1.0. [RT #45117]

4603.	[doc]		Automatically generate named.conf(5) man page
			from doc/misc/options. Thanks to Tony Finch.
			[RT #43525]

4602.	[func]		Threads are now set to human-readable
			names to assist debugging, when supported by
			the OS. [RT #43234]

4601.	[bug]		Reject incorrect RSA key lengths during key
			generation and and sign/verify context
			creation. [RT #45043]

4600.	[bug]		Adjust RPZ trigger counts only when the entry
			being deleted exists. [RT #43386]

4599.	[bug]		Fix inconsistencies in inline signing time
			comparison that were introduced with the
			introduction of rdatasetheader->resign_lsb.
			[RT #42112]

4597.	[bug]		The validator now ignores SHA-1 DS digest type
			when a DS record with SHA-384 digest type is
			present and is a supported digest type.
			[RT #45017]

4596.	[bug]		Validate glue before adding it to the additional
			section. This also fixes incorrect TTL capping
			when the RRSIG expired earlier than the TTL.
			[RT #45062]

4593.	[doc]		Update README using markdown, remove outdated FAQ
			file in favor of the knowledge base.

4592.	[bug]		A race condition on shutdown could trigger an
			assertion failure in dispatch.c. [RT #43822]

4591.	[port]		Addressed some python 3 compatibility issues.
			Thanks to Ville Skytta. [RT #44955] [RT #44956]

4590.	[bug]		Support for PTHREAD_MUTEX_ADAPTIVE_NP was not being
			properly detected. [RT #44871]

4589.	[cleanup]	"configure -q" is now silent. [RT #44829]

4588.	[bug]		nsupdate could send queries for TKEY to the wrong
			server when using GSSAPI. Thanks to Tomas Hozza.
			[RT #39893]

4587.	[bug]		named-checkzone failed to handle occulted data below
			DNAMEs correctly. [RT #44877]

4585.	[port]		win32: Set CompileAS value. [RT #42474]

4584.	[bug]		A number of memory usage statistics were not properly
			reported when they exceeded 4G.  [RT #44750]

4574.	[bug]		Dig leaked memory with multiple +subnet options.
			[RT #44683]

4555.	[func]		dig +ednsopt: EDNS options can now be specified by
			name in addition to numeric value. [RT #44461]
@
text
@@


1.1.1.1.4.1
log
@Sync with HEAD
@
text
@@


1.1.1.1.2.1
log
@file io.hpp was added on branch pgoyette-compat on 2018-04-16 01:58:06 +0000
@
text
@d1 436
@


1.1.1.1.2.2
log
@Sync with HEAD, resolve some conflicts
@
text
@a0 436
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#if !defined(TOOLS_IO_HPP)
#define TOOLS_IO_HPP

#include <istream>
#include <ostream>
#include <streambuf>

#include "auto_array.hpp"
#include "fs.hpp"

namespace tools {
namespace io {

// ------------------------------------------------------------------------
// The "file_handle" class.
// ------------------------------------------------------------------------

//!
//! \brief Simple RAII model for system file handles.
//!
//! The \a file_handle class is a simple RAII model for native system file
//! handles.  This class wraps one of such handles grabbing its ownership,
//! and automaticaly closes it upon destruction.  It is basically used
//! inside the library to avoid leaking open file handles, shall an
//! unexpected execution trace occur.
//!
//! A \a file_handle object can be copied but doing so invalidates the
//! source object.  There can only be a single valid \a file_handle object
//! for a given system file handle.  This is similar to std::auto_ptr\<\>'s
//! semantics.
//!
//! This class also provides some convenience methods to issue special file
//! operations under their respective platforms.
//!
class file_handle
{
public:
    //!
    //! \brief Opaque name for the native handle type.
    //!
    //! Each operating system identifies file handles using a specific type.
    //! The \a handle_type type is used to transparently refer to file
    //! handles regarless of the operating system in which this class is
    //! used.
    //!
    //! If this class is used in a POSIX system, \a NativeSystemHandle is
    //! an integer type while it is a \a HANDLE in a Win32 system.
    //!
    typedef int handle_type;

    //!
    //! \brief Constructs an invalid file handle.
    //!
    //! This constructor creates a new \a file_handle object that represents
    //! an invalid file handle.  An invalid file handle can be copied but
    //! cannot be manipulated in any way (except checking for its validity).
    //!
    //! \see is_valid()
    //!
    file_handle(void);

    //!
    //! \brief Constructs a new file handle from a native file handle.
    //!
    //! This constructor creates a new \a file_handle object that takes
    //! ownership of the given \a h native file handle.  The user must not
    //! close \a h on his own during the lifetime of the new object.
    //! Ownership can be reclaimed using disown().
    //!
    //! \pre The native file handle must be valid; a close operation must
    //!      succeed on it.
    //!
    //! \see disown()
    //!
    file_handle(handle_type h);

    //!
    //! \brief Copy constructor; invalidates the source handle.
    //!
    //! This copy constructor creates a new file handle from a given one.
    //! Ownership of the native file handle is transferred to the new
    //! object, effectively invalidating the source file handle.  This
    //! avoids having two live \a file_handle objects referring to the
    //! same native file handle.  The source file handle need not be
    //! valid in the name of simplicity.
    //!
    //! \post The source file handle is invalid.
    //! \post The new file handle owns the source's native file handle.
    //!
    file_handle(const file_handle& fh);

    //!
    //! \brief Releases resources if the handle is valid.
    //!
    //! If the file handle is valid, the destructor closes it.
    //!
    //! \see is_valid()
    //!
    ~file_handle(void);

    //!
    //! \brief Assignment operator; invalidates the source handle.
    //!
    //! This assignment operator transfers ownership of the RHS file
    //! handle to the LHS one, effectively invalidating the source file
    //! handle.  This avoids having two live \a file_handle objects
    //! referring to the same native file handle.  The source file
    //! handle need not be valid in the name of simplicity.
    //!
    //! \post The RHS file handle is invalid.
    //! \post The LHS file handle owns RHS' native file handle.
    //! \return A reference to the LHS file handle.
    //!
    file_handle& operator=(const file_handle& fh);

    //!
    //! \brief Checks whether the file handle is valid or not.
    //!
    //! Returns a boolean indicating whether the file handle is valid or
    //! not.  If the file handle is invalid, no other applications can be
    //! executed other than the destructor.
    //!
    //! \return True if the file handle is valid; false otherwise.
    //!
    bool is_valid(void) const;

    //!
    //! \brief Closes the file handle.
    //!
    //! Explicitly closes the file handle, which must be valid.  Upon
    //! exit, the handle is not valid any more.
    //!
    //! \pre The file handle is valid.
    //! \post The file handle is invalid.
    //! \post The native file handle is closed.
    //!
    void close(void);

    //!
    //! \brief Reclaims ownership of the native file handle.
    //!
    //! Explicitly reclaims ownership of the native file handle contained
    //! in the \a file_handle object, returning the native file handle.
    //! The caller is responsible of closing it later on.
    //!
    //! \pre The file handle is valid.
    //! \post The file handle is invalid.
    //! \return The native file handle.
    //!
    handle_type disown(void);

    //!
    //! \brief Gets the native file handle.
    //!
    //! Returns the native file handle for the \a file_handle object.
    //! The caller can issue any operation on it except closing it.
    //! If closing is required, disown() shall be used.
    //!
    //! \pre The file handle is valid.
    //! \return The native file handle.
    //!
    handle_type get(void) const;

    //!
    //! \brief Changes the native file handle to the given one.
    //!
    //! Given a new native file handle \a h, this operation assigns this
    //! handle to the current object, closing its old native file handle.
    //! In other words, it first calls dup2() to remap the old handle to
    //! the new one and then closes the old handle.
    //!
    //! If \a h matches the current value of the handle, this is a no-op.
    //! This is done for simplicity, to avoid the caller having to check
    //! this condition on its own.
    //!
    //! If \a h is open, it is automatically closed by dup2().
    //!
    //! This operation is only available in POSIX systems.
    //!
    //! \pre The file handle is valid.
    //! \pre The native file handle \a h is valid; i.e., it must be
    //!      closeable.
    //! \post The file handle's native file handle is \a h.
    //! \throw system_error If the internal remapping operation fails.
    //!
    void posix_remap(handle_type h);

private:
    //!
    //! \brief Internal handle value.
    //!
    //! This variable holds the native handle value for the file handle
    //! hold by this object.  It is interesting to note that this needs
    //! to be mutable because the copy constructor and the assignment
    //! operator invalidate the source object.
    //!
    mutable handle_type m_handle;

    //!
    //! \brief Constant function representing an invalid handle value.
    //!
    //! Returns the platform-specific handle value that represents an
    //! invalid handle.  This is a constant function rather than a regular
    //! constant because, in the latter case, we cannot define it under
    //! Win32 due to the value being of a complex type.
    //!
    static handle_type invalid_value(void);
};

// ------------------------------------------------------------------------
// The "systembuf" class.
// ------------------------------------------------------------------------

//!
//! \brief std::streambuf implementation for system file handles.
//!
//! systembuf provides a std::streambuf implementation for system file
//! handles.  Contrarywise to file_handle, this class does \b not take
//! ownership of the native file handle; this should be taken care of
//! somewhere else.
//!
//! This class follows the expected semantics of a std::streambuf object.
//! However, it is not copyable to avoid introducing inconsistences with
//! the on-disk file and the in-memory buffers.
//!
class systembuf : public std::streambuf
{
    // Non-copyable.
    systembuf(const systembuf&);
    systembuf& operator=(const systembuf&);

public:
    typedef int handle_type;

    //!
    //! \brief Constructs a new systembuf for the given file handle.
    //!
    //! This constructor creates a new systembuf object that reads or
    //! writes data from/to the \a h native file handle.  This handle
    //! is \b not owned by the created systembuf object; the code
    //! should take care of it externally.
    //!
    //! This class buffers input and output; the buffer size may be
    //! tuned through the \a bufsize parameter, which defaults to 8192
    //! bytes.
    //!
    //! \see pistream.
    //!
    explicit systembuf(handle_type h, std::size_t bufsize = 8192);
    ~systembuf(void);

private:
    //!
    //! \brief Native file handle used by the systembuf object.
    //!
    handle_type m_handle;

    //!
    //! \brief Internal buffer size used during read and write operations.
    //!
    std::size_t m_bufsize;

    //!
    //! \brief Internal buffer used during read operations.
    //!
    char* m_read_buf;

    //!
    //! \brief Internal buffer used during write operations.
    //!
    char* m_write_buf;

protected:
    //!
    //! \brief Reads new data from the native file handle.
    //!
    //! This operation is called by input methods when there are no more
    //! data in the input buffer.  The function fills the buffer with new
    //! data, if available.
    //!
    //! \pre All input positions are exhausted (gptr() >= egptr()).
    //! \post The input buffer has new data, if available.
    //! \returns traits_type::eof() if a read error occurrs or there are
    //!          no more data to be read.  Otherwise returns
    //!          traits_type::to_int_type(*gptr()).
    //!
    virtual int_type underflow(void);

    //!
    //! \brief Makes room in the write buffer for additional data.
    //!
    //! This operation is called by output methods when there is no more
    //! space in the output buffer to hold a new element.  The function
    //! first flushes the buffer's contents to disk and then clears it to
    //! leave room for more characters.  The given \a c character is
    //! stored at the beginning of the new space.
    //!
    //! \pre All output positions are exhausted (pptr() >= epptr()).
    //! \post The output buffer has more space if no errors occurred
    //!       during the write to disk.
    //! \post *(pptr() - 1) is \a c.
    //! \returns traits_type::eof() if a write error occurrs.  Otherwise
    //!          returns traits_type::not_eof(c).
    //!
    virtual int_type overflow(int c);

    //!
    //! \brief Flushes the output buffer to disk.
    //!
    //! Synchronizes the systembuf buffers with the contents of the file
    //! associated to this object through the native file handle.  The
    //! output buffer is flushed to disk and cleared to leave new room
    //! for more data.
    //!
    //! \returns 0 on success, -1 if an error occurred.
    //!
    virtual int sync(void);
};

// ------------------------------------------------------------------------
// The "pistream" class.
// ------------------------------------------------------------------------

//!
//! \brief Child process' output stream.
//!
//! The pistream class represents an output communication channel with the
//! child process.  The child process writes data to this stream and the
//! parent process can read it through the pistream object.  In other
//! words, from the child's point of view, the communication channel is an
//! output one, but from the parent's point of view it is an input one;
//! hence the confusing pistream name.
//!
//! pistream objects cannot be copied because they own the file handle
//! they use to communicate with the child and because they buffer data
//! that flows through the communication channel.
//!
//! A pistream object behaves as a std::istream stream in all senses.
//! The class is only provided because it must provide a method to let
//! the caller explicitly close the communication channel.
//!
//! \remark <b>Blocking remarks</b>: Functions that read data from this
//! stream can block if the associated file handle blocks during the read.
//! As this class is used to communicate with child processes through
//! anonymous pipes, the most typical blocking condition happens when the
//! child has no more data to send to the pipe's system buffer.  When
//! this happens, the buffer eventually empties and the system blocks
//! until the writer generates some data.
//!
class pistream : public std::istream
{
    // Non-copyable.
    pistream(const pistream&);
    pistream& operator=(const pistream&);

    //!
    //! \brief The systembuf object used to manage this stream's data.
    //!
    systembuf m_systembuf;

public:
    //!
    //! \brief Creates a new process' output stream.
    //!
    //! Given a file handle, this constructor creates a new pistream
    //! object that owns the given file handle \a fh.  Ownership of
    //! \a fh is transferred to the created pistream object.
    //!
    //! \pre \a fh is valid.
    //! \post \a fh is invalid.
    //! \post The new pistream object owns \a fh.
    //!
    explicit pistream(const int);
};

// ------------------------------------------------------------------------
// The "muxer" class.
// ------------------------------------------------------------------------

class muxer {
    // Non-copyable.
    muxer(const muxer&);
    muxer& operator=(const muxer&);

    const int* m_fds;
    const size_t m_nfds;

    const size_t m_bufsize;
    tools::auto_array< std::string > m_buffers;

protected:
    virtual void line_callback(const size_t, const std::string&) = 0;

    size_t read_one(const size_t, const int, std::string&, const bool);

public:
    muxer(const int*, const size_t, const size_t bufsize = 1024);
    virtual ~muxer(void);

    void mux(volatile const bool&);
    void flush(void);
};

} // namespace io
} // namespace tools

#endif // !defined(TOOLS_IO_HPP)
@


