$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: chris_at_[hidden]
Date: 2008-06-09 08:54:57
Author: chris_kohlhoff
Date: 2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
New Revision: 46272
URL: http://svn.boost.org/trac/boost/changeset/46272
Log:
Add support for serial ports.
Added:
   trunk/boost/asio/basic_serial_port.hpp   (contents, props changed)
   trunk/boost/asio/detail/reactive_serial_port_service.hpp   (contents, props changed)
   trunk/boost/asio/detail/win_iocp_serial_port_service.hpp   (contents, props changed)
   trunk/boost/asio/impl/serial_port_base.ipp   (contents, props changed)
   trunk/boost/asio/serial_port.hpp   (contents, props changed)
   trunk/boost/asio/serial_port_base.hpp   (contents, props changed)
   trunk/boost/asio/serial_port_service.hpp   (contents, props changed)
   trunk/libs/asio/test/basic_serial_port.cpp   (contents, props changed)
   trunk/libs/asio/test/serial_port.cpp   (contents, props changed)
   trunk/libs/asio/test/serial_port_base.cpp   (contents, props changed)
   trunk/libs/asio/test/serial_port_service.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/asio.hpp                                    |     4 ++++                                    
   trunk/boost/asio/detail/descriptor_ops.hpp              |    18 ++++++++++++++++++                      
   trunk/boost/asio/detail/reactive_descriptor_service.hpp |     2 +-                                      
   trunk/boost/asio/detail/win_iocp_handle_service.hpp     |     4 ++--                                    
   4 files changed, 25 insertions(+), 3 deletions(-)
Modified: trunk/boost/asio.hpp
==============================================================================
--- trunk/boost/asio.hpp	(original)
+++ trunk/boost/asio.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -21,6 +21,7 @@
 #include <boost/asio/basic_deadline_timer.hpp>
 #include <boost/asio/basic_io_object.hpp>
 #include <boost/asio/basic_raw_socket.hpp>
+#include <boost/asio/basic_serial_port.hpp>
 #include <boost/asio/basic_socket_acceptor.hpp>
 #include <boost/asio/basic_socket_iostream.hpp>
 #include <boost/asio/basic_socket_streambuf.hpp>
@@ -73,6 +74,9 @@
 #include <boost/asio/raw_socket_service.hpp>
 #include <boost/asio/read.hpp>
 #include <boost/asio/read_until.hpp>
+#include <boost/asio/serial_port.hpp>
+#include <boost/asio/serial_port_base.hpp>
+#include <boost/asio/serial_port_service.hpp>
 #include <boost/asio/socket_acceptor_service.hpp>
 #include <boost/asio/socket_base.hpp>
 #include <boost/asio/strand.hpp>
Added: trunk/boost/asio/basic_serial_port.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/basic_serial_port.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,610 @@
+//
+// basic_serial_port.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+#ifndef BOOST_ASIO_BASIC_SERIAL_PORT_HPP
+#define BOOST_ASIO_BASIC_SERIAL_PORT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <string>
+#include <boost/config.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/serial_port_base.hpp>
+#include <boost/asio/serial_port_service.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+
+#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
+  || defined(GENERATING_DOCUMENTATION)
+
+namespace boost {
+namespace asio {
+
+/// Provides serial port functionality.
+/**
+ * The basic_serial_port class template provides functionality that is common
+ * to all serial ports.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe._at_n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename SerialPortService = serial_port_service>
+class basic_serial_port
+  : public basic_io_object<SerialPortService>,
+    public serial_port_base
+{
+public:
+  /// The native representation of a serial port.
+  typedef typename SerialPortService::native_type native_type;
+
+  /// A basic_serial_port is always the lowest layer.
+  typedef basic_serial_port<SerialPortService> lowest_layer_type;
+
+  /// Construct a basic_serial_port without opening it.
+  /**
+   * This constructor creates a serial port without opening it.
+   *
+   * @param io_service The io_service object that the serial port will use to
+   * dispatch handlers for any asynchronous operations performed on the port.
+   */
+  explicit basic_serial_port(boost::asio::io_service& io_service)
+    : basic_io_object<SerialPortService>(io_service)
+  {
+  }
+
+  /// Construct and open a basic_serial_port.
+  /**
+   * This constructor creates and opens a serial port for the specified device
+   * name.
+   *
+   * @param io_service The io_service object that the serial port will use to
+   * dispatch handlers for any asynchronous operations performed on the port.
+   *
+   * @param device The platform-specific device name for this serial
+   * port.
+   */
+  explicit basic_serial_port(boost::asio::io_service& io_service,
+      const char* device)
+    : basic_io_object<SerialPortService>(io_service)
+  {
+    boost::system::error_code ec;
+    this->service.open(this->implementation, device, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Construct and open a basic_serial_port.
+  /**
+   * This constructor creates and opens a serial port for the specified device
+   * name.
+   *
+   * @param io_service The io_service object that the serial port will use to
+   * dispatch handlers for any asynchronous operations performed on the port.
+   *
+   * @param device The platform-specific device name for this serial
+   * port.
+   */
+  explicit basic_serial_port(boost::asio::io_service& io_service,
+      const std::string& device)
+    : basic_io_object<SerialPortService>(io_service)
+  {
+    boost::system::error_code ec;
+    this->service.open(this->implementation, device, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Construct a basic_serial_port on an existing native serial port.
+  /**
+   * This constructor creates a serial port object to hold an existing native
+   * serial port.
+   *
+   * @param io_service The io_service object that the serial port will use to
+   * dispatch handlers for any asynchronous operations performed on the port.
+   *
+   * @param native_serial_port A native serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_serial_port(boost::asio::io_service& io_service,
+      const native_type& native_serial_port)
+    : basic_io_object<SerialPortService>(io_service)
+  {
+    boost::system::error_code ec;
+    this->service.assign(this->implementation, native_serial_port, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Get a reference to the lowest layer.
+  /**
+   * This function returns a reference to the lowest layer in a stack of
+   * layers. Since a basic_serial_port cannot contain any further layers, it
+   * simply returns a reference to itself.
+   *
+   * @return A reference to the lowest layer in the stack of layers. Ownership
+   * is not transferred to the caller.
+   */
+  lowest_layer_type& lowest_layer()
+  {
+    return *this;
+  }
+
+  /// Open the serial port using the specified device name.
+  /**
+   * This function opens the serial port for the specified device name.
+   *
+   * @param device The platform-specific device name.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void open(const std::string& device)
+  {
+    boost::system::error_code ec;
+    this->service.open(this->implementation, device, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Open the serial port using the specified device name.
+  /**
+   * This function opens the serial port using the given platform-specific
+   * device name.
+   *
+   * @param device The platform-specific device name.
+   *
+   * @param ec Set the indicate what error occurred, if any.
+   */
+  boost::system::error_code open(const std::string& device,
+      boost::system::error_code& ec)
+  {
+    return this->service.open(this->implementation, device, ec);
+  }
+
+  /// Assign an existing native serial port to the serial port.
+  /*
+   * This function opens the serial port to hold an existing native serial port.
+   *
+   * @param native_serial_port A native serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void assign(const native_type& native_serial_port)
+  {
+    boost::system::error_code ec;
+    this->service.assign(this->implementation, native_serial_port, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Assign an existing native serial port to the serial port.
+  /*
+   * This function opens the serial port to hold an existing native serial port.
+   *
+   * @param native_serial_port A native serial port.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  boost::system::error_code assign(const native_type& native_serial_port,
+      boost::system::error_code& ec)
+  {
+    return this->service.assign(this->implementation, native_serial_port, ec);
+  }
+
+  /// Determine whether the serial port is open.
+  bool is_open() const
+  {
+    return this->service.is_open(this->implementation);
+  }
+
+  /// Close the serial port.
+  /**
+   * This function is used to close the serial port. Any asynchronous read or
+   * write operations will be cancelled immediately, and will complete with the
+   * boost::asio::error::operation_aborted error.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void close()
+  {
+    boost::system::error_code ec;
+    this->service.close(this->implementation, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Close the serial port.
+  /**
+   * This function is used to close the serial port. Any asynchronous read or
+   * write operations will be cancelled immediately, and will complete with the
+   * boost::asio::error::operation_aborted error.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  boost::system::error_code close(boost::system::error_code& ec)
+  {
+    return this->service.close(this->implementation, ec);
+  }
+
+  /// Get the native serial port representation.
+  /**
+   * This function may be used to obtain the underlying representation of the
+   * serial port. This is intended to allow access to native serial port
+   * functionality that is not otherwise provided.
+   */
+  native_type native()
+  {
+    return this->service.native(this->implementation);
+  }
+
+  /// Cancel all asynchronous operations associated with the serial port.
+  /**
+   * This function causes all outstanding asynchronous read or write operations
+   * to finish immediately, and the handlers for cancelled operations will be
+   * passed the boost::asio::error::operation_aborted error.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void cancel()
+  {
+    boost::system::error_code ec;
+    this->service.cancel(this->implementation, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Cancel all asynchronous operations associated with the serial port.
+  /**
+   * This function causes all outstanding asynchronous read or write operations
+   * to finish immediately, and the handlers for cancelled operations will be
+   * passed the boost::asio::error::operation_aborted error.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  boost::system::error_code cancel(boost::system::error_code& ec)
+  {
+    return this->service.cancel(this->implementation, ec);
+  }
+
+  /// Send a break sequence to the serial port.
+  /**
+   * This function causes a break sequence of platform-specific duration to be
+   * sent out the serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void send_break()
+  {
+    boost::system::error_code ec;
+    this->service.send_break(this->implementation, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Send a break sequence to the serial port.
+  /**
+   * This function causes a break sequence of platform-specific duration to be
+   * sent out the serial port.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  boost::system::error_code send_break(boost::system::error_code& ec)
+  {
+    return this->service.send_break(this->implementation, ec);
+  }
+
+  /// Set an option on the serial port.
+  /**
+   * This function is used to set an option on the serial port.
+   *
+   * @param option The option value to be set on the serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa SettableSerialPortOption @n
+   * boost::asio::serial_port_base::baud_rate @n
+   * boost::asio::serial_port_base::flow_control @n
+   * boost::asio::serial_port_base::parity @n
+   * boost::asio::serial_port_base::stop_bits @n
+   * boost::asio::serial_port_base::character_size
+   */
+  template <typename SettableSerialPortOption>
+  void set_option(const SettableSerialPortOption& option)
+  {
+    boost::system::error_code ec;
+    this->service.set_option(this->implementation, option, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Set an option on the serial port.
+  /**
+   * This function is used to set an option on the serial port.
+   *
+   * @param option The option value to be set on the serial port.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @sa SettableSerialPortOption @n
+   * boost::asio::serial_port_base::baud_rate @n
+   * boost::asio::serial_port_base::flow_control @n
+   * boost::asio::serial_port_base::parity @n
+   * boost::asio::serial_port_base::stop_bits @n
+   * boost::asio::serial_port_base::character_size
+   */
+  template <typename SettableSerialPortOption>
+  boost::system::error_code set_option(const SettableSerialPortOption& option,
+      boost::system::error_code& ec)
+  {
+    return this->service.set_option(this->implementation, option, ec);
+  }
+
+  /// Get an option from the serial port.
+  /**
+   * This function is used to get the current value of an option on the serial
+   * port.
+   *
+   * @param option The option value to be obtained from the serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa GettableSerialPortOption @n
+   * boost::asio::serial_port_base::baud_rate @n
+   * boost::asio::serial_port_base::flow_control @n
+   * boost::asio::serial_port_base::parity @n
+   * boost::asio::serial_port_base::stop_bits @n
+   * boost::asio::serial_port_base::character_size
+   */
+  template <typename GettableSerialPortOption>
+  void get_option(GettableSerialPortOption& option)
+  {
+    boost::system::error_code ec;
+    this->service.get_option(this->implementation, option, ec);
+    boost::asio::detail::throw_error(ec);
+  }
+
+  /// Get an option from the serial port.
+  /**
+   * This function is used to get the current value of an option on the serial
+   * port.
+   *
+   * @param option The option value to be obtained from the serial port.
+   *
+   * @param ec Set to indicate what error occured, if any.
+   *
+   * @sa GettableSerialPortOption @n
+   * boost::asio::serial_port_base::baud_rate @n
+   * boost::asio::serial_port_base::flow_control @n
+   * boost::asio::serial_port_base::parity @n
+   * boost::asio::serial_port_base::stop_bits @n
+   * boost::asio::serial_port_base::character_size
+   */
+  template <typename GettableSerialPortOption>
+  boost::system::error_code get_option(GettableSerialPortOption& option,
+      boost::system::error_code& ec)
+  {
+    return this->service.get_option(this->implementation, option, ec);
+  }
+
+  /// Write some data to the serial port.
+  /**
+   * This function is used to write data to the serial port. The function call
+   * will block until one or more bytes of the data has been written
+   * successfully, or until an error occurs.
+   *
+   * @param buffers One or more data buffers to be written to the serial port.
+   *
+   * @returns The number of bytes written.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The write_some operation may not transmit all of the data to the
+   * peer. Consider using the @ref write function if you need to ensure that
+   * all data is written before the blocking operation completes.
+   *
+   * @par Example
+   * To write a single data buffer use the @ref buffer function as follows:
+   * @code
+   * serial_port.write_some(boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on writing multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->service.write_some(this->implementation, buffers, ec);
+    boost::asio::detail::throw_error(ec);
+    return s;
+  }
+
+  /// Write some data to the serial port.
+  /**
+   * This function is used to write data to the serial port. The function call
+   * will block until one or more bytes of the data has been written
+   * successfully, or until an error occurs.
+   *
+   * @param buffers One or more data buffers to be written to the serial port.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes written. Returns 0 if an error occurred.
+   *
+   * @note The write_some operation may not transmit all of the data to the
+   * peer. Consider using the @ref write function if you need to ensure that
+   * all data is written before the blocking operation completes.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return this->service.write_some(this->implementation, buffers, ec);
+  }
+
+  /// Start an asynchronous write.
+  /**
+   * This function is used to asynchronously write data to the serial port.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be written to the serial port.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the write operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes written.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_service::post().
+   *
+   * @note The write operation may not transmit all of the data to the peer.
+   * Consider using the @ref async_write function if you need to ensure that all
+   * data is written before the asynchronous operation completes.
+   *
+   * @par Example
+   * To write a single data buffer use the @ref buffer function as follows:
+   * @code
+   * serial_port.async_write_some(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on writing multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  void async_write_some(const ConstBufferSequence& buffers,
+      WriteHandler handler)
+  {
+    this->service.async_write_some(this->implementation, buffers, handler);
+  }
+
+  /// Read some data from the serial port.
+  /**
+   * This function is used to read data from the serial port. The function
+   * call will block until one or more bytes of data has been read successfully,
+   * or until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   *
+   * @returns The number of bytes read.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The read_some operation may not read all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that
+   * the requested amount of data is read before the blocking operation
+   * completes.
+   *
+   * @par Example
+   * To read into a single data buffer use the @ref buffer function as follows:
+   * @code
+   * serial_port.read_some(boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on reading into multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->service.read_some(this->implementation, buffers, ec);
+    boost::asio::detail::throw_error(ec);
+    return s;
+  }
+
+  /// Read some data from the serial port.
+  /**
+   * This function is used to read data from the serial port. The function
+   * call will block until one or more bytes of data has been read successfully,
+   * or until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes read. Returns 0 if an error occurred.
+   *
+   * @note The read_some operation may not read all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that
+   * the requested amount of data is read before the blocking operation
+   * completes.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return this->service.read_some(this->implementation, buffers, ec);
+  }
+
+  /// Start an asynchronous read.
+  /**
+   * This function is used to asynchronously read data from the serial port.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the read operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes read.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_service::post().
+   *
+   * @note The read operation may not read all of the requested number of bytes.
+   * Consider using the @ref async_read function if you need to ensure that the
+   * requested amount of data is read before the asynchronous operation
+   * completes.
+   *
+   * @par Example
+   * To read into a single data buffer use the @ref buffer function as follows:
+   * @code
+   * serial_port.async_read_some(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on reading into multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  void async_read_some(const MutableBufferSequence& buffers,
+      ReadHandler handler)
+  {
+    this->service.async_read_some(this->implementation, buffers, handler);
+  }
+};
+
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
+       //   || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP
Modified: trunk/boost/asio/detail/descriptor_ops.hpp
==============================================================================
--- trunk/boost/asio/detail/descriptor_ops.hpp	(original)
+++ trunk/boost/asio/detail/descriptor_ops.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -47,6 +47,12 @@
   return return_value;
 }
 
+inline int open(const char* path, int flags, boost::system::error_code& ec)
+{
+  clear_error(ec);
+  return error_wrapper(::open(path, flags), ec);
+}
+
 inline int close(int d, boost::system::error_code& ec)
 {
   clear_error(ec);
@@ -88,6 +94,18 @@
   return error_wrapper(::ioctl(d, cmd, arg), ec);
 }
 
+inline int fcntl(int d, long cmd, boost::system::error_code& ec)
+{
+  clear_error(ec);
+  return error_wrapper(::fcntl(d, cmd), ec);
+}
+
+inline int fcntl(int d, long cmd, long arg, boost::system::error_code& ec)
+{
+  clear_error(ec);
+  return error_wrapper(::fcntl(d, cmd, arg), ec);
+}
+
 inline int poll_read(int d, boost::system::error_code& ec)
 {
   clear_error(ec);
Modified: trunk/boost/asio/detail/reactive_descriptor_service.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_descriptor_service.hpp	(original)
+++ trunk/boost/asio/detail/reactive_descriptor_service.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -177,7 +177,7 @@
   }
 
   // Get the native descriptor representation.
-  native_type native(implementation_type& impl)
+  native_type native(const implementation_type& impl) const
   {
     return impl.descriptor_;
   }
Added: trunk/boost/asio/detail/reactive_serial_port_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactive_serial_port_service.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,260 @@
+//
+// reactive_serial_port_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+#ifndef BOOST_ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <cstring>
+#include <string>
+#include <boost/asio/detail/pop_options.hpp>
+
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#include <boost/asio/detail/push_options.hpp>
+#include <termios.h>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/descriptor_ops.hpp>
+#include <boost/asio/detail/reactive_descriptor_service.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Extend reactive_descriptor_service to provide serial port support.
+template <typename Reactor>
+class reactive_serial_port_service
+  : public boost::asio::detail::service_base<
+      reactive_serial_port_service<Reactor> >
+{
+public:
+  // The native type of a stream handle.
+  typedef typename reactive_descriptor_service<Reactor>::native_type
+    native_type;
+
+  // The implementation type of the stream handle.
+  typedef typename reactive_descriptor_service<Reactor>::implementation_type
+    implementation_type;
+
+  reactive_serial_port_service(boost::asio::io_service& io_service)
+    : boost::asio::detail::service_base<
+        reactive_serial_port_service>(io_service),
+      descriptor_service_(boost::asio::use_service<
+          reactive_descriptor_service<Reactor> >(io_service))
+  {
+  }
+
+  // Destroy all user-defined handler objects owned by the service.
+  void shutdown_service()
+  {
+  }
+
+  // Construct a new handle implementation.
+  void construct(implementation_type& impl)
+  {
+    descriptor_service_.construct(impl);
+  }
+
+  // Destroy a handle implementation.
+  void destroy(implementation_type& impl)
+  {
+    descriptor_service_.destroy(impl);
+  }
+
+  // Open the serial port using the specified device name.
+  boost::system::error_code open(implementation_type& impl,
+      const std::string& device, boost::system::error_code& ec)
+  {
+    if (is_open(impl))
+    {
+      ec = boost::asio::error::already_open;
+      return ec;
+    }
+
+    int fd = descriptor_ops::open(device.c_str(),
+        O_RDWR | O_NONBLOCK | O_NOCTTY, ec);
+    if (fd < 0)
+      return ec;
+
+    int s = descriptor_ops::fcntl(fd, F_GETFL, ec);
+    if (s >= 0)
+      s = descriptor_ops::fcntl(fd, F_SETFL, s | O_NONBLOCK, ec);
+    if (s < 0)
+    {
+      boost::system::error_code ignored_ec;
+      descriptor_ops::close(fd, ignored_ec);
+      return ec;
+    }
+  
+    // Set up default serial port options.
+    termios ios;
+    descriptor_ops::clear_error(ec);
+    s = descriptor_ops::error_wrapper(::tcgetattr(fd, &ios), ec);
+    if (s >= 0)
+    {
+      ::cfmakeraw(&ios);
+      ios.c_iflag |= IGNPAR;
+      descriptor_ops::clear_error(ec);
+      s = descriptor_ops::error_wrapper(::tcsetattr(fd, TCSANOW, &ios), ec);
+    }
+    if (s < 0)
+    {
+      boost::system::error_code ignored_ec;
+      descriptor_ops::close(fd, ignored_ec);
+      return ec;
+    }
+  
+    // We're done. Take ownership of the serial port descriptor.
+    if (descriptor_service_.assign(impl, fd, ec))
+    {
+      boost::system::error_code ignored_ec;
+      descriptor_ops::close(fd, ignored_ec);
+    }
+
+    return ec;
+  }
+
+  // Assign a native handle to a handle implementation.
+  boost::system::error_code assign(implementation_type& impl,
+      const native_type& native_descriptor, boost::system::error_code& ec)
+  {
+    return descriptor_service_.assign(impl, native_descriptor, ec);
+  }
+
+  // Determine whether the handle is open.
+  bool is_open(const implementation_type& impl) const
+  {
+    return descriptor_service_.is_open(impl);
+  }
+
+  // Destroy a handle implementation.
+  boost::system::error_code close(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return descriptor_service_.close(impl, ec);
+  }
+
+  // Get the native handle representation.
+  native_type native(implementation_type& impl)
+  {
+    return descriptor_service_.native(impl);
+  }
+
+  // Cancel all operations associated with the handle.
+  boost::system::error_code cancel(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return descriptor_service_.cancel(impl, ec);
+  }
+
+  // Set an option on the serial port.
+  template <typename SettableSerialPortOption>
+  boost::system::error_code set_option(implementation_type& impl,
+      const SettableSerialPortOption& option, boost::system::error_code& ec)
+  {
+    termios ios;
+    descriptor_ops::clear_error(ec);
+    descriptor_ops::error_wrapper(::tcgetattr(
+          descriptor_service_.native(impl), &ios), ec);
+    if (ec)
+      return ec;
+
+    if (option.store(ios, ec))
+      return ec;
+
+    descriptor_ops::clear_error(ec);
+    descriptor_ops::error_wrapper(::tcsetattr(
+          descriptor_service_.native(impl), TCSANOW, &ios), ec);
+    return ec;
+  }
+
+  // Get an option from the serial port.
+  template <typename GettableSerialPortOption>
+  boost::system::error_code get_option(const implementation_type& impl,
+      GettableSerialPortOption& option, boost::system::error_code& ec) const
+  {
+    termios ios;
+    descriptor_ops::clear_error(ec);
+    descriptor_ops::error_wrapper(::tcgetattr(
+          descriptor_service_.native(impl), &ios), ec);
+    if (ec)
+      return ec;
+
+    return option.load(ios, ec);
+  }
+
+  // Send a break sequence to the serial port.
+  boost::system::error_code send_break(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    descriptor_ops::clear_error(ec);
+    descriptor_ops::error_wrapper(::tcsendbreak(
+          descriptor_service_.native(impl), 0), ec);
+    return ec;
+  }
+
+  // Write the given data. Returns the number of bytes sent.
+  template <typename ConstBufferSequence>
+  size_t write_some(implementation_type& impl,
+      const ConstBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return descriptor_service_.write_some(impl, buffers, ec);
+  }
+
+  // Start an asynchronous write. The data being written must be valid for the
+  // lifetime of the asynchronous operation.
+  template <typename ConstBufferSequence, typename Handler>
+  void async_write_some(implementation_type& impl,
+      const ConstBufferSequence& buffers, Handler handler)
+  {
+    descriptor_service_.async_write_some(impl, buffers, handler);
+  }
+
+  // Read some data. Returns the number of bytes received.
+  template <typename MutableBufferSequence>
+  size_t read_some(implementation_type& impl,
+      const MutableBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return descriptor_service_.read_some(impl, buffers, ec);
+  }
+
+  // Start an asynchronous read. The buffer for the data being received must be
+  // valid for the lifetime of the asynchronous operation.
+  template <typename MutableBufferSequence, typename Handler>
+  void async_read_some(implementation_type& impl,
+      const MutableBufferSequence& buffers, Handler handler)
+  {
+    descriptor_service_.async_read_some(impl, buffers, handler);
+  }
+
+private:
+  // The handle service used for initiating asynchronous operations.
+  reactive_descriptor_service<Reactor>& descriptor_service_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP
Modified: trunk/boost/asio/detail/win_iocp_handle_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_handle_service.hpp	(original)
+++ trunk/boost/asio/detail/win_iocp_handle_service.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -155,7 +155,7 @@
 
   // Destroy a handle implementation.
   boost::system::error_code close(implementation_type& impl,
-                                  boost::system::error_code& ec)
+      boost::system::error_code& ec)
   {
     if (is_open(impl))
     {
@@ -176,7 +176,7 @@
   }
 
   // Get the native handle representation.
-  native_type native(implementation_type& impl)
+  native_type native(const implementation_type& impl) const
   {
     return impl.handle_;
   }
Added: trunk/boost/asio/detail/win_iocp_serial_port_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_serial_port_service.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,294 @@
+//
+// win_iocp_serial_port_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+#ifndef BOOST_ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <cstring>
+#include <string>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/win_iocp_handle_service.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Extend win_iocp_handle_service to provide serial port support.
+class win_iocp_serial_port_service
+  : public boost::asio::detail::service_base<win_iocp_serial_port_service>
+{
+public:
+  // The native type of a stream handle.
+  typedef win_iocp_handle_service::native_type native_type;
+
+  // The implementation type of the stream handle.
+  typedef win_iocp_handle_service::implementation_type implementation_type;
+
+  win_iocp_serial_port_service(boost::asio::io_service& io_service)
+    : boost::asio::detail::service_base<
+        win_iocp_serial_port_service>(io_service),
+      handle_service_(
+          boost::asio::use_service<win_iocp_handle_service>(io_service))
+  {
+  }
+
+  // Destroy all user-defined handler objects owned by the service.
+  void shutdown_service()
+  {
+  }
+
+  // Construct a new handle implementation.
+  void construct(implementation_type& impl)
+  {
+    handle_service_.construct(impl);
+  }
+
+  // Destroy a handle implementation.
+  void destroy(implementation_type& impl)
+  {
+    handle_service_.destroy(impl);
+  }
+
+  // Open the serial port using the specified device name.
+  boost::system::error_code open(implementation_type& impl,
+      const std::string& device, boost::system::error_code& ec)
+  {
+    if (is_open(impl))
+    {
+      ec = boost::asio::error::already_open;
+      return ec;
+    }
+
+    // For convenience, add a leading \\.\ sequence if not already present.
+    std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device;
+
+    // Open a handle to the serial port.
+    ::HANDLE handle = ::CreateFile(name.c_str(),
+        GENERIC_READ | GENERIC_WRITE, 0, 0,
+        OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+    if (handle == INVALID_HANDLE_VALUE)
+    {
+      DWORD last_error = ::GetLastError();
+      ec = boost::system::error_code(last_error,
+          boost::asio::error::get_system_category());
+      return ec;
+    }
+
+    // Determine the initial serial port parameters.
+    using namespace std; // For memcpy.
+    ::DCB dcb;
+    memset(&dcb, 0, sizeof(DCB));
+    dcb.DCBlength = sizeof(DCB);
+    if (!::GetCommState(handle, &dcb))
+    {
+      DWORD last_error = ::GetLastError();
+      ::CloseHandle(handle);
+      ec = boost::system::error_code(last_error,
+          boost::asio::error::get_system_category());
+      return ec;
+    }
+
+    // Set some default serial port parameters. This implementation does not
+    // support changing these, so they might as well be in a known state.
+    dcb.fBinary = TRUE; // Win32 only supports binary mode.
+    dcb.fDsrSensitivity = FALSE;
+    dcb.fNull = FALSE; // Do not ignore NULL characters.
+    dcb.fAbortOnError = FALSE; // Ignore serial framing errors.
+    if (!::SetCommState(handle, &dcb))
+    {
+      DWORD last_error = ::GetLastError();
+      ::CloseHandle(handle);
+      ec = boost::system::error_code(last_error,
+          boost::asio::error::get_system_category());
+      return ec;
+    }
+
+    // Set up timeouts so that the serial port will behave similarly to a
+    // network socket. Reads wait for at least one byte, then return with
+    // whatever they have. Writes return once everything is out the door.
+    ::COMMTIMEOUTS timeouts;
+    timeouts.ReadIntervalTimeout = 1;
+    timeouts.ReadTotalTimeoutMultiplier = 0;
+    timeouts.ReadTotalTimeoutConstant = 0;
+    timeouts.WriteTotalTimeoutMultiplier = 0;
+    timeouts.WriteTotalTimeoutConstant = 0;
+    if (!::SetCommTimeouts(handle, &timeouts))
+    {
+      DWORD last_error = ::GetLastError();
+      ::CloseHandle(handle);
+      ec = boost::system::error_code(last_error,
+          boost::asio::error::get_system_category());
+      return ec;
+    }
+
+    // We're done. Take ownership of the serial port handle.
+    if (handle_service_.assign(impl, handle, ec))
+      ::CloseHandle(handle);
+    return ec;
+  }
+
+  // Assign a native handle to a handle implementation.
+  boost::system::error_code assign(implementation_type& impl,
+      const native_type& native_handle, boost::system::error_code& ec)
+  {
+    return handle_service_.assign(impl, native_handle, ec);
+  }
+
+  // Determine whether the handle is open.
+  bool is_open(const implementation_type& impl) const
+  {
+    return handle_service_.is_open(impl);
+  }
+
+  // Destroy a handle implementation.
+  boost::system::error_code close(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return handle_service_.close(impl, ec);
+  }
+
+  // Get the native handle representation.
+  native_type native(implementation_type& impl)
+  {
+    return handle_service_.native(impl);
+  }
+
+  // Cancel all operations associated with the handle.
+  boost::system::error_code cancel(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return handle_service_.cancel(impl, ec);
+  }
+
+  // Set an option on the serial port.
+  template <typename SettableSerialPortOption>
+  boost::system::error_code set_option(implementation_type& impl,
+      const SettableSerialPortOption& option, boost::system::error_code& ec)
+  {
+    using namespace std; // For memcpy.
+
+    ::DCB dcb;
+    memset(&dcb, 0, sizeof(DCB));
+    dcb.DCBlength = sizeof(DCB);
+    if (!::GetCommState(handle_service_.native(impl), &dcb))
+    {
+      DWORD last_error = ::GetLastError();
+      ec = boost::system::error_code(last_error,
+          boost::asio::error::get_system_category());
+      return ec;
+    }
+
+    if (option.store(dcb, ec))
+      return ec;
+
+    if (!::SetCommState(handle_service_.native(impl), &dcb))
+    {
+      DWORD last_error = ::GetLastError();
+      ec = boost::system::error_code(last_error,
+          boost::asio::error::get_system_category());
+      return ec;
+    }
+
+    ec = boost::system::error_code();
+    return ec;
+  }
+
+  // Get an option from the serial port.
+  template <typename GettableSerialPortOption>
+  boost::system::error_code get_option(const implementation_type& impl,
+      GettableSerialPortOption& option, boost::system::error_code& ec) const
+  {
+    using namespace std; // For memcpy.
+
+    ::DCB dcb;
+    memset(&dcb, 0, sizeof(DCB));
+    dcb.DCBlength = sizeof(DCB);
+    if (!::GetCommState(handle_service_.native(impl), &dcb))
+    {
+      DWORD last_error = ::GetLastError();
+      ec = boost::system::error_code(last_error,
+          boost::asio::error::get_system_category());
+      return ec;
+    }
+
+    return option.load(dcb, ec);
+  }
+
+  // Send a break sequence to the serial port.
+  boost::system::error_code send_break(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    ec = boost::asio::error::operation_not_supported;
+    return ec;
+  }
+
+  // Write the given data. Returns the number of bytes sent.
+  template <typename ConstBufferSequence>
+  size_t write_some(implementation_type& impl,
+      const ConstBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return handle_service_.write_some(impl, buffers, ec);
+  }
+
+  // Start an asynchronous write. The data being written must be valid for the
+  // lifetime of the asynchronous operation.
+  template <typename ConstBufferSequence, typename Handler>
+  void async_write_some(implementation_type& impl,
+      const ConstBufferSequence& buffers, Handler handler)
+  {
+    handle_service_.async_write_some(impl, buffers, handler);
+  }
+
+  // Read some data. Returns the number of bytes received.
+  template <typename MutableBufferSequence>
+  size_t read_some(implementation_type& impl,
+      const MutableBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return handle_service_.read_some(impl, buffers, ec);
+  }
+
+  // Start an asynchronous read. The buffer for the data being received must be
+  // valid for the lifetime of the asynchronous operation.
+  template <typename MutableBufferSequence, typename Handler>
+  void async_read_some(implementation_type& impl,
+      const MutableBufferSequence& buffers, Handler handler)
+  {
+    handle_service_.async_read_some(impl, buffers, handler);
+  }
+
+private:
+  // The handle service used for initiating asynchronous operations.
+  win_iocp_handle_service& handle_service_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP
Added: trunk/boost/asio/impl/serial_port_base.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/serial_port_base.ipp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,527 @@
+//
+// serial_port_base.ipp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+#ifndef BOOST_ASIO_SERIAL_PORT_BASE_IPP
+#define BOOST_ASIO_SERIAL_PORT_BASE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+inline serial_port_base::baud_rate::baud_rate(unsigned int rate)
+  : value_(rate)
+{
+}
+
+inline unsigned int serial_port_base::baud_rate::value() const
+{
+  return value_;
+}
+
+inline boost::system::error_code serial_port_base::baud_rate::store(
+    BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  storage.BaudRate = value_;
+#else
+  speed_t baud;
+  switch (value_)
+  {
+  // Do POSIX-specified rates first.
+  case 0: baud = B0; break;
+  case 50: baud = B50; break;
+  case 75: baud = B75; break;
+  case 110: baud = B110; break;
+  case 134: baud = B134; break;
+  case 150: baud = B150; break;
+  case 200: baud = B200; break;
+  case 300: baud = B300; break;
+  case 600: baud = B600; break;
+  case 1200: baud = B1200; break;
+  case 1800: baud = B1800; break;
+  case 2400: baud = B2400; break;
+  case 4800: baud = B4800; break;
+  case 9600: baud = B9600; break;
+  case 19200: baud = B19200; break;
+  case 38400: baud = B38400; break;
+  // And now the extended ones conditionally.
+# ifdef B7200
+  case 7200: baud = B7200; break;
+# endif
+# ifdef B14400
+  case 14400: baud = B14400; break;
+# endif
+# ifdef B57600
+  case 57600: baud = B57600; break;
+# endif
+# ifdef B115200
+  case 115200: baud = B115200; break;
+# endif
+# ifdef B230400
+  case 230400: baud = B230400; break;
+# endif
+# ifdef B460800
+  case 460800: baud = B460800; break;
+# endif
+# ifdef B500000
+  case 500000: baud = B500000; break;
+# endif
+# ifdef B576000
+  case 576000: baud = B576000; break;
+# endif
+# ifdef B921600
+  case 921600: baud = B921600; break;
+# endif
+# ifdef B1000000
+  case 1000000: baud = B1000000; break;
+# endif
+# ifdef B1152000
+  case 1152000: baud = B1152000; break;
+# endif
+# ifdef B2000000
+  case 2000000: baud = B2000000; break;
+# endif
+# ifdef B3000000
+  case 3000000: baud = B3000000; break;
+# endif
+# ifdef B3500000
+  case 3500000: baud = B3500000; break;
+# endif
+# ifdef B4000000
+  case 4000000: baud = B4000000; break;
+# endif
+  default:
+    baud = B0;
+    ec = boost::asio::error::invalid_argument;
+    return ec;
+  }
+  ::cfsetspeed(&storage, baud);
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+inline boost::system::error_code serial_port_base::baud_rate::load(
+    const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  value_ = storage.BaudRate;
+#else
+  speed_t baud = ::cfgetospeed(&storage);
+  switch (baud)
+  {
+  // First do those specified by POSIX.
+  case B0: value_ = 0; break;
+  case B50: value_ = 50; break;
+  case B75: value_ = 75; break;
+  case B110: value_ = 110; break;
+  case B134: value_ = 134; break;
+  case B150: value_ = 150; break;
+  case B200: value_ = 200; break;
+  case B300: value_ = 300; break;
+  case B600: value_ = 600; break;
+  case B1200: value_ = 1200; break;
+  case B1800: value_ = 1800; break;
+  case B2400: value_ = 2400; break;
+  case B4800: value_ = 4800; break;
+  case B9600: value_ = 9600; break;
+  case B19200: value_ = 19200; break;
+  case B38400: value_ = 38400; break;
+  // Now conditionally handle a bunch of extended rates.
+# ifdef B7200
+  case B7200: value_ = 7200; break;
+# endif
+# ifdef B14400
+  case B14400: value_ = 14400; break;
+# endif
+# ifdef B57600
+  case B57600: value_ = 57600; break;
+# endif
+# ifdef B115200
+  case B115200: value_ = 115200; break;
+# endif
+# ifdef B230400
+  case B230400: value_ = 230400; break;
+# endif
+# ifdef B460800
+  case B460800: value_ = 460800; break;
+# endif
+# ifdef B500000
+  case B500000: value_ = 500000; break;
+# endif
+# ifdef B576000
+  case B576000: value_ = 576000; break;
+# endif
+# ifdef B921600
+  case B921600: value_ = 921600; break;
+# endif
+# ifdef B1000000
+  case B1000000: value_ = 1000000; break;
+# endif
+# ifdef B1152000
+  case B1152000: value_ = 1152000; break;
+# endif
+# ifdef B2000000
+  case B2000000: value_ = 2000000; break;
+# endif
+# ifdef B3000000
+  case B3000000: value_ = 3000000; break;
+# endif
+# ifdef B3500000
+  case B3500000: value_ = 3500000; break;
+# endif
+# ifdef B4000000
+  case B4000000: value_ = 4000000; break;
+# endif
+  default:
+    value_ = 0;
+    ec = boost::asio::error::invalid_argument;
+    return ec;
+  }
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+inline serial_port_base::flow_control::flow_control(
+    serial_port_base::flow_control::type t)
+  : value_(t)
+{
+  if (t != none && t != software && t != hardware)
+    throw std::out_of_range("invalid flow_control value");
+}
+
+inline serial_port_base::flow_control::type
+serial_port_base::flow_control::value() const
+{
+  return value_;
+}
+
+inline boost::system::error_code serial_port_base::flow_control::store(
+    BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  storage.fOutxCtsFlow = FALSE;
+  storage.fOutxDsrFlow = FALSE;
+  storage.fTXContinueOnXoff = TRUE;
+  storage.fDtrControl = DTR_CONTROL_ENABLE;
+  storage.fDsrSensitivity = FALSE;
+  storage.fOutX = FALSE;
+  storage.fInX = FALSE;
+  storage.fRtsControl = RTS_CONTROL_ENABLE;
+  switch (value_)
+  {
+  case none:
+    break;
+  case software:
+    storage.fOutX = TRUE;
+    storage.fInX = TRUE;
+    break;
+  case hardware:
+    storage.fOutxCtsFlow = TRUE;
+    storage.fRtsControl = RTS_CONTROL_HANDSHAKE;
+    break;
+  default:
+    break;
+  }
+#else
+  switch (value_)
+  {
+  case none:
+    storage.c_iflag &= ~(IXOFF | IXON);
+    storage.c_cflag &= ~CRTSCTS;
+    break;
+  case software:
+    storage.c_iflag |= IXOFF | IXON;
+    storage.c_cflag &= ~CRTSCTS;
+    break;
+  case hardware:
+    storage.c_iflag &= ~(IXOFF | IXON);
+    storage.c_cflag |= CRTSCTS;
+    break;
+  default:
+    break;
+  }
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+inline boost::system::error_code serial_port_base::flow_control::load(
+    const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  if (storage.fOutX && storage.fInX)
+  {
+    value_ = software;
+  }
+  else if (storage.fOutxCtsFlow && storage.fRtsControl == RTS_CONTROL_HANDSHAKE)
+  {
+    value_ = hardware;
+  }
+  else
+  {
+    value_ = none;
+  }
+#else
+  if (storage.c_iflag & (IXOFF | IXON))
+  {
+    value_ = software;
+  }
+  else if (storage.c_cflag & CRTSCTS)
+  {
+    value_ = hardware;
+  }
+  else
+  {
+    value_ = none;
+  }
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+inline serial_port_base::parity::parity(serial_port_base::parity::type t)
+  : value_(t)
+{
+  if (t != none && t != odd && t != even)
+    throw std::out_of_range("invalid parity value");
+}
+
+inline serial_port_base::parity::type serial_port_base::parity::value() const
+{
+  return value_;
+}
+
+inline boost::system::error_code serial_port_base::parity::store(
+    BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  switch (value_)
+  {
+  case none:
+    storage.fParity = FALSE;
+    storage.Parity = NOPARITY;
+    break;
+  case odd:
+    storage.fParity = TRUE;
+    storage.Parity = ODDPARITY;
+    break;
+  case even:
+    storage.fParity = TRUE;
+    storage.Parity = EVENPARITY;
+    break;
+  default:
+    break;
+  }
+#else
+  switch (value_)
+  {
+  case none:
+    storage.c_iflag |= IGNPAR;
+    storage.c_cflag &= ~(PARENB | PARODD);
+    break;
+  case even:
+    storage.c_iflag &= ~(IGNPAR | PARMRK);
+    storage.c_iflag |= INPCK;
+    storage.c_cflag |= PARENB;
+    storage.c_cflag &= ~PARODD;
+    break;
+  case odd:
+    storage.c_iflag &= ~(IGNPAR | PARMRK);
+    storage.c_iflag |= INPCK;
+    storage.c_cflag |= (PARENB | PARODD);
+    break;
+  default:
+    break;
+  }
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+inline boost::system::error_code serial_port_base::parity::load(
+    const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  if (storage.Parity == EVENPARITY)
+  {
+    value_ = even;
+  }
+  else if (storage.Parity == ODDPARITY)
+  {
+    value_ = odd;
+  }
+  else
+  {
+    value_ = none;
+  }
+#else
+  if (storage.c_cflag & PARENB)
+  {
+    if (storage.c_cflag & PARODD)
+    {
+      value_ = odd;
+    }
+    else
+    {
+      value_ = even;
+    }
+  }
+  else
+  {
+    value_ = none;
+  }
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+inline serial_port_base::stop_bits::stop_bits(
+    serial_port_base::stop_bits::type t)
+  : value_(t)
+{
+  if (t != one && t != onepointfive && t != two)
+    throw std::out_of_range("invalid stop_bits value");
+}
+
+inline serial_port_base::stop_bits::type
+serial_port_base::stop_bits::value() const
+{
+  return value_;
+}
+
+inline boost::system::error_code serial_port_base::stop_bits::store(
+    BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  switch (value_)
+  {
+  case one:
+    storage.StopBits = ONESTOPBIT;
+    break;
+  case onepointfive:
+    storage.StopBits = ONE5STOPBITS;
+    break;
+  case two:
+    storage.StopBits = TWOSTOPBITS;
+    break;
+  default:
+    break;
+  }
+#else
+  switch (value_)
+  {
+  case one:
+    storage.c_cflag &= ~CSTOPB;
+    break;
+  case two:
+    storage.c_cflag |= CSTOPB;
+    break;
+  default:
+    ec = boost::asio::error::operation_not_supported;
+    return ec;
+  }
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+inline boost::system::error_code serial_port_base::stop_bits::load(
+    const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  if (storage.StopBits == ONESTOPBIT)
+  {
+    value_ = one;
+  }
+  else if (storage.StopBits == ONE5STOPBITS)
+  {
+    value_ = onepointfive;
+  }
+  else if (storage.StopBits == TWOSTOPBITS)
+  {
+    value_ = two;
+  }
+  else
+  {
+    value_ = one;
+  }
+#else
+  value_ = (storage.c_cflag & CSTOPB) ? two : one;
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+inline serial_port_base::character_size::character_size(unsigned int t)
+  : value_(t)
+{
+  if (t < 5 || t > 8)
+    throw std::out_of_range("invalid character_size value");
+}
+
+inline unsigned int serial_port_base::character_size::value() const
+{
+  return value_;
+}
+
+inline boost::system::error_code serial_port_base::character_size::store(
+    BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  storage.ByteSize = value_;
+#else
+  storage.c_cflag &= ~CSIZE;
+  switch (value_)
+  {
+  case 5: storage.c_cflag |= CS5; break;
+  case 6: storage.c_cflag |= CS6; break;
+  case 7: storage.c_cflag |= CS7; break;
+  case 8: storage.c_cflag |= CS8; break;
+  default: break;
+  }
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+inline boost::system::error_code serial_port_base::character_size::load(
+    const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  value_ = storage.ByteSize;
+#else
+  if ((storage.c_cflag & CSIZE) == CS5) { value_ = 5; }
+  else if ((storage.c_cflag & CSIZE) == CS6) { value_ = 6; }
+  else if ((storage.c_cflag & CSIZE) == CS7) { value_ = 7; }
+  else if ((storage.c_cflag & CSIZE) == CS8) { value_ = 8; }
+  else
+  {
+    // Hmmm, use 8 for now.
+    value_ = 8;
+  }
+#endif
+  ec = boost::system::error_code();
+  return ec;
+}
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SERIAL_PORT_BASE_IPP
Added: trunk/boost/asio/serial_port.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/serial_port.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,40 @@
+//
+// serial_port.hpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+#ifndef BOOST_ASIO_SERIAL_PORT_HPP
+#define BOOST_ASIO_SERIAL_PORT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/basic_serial_port.hpp>
+
+#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
+  || defined(GENERATING_DOCUMENTATION)
+
+namespace boost {
+namespace asio {
+
+/// Typedef for the typical usage of a serial port.
+typedef basic_serial_port<> serial_port;
+
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
+       //   || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SERIAL_PORT_HPP
Added: trunk/boost/asio/serial_port_base.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/serial_port_base.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,159 @@
+//
+// serial_port_base.hpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+#ifndef BOOST_ASIO_SERIAL_PORT_BASE_HPP
+#define BOOST_ASIO_SERIAL_PORT_BASE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <stdexcept>
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+# include <termios.h>
+#endif
+#include <boost/system/error_code.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/socket_types.hpp>
+
+#if defined(GENERATING_DOCUMENTATION)
+# define BOOST_ASIO_OPTION_STORAGE implementation_defined
+#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# define BOOST_ASIO_OPTION_STORAGE DCB
+#else
+# define BOOST_ASIO_OPTION_STORAGE termios
+#endif
+
+namespace boost {
+namespace asio {
+
+/// The serial_port_base class is used as a base for the basic_serial_port class
+/// template so that we have a common place to define the serial port options.
+class serial_port_base
+{
+public:
+  /// Serial port option to permit changing the baud rate.
+  /**
+   * Implements changing the baud rate for a given serial port.
+   */
+  class baud_rate
+  {
+  public:
+    explicit baud_rate(unsigned int rate = 0);
+    unsigned int value() const;
+    boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec) const;
+    boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec);
+  private:
+    unsigned int value_;
+  };
+
+  /// Serial port option to permit changing the flow control.
+  /**
+   * Implements changing the flow control for a given serial port.
+   */
+  class flow_control
+  {
+  public:
+    enum type { none, software, hardware };
+    explicit flow_control(type t = none);
+    type value() const;
+    boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec) const;
+    boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec);
+  private:
+    type value_;
+  };
+
+  /// Serial port option to permit changing the parity.
+  /**
+   * Implements changing the parity for a given serial port.
+   */
+  class parity
+  {
+  public:
+    enum type { none, odd, even };
+    explicit parity(type t = none);
+    type value() const;
+    boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec) const;
+    boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec);
+  private:
+    type value_;
+  };
+
+  /// Serial port option to permit changing the number of stop bits.
+  /**
+   * Implements changing the number of stop bits for a given serial port.
+   */
+  class stop_bits
+  {
+  public:
+    enum type { one, onepointfive, two };
+    explicit stop_bits(type t = one);
+    type value() const;
+    boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec) const;
+    boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec);
+  private:
+    type value_;
+  };
+
+  /// Serial port option to permit changing the character size.
+  /**
+   * Implements changing the character size for a given serial port.
+   */
+  class character_size
+  {
+  public:
+    explicit character_size(unsigned int t = 8);
+    unsigned int value() const;
+    boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec) const;
+    boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+        boost::system::error_code& ec);
+  private:
+    unsigned int value_;
+  };
+
+protected:
+  /// Protected destructor to prevent deletion through this type.
+  ~serial_port_base()
+  {
+  }
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+private:
+  // Workaround to enable the empty base optimisation with Borland C++.
+  char dummy_;
+#endif
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/impl/serial_port_base.ipp>
+
+#undef BOOST_ASIO_OPTION_STORAGE
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SERIAL_PORT_BASE_HPP
Added: trunk/boost/asio/serial_port_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/serial_port_service.hpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,224 @@
+//
+// serial_port_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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)
+//
+
+#ifndef BOOST_ASIO_SERIAL_PORT_SERVICE_HPP
+#define BOOST_ASIO_SERIAL_PORT_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <cstddef>
+#include <boost/config.hpp>
+#include <string>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/service_base.hpp>
+#include <boost/asio/detail/reactive_serial_port_service.hpp>
+#include <boost/asio/detail/win_iocp_serial_port_service.hpp>
+
+#if !defined(BOOST_ASIO_DISABLE_SERIAL_PORT)
+# if defined(BOOST_ASIO_HAS_IOCP) \
+    || !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#  define BOOST_ASIO_HAS_SERIAL_PORT 1
+# endif // defined(BOOST_ASIO_HAS_IOCP)
+#endif // !defined(BOOST_ASIO_DISABLE_STREAM_HANDLE)
+
+#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
+  || defined(GENERATING_DOCUMENTATION)
+
+namespace boost {
+namespace asio {
+
+/// Default service implementation for a serial port.
+class serial_port_service
+#if defined(GENERATING_DOCUMENTATION)
+  : public boost::asio::io_service::service
+#else
+  : public boost::asio::detail::service_base<serial_port_service>
+#endif
+{
+public:
+#if defined(GENERATING_DOCUMENTATION)
+  /// The unique service identifier.
+  static boost::asio::io_service::id id;
+#endif
+
+private:
+  // The type of the platform-specific implementation.
+#if defined(BOOST_ASIO_HAS_IOCP)
+  typedef detail::win_iocp_serial_port_service service_impl_type;
+#elif defined(BOOST_ASIO_HAS_EPOLL)
+  typedef detail::reactive_serial_port_service<
+      detail::epoll_reactor<false> > service_impl_type;
+#elif defined(BOOST_ASIO_HAS_KQUEUE)
+  typedef detail::reactive_serial_port_service<
+      detail::kqueue_reactor<false> > service_impl_type;
+#elif defined(BOOST_ASIO_HAS_DEV_POLL)
+  typedef detail::reactive_serial_port_service<
+      detail::dev_poll_reactor<false> > service_impl_type;
+#else
+  typedef detail::reactive_serial_port_service<
+      detail::select_reactor<false> > service_impl_type;
+#endif
+
+public:
+  /// The type of a serial port implementation.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined implementation_type;
+#else
+  typedef service_impl_type::implementation_type implementation_type;
+#endif
+
+  /// The native handle type.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_type;
+#else
+  typedef service_impl_type::native_type native_type;
+#endif
+
+  /// Construct a new serial port service for the specified io_service.
+  explicit serial_port_service(boost::asio::io_service& io_service)
+    : boost::asio::detail::service_base<serial_port_service>(io_service),
+      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+  {
+  }
+
+  /// Destroy all user-defined handler objects owned by the service.
+  void shutdown_service()
+  {
+  }
+
+  /// Construct a new serial port implementation.
+  void construct(implementation_type& impl)
+  {
+    service_impl_.construct(impl);
+  }
+
+  /// Destroy a serial port implementation.
+  void destroy(implementation_type& impl)
+  {
+    service_impl_.destroy(impl);
+  }
+
+  /// Open a serial port.
+  boost::system::error_code open(implementation_type& impl,
+      const std::string& device, boost::system::error_code& ec)
+  {
+    return service_impl_.open(impl, device, ec);
+  }
+
+  /// Assign an existing native handle to a serial port.
+  boost::system::error_code assign(implementation_type& impl,
+      const native_type& native_handle, boost::system::error_code& ec)
+  {
+    return service_impl_.assign(impl, native_handle, ec);
+  }
+
+  /// Determine whether the handle is open.
+  bool is_open(const implementation_type& impl) const
+  {
+    return service_impl_.is_open(impl);
+  }
+
+  /// Close a serial port implementation.
+  boost::system::error_code close(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return service_impl_.close(impl, ec);
+  }
+
+  /// Get the native handle implementation.
+  native_type native(implementation_type& impl)
+  {
+    return service_impl_.native(impl);
+  }
+
+  /// Cancel all asynchronous operations associated with the handle.
+  boost::system::error_code cancel(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return service_impl_.cancel(impl, ec);
+  }
+
+  /// Set a serial port option.
+  template <typename SettableSerialPortOption>
+  boost::system::error_code set_option(implementation_type& impl,
+      const SettableSerialPortOption& option, boost::system::error_code& ec)
+  {
+    return service_impl_.set_option(impl, option, ec);
+  }
+
+  /// Get a serial port option.
+  template <typename GettableSerialPortOption>
+  boost::system::error_code get_option(const implementation_type& impl,
+      GettableSerialPortOption& option, boost::system::error_code& ec) const
+  {
+    return service_impl_.get_option(impl, option, ec);
+  }
+
+  /// Send a break sequence to the serial port.
+  boost::system::error_code send_break(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return service_impl_.send_break(impl, ec);
+  }
+
+  /// Write the given data to the stream.
+  template <typename ConstBufferSequence>
+  std::size_t write_some(implementation_type& impl,
+      const ConstBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return service_impl_.write_some(impl, buffers, ec);
+  }
+
+  /// Start an asynchronous write.
+  template <typename ConstBufferSequence, typename WriteHandler>
+  void async_write_some(implementation_type& impl,
+      const ConstBufferSequence& buffers, WriteHandler handler)
+  {
+    service_impl_.async_write_some(impl, buffers, handler);
+  }
+
+  /// Read some data from the stream.
+  template <typename MutableBufferSequence>
+  std::size_t read_some(implementation_type& impl,
+      const MutableBufferSequence& buffers, boost::system::error_code& ec)
+  {
+    return service_impl_.read_some(impl, buffers, ec);
+  }
+
+  /// Start an asynchronous read.
+  template <typename MutableBufferSequence, typename ReadHandler>
+  void async_read_some(implementation_type& impl,
+      const MutableBufferSequence& buffers, ReadHandler handler)
+  {
+    service_impl_.async_read_some(impl, buffers, handler);
+  }
+
+private:
+  // The service that provides the platform-specific implementation.
+  service_impl_type& service_impl_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
+       //   || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_SERIAL_PORT_SERVICE_HPP
Added: trunk/libs/asio/test/basic_serial_port.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/test/basic_serial_port.cpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,27 @@
+//
+// basic_serial_port.cpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include <boost/asio/basic_serial_port.hpp>
+
+#include "unit_test.hpp"
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+  test_suite* test = BOOST_TEST_SUITE("basic_serial_port");
+  test->add(BOOST_TEST_CASE(&null_test));
+  return test;
+}
Added: trunk/libs/asio/test/serial_port.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/test/serial_port.cpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,125 @@
+//
+// serial_port.cpp
+// ~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include <boost/asio/serial_port.hpp>
+
+#include <boost/asio.hpp>
+#include "unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// serial_port_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// serial_port compile and link correctly. Runtime failures are ignored.
+
+namespace serial_port_compile {
+
+void write_some_handler(const boost::system::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const boost::system::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+  using namespace boost::asio;
+
+  try
+  {
+    io_service ios;
+    char mutable_char_buffer[128] = "";
+    const char const_char_buffer[128] = "";
+    serial_port::baud_rate serial_port_option;
+    boost::system::error_code ec;
+
+    // basic_serial_port constructors.
+
+    serial_port port1(ios);
+    serial_port port2(ios, "null");
+    serial_port::native_type native_port1 = port1.native();
+    serial_port port3(ios, native_port1);
+
+    // basic_io_object functions.
+
+    io_service& ios_ref = port1.io_service();
+    (void)ios_ref;
+
+    // basic_serial_port functions.
+
+    serial_port::lowest_layer_type& lowest_layer = port1.lowest_layer();
+    (void)lowest_layer;
+
+    port1.open("null");
+    port1.open("null", ec);
+
+    serial_port::native_type native_port2 = port1.native();
+    port1.assign(native_port2);
+    serial_port::native_type native_port3 = port1.native();
+    port1.assign(native_port3, ec);
+
+    bool is_open = port1.is_open();
+    (void)is_open;
+
+    port1.close();
+    port1.close(ec);
+
+    serial_port::native_type native_port4 = port1.native();
+    (void)native_port4;
+
+    port1.cancel();
+    port1.cancel(ec);
+
+    port1.set_option(serial_port_option);
+    port1.set_option(serial_port_option, ec);
+
+    port1.get_option(serial_port_option);
+    port1.get_option(serial_port_option, ec);
+
+    port1.send_break();
+    port1.send_break(ec);
+
+    port1.write_some(buffer(mutable_char_buffer));
+    port1.write_some(buffer(const_char_buffer));
+    port1.write_some(buffer(mutable_char_buffer), ec);
+    port1.write_some(buffer(const_char_buffer), ec);
+
+    port1.async_write_some(buffer(mutable_char_buffer), write_some_handler);
+    port1.async_write_some(buffer(const_char_buffer), write_some_handler);
+
+    port1.read_some(buffer(mutable_char_buffer));
+    port1.read_some(buffer(mutable_char_buffer), ec);
+
+    port1.async_read_some(buffer(mutable_char_buffer), read_some_handler);
+  }
+  catch (std::exception&)
+  {
+  }
+}
+
+} // namespace serial_port_compile
+
+//------------------------------------------------------------------------------
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+  test_suite* test = BOOST_TEST_SUITE("serial_port");
+  test->add(BOOST_TEST_CASE(&serial_port_compile::test));
+  return test;
+}
Added: trunk/libs/asio/test/serial_port_base.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/test/serial_port_base.cpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,96 @@
+//
+// serial_port_base.cpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include <boost/asio/serial_port_base.hpp>
+
+#include <boost/asio.hpp>
+#include "unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// serial_port_base_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Verify that all options and and their accessors compile. Runtime failures are
+// ignored.
+
+namespace serial_port_base_compile {
+
+void test()
+{
+  using namespace boost::asio;
+
+  try
+  {
+    io_service ios;
+    serial_port port(ios);
+
+    // baud_rate class.
+
+    serial_port_base::baud_rate baud_rate1(9600);
+    port.set_option(baud_rate1);
+    serial_port_base::baud_rate baud_rate2;
+    port.get_option(baud_rate2);
+    static_cast<unsigned int>(baud_rate2.value());
+
+    // flow_control class.
+
+    serial_port_base::flow_control flow_control1(
+      serial_port_base::flow_control::none);
+    port.set_option(flow_control1);
+    serial_port_base::flow_control flow_control2;
+    port.get_option(flow_control2);
+    static_cast<serial_port_base::flow_control::type>(flow_control2.value());
+
+    // parity class.
+
+    serial_port_base::parity parity1(serial_port_base::parity::none);
+    port.set_option(parity1);
+    serial_port_base::parity parity2;
+    port.get_option(parity2);
+    static_cast<serial_port_base::parity::type>(parity2.value());
+
+    // stop_bits class.
+
+    serial_port_base::stop_bits stop_bits1(serial_port_base::stop_bits::one);
+    port.set_option(stop_bits1);
+    serial_port_base::stop_bits stop_bits2;
+    port.get_option(stop_bits2);
+    static_cast<serial_port_base::stop_bits::type>(stop_bits2.value());
+
+    // character_size class.
+
+    serial_port_base::character_size character_size1(8);
+    port.set_option(character_size1);
+    serial_port_base::character_size character_size2;
+    port.get_option(character_size2);
+    static_cast<unsigned int>(character_size2.value());
+  }
+  catch (std::exception&)
+  {
+  }
+}
+
+} // namespace serial_port_base_compile
+
+//------------------------------------------------------------------------------
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+  test_suite* test = BOOST_TEST_SUITE("serial_port_base");
+  test->add(BOOST_TEST_CASE(&serial_port_base_compile::test));
+  return test;
+}
Added: trunk/libs/asio/test/serial_port_service.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/asio/test/serial_port_service.cpp	2008-06-09 08:54:55 EDT (Mon, 09 Jun 2008)
@@ -0,0 +1,27 @@
+//
+// serial_port_service.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include <boost/asio/serial_port_service.hpp>
+
+#include "unit_test.hpp"
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+  test_suite* test = BOOST_TEST_SUITE("serial_port_service");
+  test->add(BOOST_TEST_CASE(&null_test));
+  return test;
+}