File indexing completed on 2025-01-18 09:28:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_ASIO_DETAIL_IMPL_POSIX_SERIAL_PORT_SERVICE_IPP
0013 #define BOOST_ASIO_DETAIL_IMPL_POSIX_SERIAL_PORT_SERVICE_IPP
0014
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif
0018
0019 #include <boost/asio/detail/config.hpp>
0020
0021 #if defined(BOOST_ASIO_HAS_SERIAL_PORT)
0022 #if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
0023
0024 #include <cstring>
0025 #include <boost/asio/detail/posix_serial_port_service.hpp>
0026
0027 #include <boost/asio/detail/push_options.hpp>
0028
0029 namespace boost {
0030 namespace asio {
0031 namespace detail {
0032
0033 posix_serial_port_service::posix_serial_port_service(
0034 execution_context& context)
0035 : execution_context_service_base<posix_serial_port_service>(context),
0036 descriptor_service_(context)
0037 {
0038 }
0039
0040 void posix_serial_port_service::shutdown()
0041 {
0042 descriptor_service_.shutdown();
0043 }
0044
0045 boost::system::error_code posix_serial_port_service::open(
0046 posix_serial_port_service::implementation_type& impl,
0047 const std::string& device, boost::system::error_code& ec)
0048 {
0049 if (is_open(impl))
0050 {
0051 ec = boost::asio::error::already_open;
0052 BOOST_ASIO_ERROR_LOCATION(ec);
0053 return ec;
0054 }
0055
0056 descriptor_ops::state_type state = 0;
0057 int fd = descriptor_ops::open(device.c_str(),
0058 O_RDWR | O_NONBLOCK | O_NOCTTY, ec);
0059 if (fd < 0)
0060 {
0061 BOOST_ASIO_ERROR_LOCATION(ec);
0062 return ec;
0063 }
0064
0065 int s = descriptor_ops::fcntl(fd, F_GETFL, ec);
0066 if (s >= 0)
0067 s = descriptor_ops::fcntl(fd, F_SETFL, s | O_NONBLOCK, ec);
0068 if (s < 0)
0069 {
0070 boost::system::error_code ignored_ec;
0071 descriptor_ops::close(fd, state, ignored_ec);
0072 BOOST_ASIO_ERROR_LOCATION(ec);
0073 return ec;
0074 }
0075
0076
0077 termios ios;
0078 s = ::tcgetattr(fd, &ios);
0079 descriptor_ops::get_last_error(ec, s < 0);
0080 if (s >= 0)
0081 {
0082 #if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
0083 ::cfmakeraw(&ios);
0084 #else
0085 ios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK
0086 | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
0087 ios.c_oflag &= ~OPOST;
0088 ios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
0089 ios.c_cflag &= ~(CSIZE | PARENB);
0090 ios.c_cflag |= CS8;
0091 #endif
0092 ios.c_iflag |= IGNPAR;
0093 ios.c_cflag |= CREAD | CLOCAL;
0094 s = ::tcsetattr(fd, TCSANOW, &ios);
0095 descriptor_ops::get_last_error(ec, s < 0);
0096 }
0097 if (s < 0)
0098 {
0099 boost::system::error_code ignored_ec;
0100 descriptor_ops::close(fd, state, ignored_ec);
0101 BOOST_ASIO_ERROR_LOCATION(ec);
0102 return ec;
0103 }
0104
0105
0106 if (descriptor_service_.assign(impl, fd, ec))
0107 {
0108 boost::system::error_code ignored_ec;
0109 descriptor_ops::close(fd, state, ignored_ec);
0110 }
0111
0112 BOOST_ASIO_ERROR_LOCATION(ec);
0113 return ec;
0114 }
0115
0116 boost::system::error_code posix_serial_port_service::do_set_option(
0117 posix_serial_port_service::implementation_type& impl,
0118 posix_serial_port_service::store_function_type store,
0119 const void* option, boost::system::error_code& ec)
0120 {
0121 termios ios;
0122 int s = ::tcgetattr(descriptor_service_.native_handle(impl), &ios);
0123 descriptor_ops::get_last_error(ec, s < 0);
0124 if (s < 0)
0125 {
0126 BOOST_ASIO_ERROR_LOCATION(ec);
0127 return ec;
0128 }
0129
0130 if (store(option, ios, ec))
0131 {
0132 BOOST_ASIO_ERROR_LOCATION(ec);
0133 return ec;
0134 }
0135
0136 s = ::tcsetattr(descriptor_service_.native_handle(impl), TCSANOW, &ios);
0137 descriptor_ops::get_last_error(ec, s < 0);
0138 BOOST_ASIO_ERROR_LOCATION(ec);
0139 return ec;
0140 }
0141
0142 boost::system::error_code posix_serial_port_service::do_get_option(
0143 const posix_serial_port_service::implementation_type& impl,
0144 posix_serial_port_service::load_function_type load,
0145 void* option, boost::system::error_code& ec) const
0146 {
0147 termios ios;
0148 int s = ::tcgetattr(descriptor_service_.native_handle(impl), &ios);
0149 descriptor_ops::get_last_error(ec, s < 0);
0150 if (s < 0)
0151 {
0152 BOOST_ASIO_ERROR_LOCATION(ec);
0153 return ec;
0154 }
0155
0156 load(option, ios, ec);
0157 BOOST_ASIO_ERROR_LOCATION(ec);
0158 return ec;
0159 }
0160
0161 }
0162 }
0163 }
0164
0165 #include <boost/asio/detail/pop_options.hpp>
0166
0167 #endif
0168 #endif
0169
0170 #endif