| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 | // 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 <boost/process/detail/config.hpp>#include <boost/process/detail/traits.hpp>#if defined(BOOST_POSIX_API)#include <boost/process/detail/posix/handler.hpp>#elif defined(BOOST_WINDOWS_API)#include <boost/process/detail/windows/handler.hpp>#endif#include <system_error>#include <type_traits>#include <boost/fusion/algorithm/query/find_if.hpp>#include <boost/fusion/sequence/intrinsic/begin.hpp>#include <boost/fusion/sequence/intrinsic/end.hpp>#include <boost/fusion/container/vector/convert.hpp>#include <boost/fusion/iterator/deref.hpp>#include <boost/fusion/sequence/comparison/equal_to.hpp>#include <boost/fusion/container/set/convert.hpp>#include <boost/type_index.hpp>/** \file boost/process/error.hpp * *    Header which provides the error properties. It allows to explicitly set the error handling, the properties are: *\xmlonly<programlisting>namespace boost {  namespace process {    <emphasis>unspecified</emphasis> <globalname alt="boost::process::ignore_error">ignore_error</globalname>;    <emphasis>unspecified</emphasis> <globalname alt="boost::process::throw_on_error">throw_on_error</globalname>;    <emphasis>unspecified</emphasis> <globalname alt="boost::process::error">error</globalname>;    <emphasis>unspecified</emphasis> <globalname alt="boost::process::error_ref">error_ref</globalname>;    <emphasis>unspecified</emphasis> <globalname alt="boost::process::error_code">error_code</globalname>;  }}</programlisting>\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 <class Executor>    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 <class Executor>    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<typename T>struct is_error_handler : std::false_type {};template<> struct is_error_handler<set_on_error>    : std::true_type {};template<> struct is_error_handler<throw_on_error_> : std::true_type {};template<> struct is_error_handler<ignore_error_>   : std::true_type {};template<typename Iterator, typename End>struct has_error_handler_impl{    typedef typename boost::fusion::result_of::deref<Iterator>::type ref_type;    typedef typename std::remove_reference<ref_type>::type res_type_;    typedef typename std::remove_cv<res_type_>::type res_type;    typedef typename is_error_handler<res_type>::type cond;    typedef typename boost::fusion::result_of::next<Iterator>::type next_itr;    typedef typename has_error_handler_impl<next_itr, End>::type next;    typedef typename boost::mpl::or_<cond, next>::type type;};template<typename Iterator>struct has_error_handler_impl<Iterator, Iterator>{    typedef boost::mpl::false_ type;};template<typename Sequence>struct has_error_handler{    typedef typename boost::fusion::result_of::as_vector<Sequence>::type vector_type;    typedef typename has_error_handler_impl<            typename boost::fusion::result_of::begin<vector_type>::type,            typename boost::fusion::result_of::end<  vector_type>::type            >::type type;};template<typename Sequence>struct has_ignore_error{    typedef typename boost::fusion::result_of::as_set<Sequence>::type set_type;    typedef typename boost::fusion::result_of::has_key<set_type, ignore_error_>::type  type1;    typedef typename boost::fusion::result_of::has_key<set_type, ignore_error_&>::type type2;    typedef typename boost::fusion::result_of::has_key<set_type, const ignore_error_&>::type type3;    typedef typename boost::mpl::or_<type1,type2, type3>::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<std::error_code>{    typedef error_tag type;};template<>struct initializer_builder<error_tag>{    typedef error_builder type;};}/**The ignore_error property will disable any error handling. This can be usefulon 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));\endcodeThe following syntax is valid:\code{.cpp}error(ec);error=ec;\endcodeThe 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 <globalname alt="boost::process::error">error</globalname> \endxmlonly .constexpr boost::process::detail::error_ error_ref;///Alias for \xmlonly <globalname alt="boost::process::error">error</globalname> \endxmlonly .constexpr boost::process::detail::error_ error_code;}}#endif
 |