0byt3m1n1
Path:
C:
/
Program Files
/
R
/
R-4.2.2
/
library
/
BH
/
include
/
boost
/
process
/
v2
/
[
Home
]
File: exit_code.hpp
// // process/exit_code.hpp // ~~~~~~~~~~~~~~ // // Copyright (c) 2022 Klemens D. Morgenstern (klemens dot morgenstern at gmx dot net) // // 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_V2_EXIT_CODE_HPP #define BOOST_PROCESS_V2_EXIT_CODE_HPP #include <boost/process/v2/detail/config.hpp> #include <boost/process/v2/error.hpp> #if defined(BOOST_PROCESS_V2_STANDALONE) #include <asio/associator.hpp> #include <asio/async_result.hpp> #else #include <boost/asio/associator.hpp> #include <boost/asio/async_result.hpp> #endif #if defined(BOOST_PROCESS_V2_POSIX) #include <sys/wait.h> #endif BOOST_PROCESS_V2_BEGIN_NAMESPACE #if defined(GENERATING_DOCUMENTATION) /// The native exit-code type, usually an integral value /** The OS may have a value different from `int` to represent * the exit codes of subprocesses. It might also * contain additional information. */ typedef implementation_defined native_exit_code_type; /// Check if the native exit code indicates the process is still running bool process_is_running(native_exit_code_type code); /// Obtain the portable part of the exit code, i.e. what the subprocess has returned from main. int evaluate_exit_code(native_exit_code_type code); #else #if defined(BOOST_PROCESS_V2_WINDOWS) typedef unsigned long native_exit_code_type; namespace detail { constexpr native_exit_code_type still_active = 259u; } inline bool process_is_running(native_exit_code_type code) { return code == detail::still_active; } inline int evaluate_exit_code(native_exit_code_type code) { return static_cast<int>(code); } #else typedef int native_exit_code_type; namespace detail { constexpr native_exit_code_type still_active = 0x7f; } inline bool process_is_running(int code) { return !WIFEXITED(code) && !WIFSIGNALED(code); } inline int evaluate_exit_code(int code) { if (WIFEXITED(code)) return WEXITSTATUS(code); else if (WIFSIGNALED(code)) return WTERMSIG(code); else return code; } #endif #endif /** Convert the exit-code in a completion into an error if the actual error isn't set. * @code {.cpp} * process proc{ctx, "exit", {"1"}}; * * proc.async_wait(code_as_error( * [](error_code ec) * { * assert(ec.value() == 10); * assert(ec.category() == error::get_exit_code_category()); * })); * * @endcode */ template<typename CompletionToken> struct code_as_error_t { CompletionToken token_; const error_category & category; template<typename Token_> code_as_error_t(Token_ && token, const error_category & category) : token_(std::forward<Token_>(token)), category(category) { } }; /// Deduction function for code_as_error_t. template<typename CompletionToken> code_as_error_t<CompletionToken> code_as_error( CompletionToken && token, const error_category & category = error::get_exit_code_category()) { return code_as_error_t<typename std::decay<CompletionToken>::type>( std::forward<CompletionToken>(token), category); }; namespace detail { template<typename Handler> struct code_as_error_handler { typedef void result_type; template<typename H> code_as_error_handler(H && h, const error_category & category) : handler_(std::forward<H>(h)), category(category) { } void operator()(error_code ec, native_exit_code_type code) { if (!ec) ec.assign(code, category); std::move(handler_)(ec); } Handler handler_; const error_category & category; }; } BOOST_PROCESS_V2_END_NAMESPACE #if !defined(BOOST_PROCESS_V2_STANDALONE) namespace boost { #endif namespace asio { template <typename CompletionToken> struct async_result< BOOST_PROCESS_V2_NAMESPACE::code_as_error_t<CompletionToken>, void(BOOST_PROCESS_V2_NAMESPACE::error_code, BOOST_PROCESS_V2_NAMESPACE::native_exit_code_type)> { using signature = void(BOOST_PROCESS_V2_NAMESPACE::error_code); using return_type = typename async_result<CompletionToken, void(BOOST_PROCESS_V2_NAMESPACE::error_code)>::return_type; template <typename Initiation> struct init_wrapper { init_wrapper(Initiation init) : initiation_(std::move(init)) { } template <typename Handler, typename... Args> void operator()( Handler && handler, const BOOST_PROCESS_V2_NAMESPACE::error_category & cat, Args && ... args) { std::move(initiation_)( BOOST_PROCESS_V2_NAMESPACE::detail::code_as_error_handler<typename decay<Handler>::type>( std::forward<Handler>(handler), cat), std::forward<Args>(args)...); } Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args> static BOOST_PROCESS_V2_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature, (async_initiate<CompletionToken, signature>( declval<init_wrapper<typename decay<Initiation>::type> >(), declval<CompletionToken&>(), declval<BOOST_ASIO_MOVE_ARG(Args)>()...))) initiate( Initiation && initiation, RawCompletionToken && token, Args &&... args) { return async_initiate<CompletionToken, signature>( init_wrapper<typename decay<Initiation>::type>( std::forward<Initiation>(initiation)), token.token_, token.category, std::forward<Args>(args)...); } }; template<template <typename, typename> class Associator, typename Handler, typename DefaultCandidate> struct associator<Associator, BOOST_PROCESS_V2_NAMESPACE::detail::code_as_error_handler<Handler>, DefaultCandidate> : Associator<Handler, DefaultCandidate> { static typename Associator<Handler, DefaultCandidate>::type get( const BOOST_PROCESS_V2_NAMESPACE::detail::code_as_error_handler<Handler> & h, const DefaultCandidate& c = DefaultCandidate()) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); } }; } #if !defined(BOOST_PROCESS_V2_STANDALONE) } // boost #endif #endif //BOOST_PROCESS_V2_EXIT_CODE_HPP