// Copyright (c) 2006, 2007 Julio M. Merino Vidal // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling // Copyright (c) 2009 Boris Schaeling // Copyright (c) 2010 Felipe Tanus, Boris Schaeling // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling // Copyright (c) 2016 Klemens D. Morgenstern // // 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_PROCESS_DETAIL_ERROR_HPP #define BOOST_PROCESS_DETAIL_ERROR_HPP #include #include #if defined(BOOST_POSIX_API) #include #elif defined(BOOST_WINDOWS_API) #include #endif #include #include #include #include #include #include #include #include #include #include /** \file boost/process/error.hpp * * Header which provides the error properties. It allows to explicitly set the error handling, the properties are: * \xmlonly namespace boost { namespace process { unspecified ignore_error; unspecified throw_on_error; unspecified error; unspecified error_ref; unspecified error_code; } } \endxmlonly * For error there are two aliases: error_ref and error_code */ namespace boost { namespace process { namespace detail { struct throw_on_error_ : ::boost::process::detail::api::handler_base_ext { constexpr throw_on_error_() {}; template void on_error(Executor&, const std::error_code & ec) const { throw process_error(ec, "process creation failed"); } const throw_on_error_ &operator()() const {return *this;} }; struct ignore_error_ : ::boost::process::detail::api::handler_base_ext { constexpr ignore_error_() {}; }; struct set_on_error : ::boost::process::detail::api::handler_base_ext { set_on_error(const set_on_error&) = default; explicit set_on_error(std::error_code &ec) : ec_(ec) {} template void on_error(Executor&, const std::error_code & ec) const { ec_ = ec; } private: std::error_code &ec_; }; struct error_ { constexpr error_() {} set_on_error operator()(std::error_code &ec) const {return set_on_error(ec);} set_on_error operator= (std::error_code &ec) const {return set_on_error(ec);} }; template struct is_error_handler : std::false_type {}; template<> struct is_error_handler : std::true_type {}; template<> struct is_error_handler : std::true_type {}; template<> struct is_error_handler : std::true_type {}; template struct has_error_handler_impl { typedef typename boost::fusion::result_of::deref::type ref_type; typedef typename std::remove_reference::type res_type_; typedef typename std::remove_cv::type res_type; typedef typename is_error_handler::type cond; typedef typename boost::fusion::result_of::next::type next_itr; typedef typename has_error_handler_impl::type next; typedef typename boost::mpl::or_::type type; }; template struct has_error_handler_impl { typedef boost::mpl::false_ type; }; template struct has_error_handler { typedef typename boost::fusion::result_of::as_vector::type vector_type; typedef typename has_error_handler_impl< typename boost::fusion::result_of::begin::type, typename boost::fusion::result_of::end< vector_type>::type >::type type; }; template struct has_ignore_error { typedef typename boost::fusion::result_of::as_set::type set_type; typedef typename boost::fusion::result_of::has_key::type type1; typedef typename boost::fusion::result_of::has_key::type type2; typedef typename boost::fusion::result_of::has_key::type type3; typedef typename boost::mpl::or_::type type; }; struct error_builder { std::error_code *err; typedef set_on_error result_type; set_on_error get_initializer() {return set_on_error(*err);}; void operator()(std::error_code & ec) {err = &ec;}; }; template<> struct initializer_tag { typedef error_tag type; }; template<> struct initializer_builder { typedef error_builder type; }; } /**The ignore_error property will disable any error handling. This can be useful on linux, where error handling will require a pipe.*/ constexpr boost::process::detail::ignore_error_ ignore_error; /**The throw_on_error property will enable the exception when launching a process. It is unnecessary by default, but may be used, when an additional error_code is provided.*/ constexpr boost::process::detail::throw_on_error_ throw_on_error; /** The error property will set the executor to handle any errors by setting an [std::error_code](http://en.cppreference.com/w/cpp/error/error_code). \code{.cpp} std::error_code ec; system("gcc", error(ec)); \endcode The following syntax is valid: \code{.cpp} error(ec); error=ec; \endcode The overload version is achieved by just passing an object of [std::error_code](http://en.cppreference.com/w/cpp/error/error_code) to the function. */ constexpr boost::process::detail::error_ error; ///Alias for \xmlonly error \endxmlonly . constexpr boost::process::detail::error_ error_ref; ///Alias for \xmlonly error \endxmlonly . constexpr boost::process::detail::error_ error_code; }} #endif