// Copyright (c) 2009 Dmitry Goncharov // // 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_POSIX_SIGNALFD_HPP #define BOOST_ASIO_POSIX_SIGNALFD_HPP #if (!defined(BOOST_WINDOWS) && !defined(__CYGWIN__)) \ || defined(GENERATING_DOCUMENTATION) #include #include #include #include #include #include namespace boost { namespace asio { namespace posix { template class signalfd { public: typedef char buf_type; signalfd() { int s = pipe(m_pipe); if (s < 0) { boost::system::error_code const ec(errno, boost::asio::error::get_system_category()); boost::system::system_error const e(ec, "pipe"); boost::throw_exception(e); } struct sigaction act; std::memset(&act, 0, sizeof act); std::memset(&m_oldact, 0, sizeof m_oldact); act.sa_handler = signalfd::on_signal; s = sigaction(Signo, &act, &m_oldact); if (s < 0) { boost::system::error_code const ec(errno, boost::asio::error::get_system_category()); boost::system::system_error const e(ec, "sigaction"); boost::throw_exception(e); } } ~signalfd() { sigaction(Signo, &m_oldact, 0); close(m_pipe[0]); close(m_pipe[1]); } int fd() const { return m_pipe[0]; } private: signalfd(signalfd const&); signalfd const& operator=(signalfd const&); private: static void on_signal(int signo) { try { buf_type const c = 0; // The return value is ignored, because // if write() fails there is, probably, nothing useful that can be done. while (write(m_pipe[1], &c, sizeof c) < 0 && EINTR == errno); } catch (...) {} } static int m_pipe[2]; private: struct sigaction m_oldact; }; template int signalfd::m_pipe[2]; }}} #endif // (!defined(BOOST_WINDOWS) && !defined(__CYGWIN__)) \ // || defined(GENERATING_DOCUMENTATION) #endif // BOOST_ASIO_POSIX_SIGNALFD_HPP