summaryrefslogtreecommitdiff
path: root/boost/process/error.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/process/error.hpp')
-rw-r--r--boost/process/error.hpp211
1 files changed, 211 insertions, 0 deletions
diff --git a/boost/process/error.hpp b/boost/process/error.hpp
new file mode 100644
index 0000000000..f70cce6c83
--- /dev/null
+++ b/boost/process/error.hpp
@@ -0,0 +1,211 @@
+// 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 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 <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