diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:11:01 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:11:01 +0900 |
commit | 3fdc3e5ee96dca5b11d1694975a65200787eab86 (patch) | |
tree | 5c1733853892b8397d67706fa453a9bd978d2102 /boost/process | |
parent | 88e602c57797660ebe0f9e15dbd64c1ff16dead3 (diff) | |
download | boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.gz boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.bz2 boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.zip |
Imported Upstream version 1.66.0upstream/1.66.0
Diffstat (limited to 'boost/process')
89 files changed, 5859 insertions, 5707 deletions
diff --git a/boost/process/async.hpp b/boost/process/async.hpp index 9698aab931..4bfe5d4136 100644 --- a/boost/process/async.hpp +++ b/boost/process/async.hpp @@ -7,7 +7,7 @@ The header which provides the basic asynchrounous features. It provides the on_exit property, which allows callbacks when the process exits. -It also implements the necessary traits for passing an boost::asio::io_service, +It also implements the necessary traits for passing an boost::asio::io_context, which is needed for asynchronous communication. It also pulls the [boost::asio::buffer](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/buffer.html) @@ -32,20 +32,20 @@ namespace boost { #include <boost/process/detail/traits.hpp> #include <boost/process/detail/on_exit.hpp> -#include <boost/asio/io_service.hpp> +#include <boost/asio/io_context.hpp> #include <boost/asio/streambuf.hpp> #include <boost/asio/buffer.hpp> #include <type_traits> #include <boost/fusion/iterator/deref.hpp> #if defined(BOOST_POSIX_API) -#include <boost/process/detail/posix/io_service_ref.hpp> +#include <boost/process/detail/posix/io_context_ref.hpp> #include <boost/process/detail/posix/async_in.hpp> #include <boost/process/detail/posix/async_out.hpp> #include <boost/process/detail/posix/on_exit.hpp> #elif defined(BOOST_WINDOWS_API) -#include <boost/process/detail/windows/io_service_ref.hpp> +#include <boost/process/detail/windows/io_context_ref.hpp> #include <boost/process/detail/windows/async_in.hpp> #include <boost/process/detail/windows/async_out.hpp> #include <boost/process/detail/windows/on_exit.hpp> @@ -56,25 +56,25 @@ namespace boost { namespace process { namespace detail { struct async_tag; template<typename T> -struct is_io_service : std::false_type {}; +struct is_io_context : std::false_type {}; template<> -struct is_io_service<api::io_service_ref> : std::true_type {}; +struct is_io_context<api::io_context_ref> : std::true_type {}; template<typename Tuple> -inline asio::io_service& get_io_service(const Tuple & tup) +inline asio::io_context& get_io_context(const Tuple & tup) { - auto& ref = *boost::fusion::find_if<is_io_service<boost::mpl::_>>(tup); + auto& ref = *boost::fusion::find_if<is_io_context<boost::mpl::_>>(tup); return ref.get(); } struct async_builder { - boost::asio::io_service * ios; + boost::asio::io_context * ios; - void operator()(boost::asio::io_service & ios_) {this->ios = &ios_;}; + void operator()(boost::asio::io_context & ios_) {this->ios = &ios_;}; - typedef api::io_service_ref result_type; - api::io_service_ref get_initializer() {return api::io_service_ref (*ios);}; + typedef api::io_context_ref result_type; + api::io_context_ref get_initializer() {return api::io_context_ref (*ios);}; }; @@ -90,7 +90,7 @@ using ::boost::asio::buffer; #if defined(BOOST_PROCESS_DOXYGEN) -/** When an io_service is passed, the on_exit property can be used, to be notified +/** When an io_context is passed, the on_exit property can be used, to be notified when the child process exits. @@ -107,7 +107,7 @@ with `function` being a callable object with the signature `(int, const std::err \par Example \code{.cpp} -io_service ios; +io_context ios; child c("ls", on_exit=[](int exit, const std::error_code& ec_in){}); @@ -117,8 +117,8 @@ chlid c2("ls", on_exit=exit_code); \endcode \note The handler is not invoked when the launch fails. -\warning When used \ref ignore_error it might gte invoked on error. - +\warning When used \ref ignore_error it might get invoked on error. +\warning All `on_exit` use one signal(SIGCHLD) on posix, which is only guaranteed to work when all use the same `io_context`. */ constexpr static ::boost::process::detail::on_exit_ on_exit{}; #endif diff --git a/boost/process/async_pipe.hpp b/boost/process/async_pipe.hpp index 97af165859..101fe1d59d 100644 --- a/boost/process/async_pipe.hpp +++ b/boost/process/async_pipe.hpp @@ -48,31 +48,31 @@ public: typedef platform_specific handle_type; /** Construct a new async_pipe, does automatically open the pipe. - * Initializes source and sink with the same io_service. + * Initializes source and sink with the same io_context. * @note Windows creates a named pipe here, where the name is automatically generated. */ - inline async_pipe(boost::asio::io_service & ios); + inline async_pipe(boost::asio::io_context & ios); /** Construct a new async_pipe, does automatically open the pipe. * @note Windows creates a named pipe here, where the name is automatically generated. */ - inline async_pipe(boost::asio::io_service & ios_source, - boost::asio::io_service & ios_sink); + inline async_pipe(boost::asio::io_context & ios_source, + boost::asio::io_context & ios_sink); /** Construct a new async_pipe, does automatically open. - * Initializes source and sink with the same io_service. + * Initializes source and sink with the same io_context. * * @note Windows restricts possible names. */ - inline async_pipe(boost::asio::io_service & ios, const std::string & name); + inline async_pipe(boost::asio::io_context & ios, const std::string & name); /** Construct a new async_pipe, does automatically open. * * @note Windows restricts possible names. */ - inline async_pipe(boost::asio::io_service & ios_source, - boost::asio::io_service & ios_sink, const std::string & name); + inline async_pipe(boost::asio::io_context & ios_source, + boost::asio::io_context & ios_sink, const std::string & name); /** Copy-Constructor of the async pipe. * @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown. @@ -89,15 +89,15 @@ public: * */ template<class CharT, class Traits = std::char_traits<CharT>> - explicit async_pipe(boost::asio::io_service & ios, const basic_pipe<CharT, Traits> & p); + explicit async_pipe(boost::asio::io_context & ios, const basic_pipe<CharT, Traits> & p); - /** Construct the async-pipe from a pipe, with two different io_service objects. + /** Construct the async-pipe from a pipe, with two different io_context objects. * @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown. * */ template<class CharT, class Traits = std::char_traits<CharT>> - explicit async_pipe(boost::asio::io_service & ios_source, - boost::asio::io_service & ios_sink, + explicit async_pipe(boost::asio::io_context & ios_source, + boost::asio::io_context & ios_sink, const basic_pipe<CharT, Traits> & p); @@ -189,15 +189,15 @@ public: ///Get the asio handle of the pipe source. Qualified as rvalue handle_type && source() &&; - /// Move the source out of this class and change the io_service. Qualified as rvalue. \attention Will always move. - handle_type source(::boost::asio::io_service& ios) &&; - /// Move the sink out of this class and change the io_service. Qualified as rvalue. \attention Will always move - handle_type sink (::boost::asio::io_service& ios) &&; + /// Move the source out of this class and change the io_context. Qualified as rvalue. \attention Will always move. + handle_type source(::boost::asio::io_context& ios) &&; + /// Move the sink out of this class and change the io_context. Qualified as rvalue. \attention Will always move + handle_type sink (::boost::asio::io_context& ios) &&; - /// Copy the source out of this class and change the io_service. \attention Will always copy. - handle_type source(::boost::asio::io_service& ios) const &; - /// Copy the sink out of this class and change the io_service. \attention Will always copy - handle_type sink (::boost::asio::io_service& ios) const &; + /// Copy the source out of this class and change the io_context. \attention Will always copy. + handle_type source(::boost::asio::io_context& ios) const &; + /// Copy the sink out of this class and change the io_context. \attention Will always copy + handle_type sink (::boost::asio::io_context& ios) const &; diff --git a/boost/process/async_system.hpp b/boost/process/async_system.hpp index f92b417d2e..9bd0358c43 100644 --- a/boost/process/async_system.hpp +++ b/boost/process/async_system.hpp @@ -40,8 +40,8 @@ namespace detail template<typename ExitHandler> struct async_system_handler : ::boost::process::detail::api::async_handler { - boost::asio::io_service & ios; - boost::asio::detail::async_result_init< + boost::asio::io_context & ios; + boost::asio::async_completion< ExitHandler, void(boost::system::error_code, int)> init; #if defined(BOOST_POSIX_API) @@ -50,8 +50,8 @@ struct async_system_handler : ::boost::process::detail::api::async_handler template<typename ExitHandler_> async_system_handler( - boost::asio::io_service & ios, - ExitHandler_ && exit_handler) : ios(ios), init(std::forward<ExitHandler_>(exit_handler)) + boost::asio::io_context & ios, + ExitHandler_ && exit_handler) : ios(ios), init(exit_handler) { } @@ -63,7 +63,7 @@ struct async_system_handler : ::boost::process::detail::api::async_handler #if defined(BOOST_POSIX_API) errored = true; #endif - auto & h = init.handler; + auto & h = init.completion_handler; ios.post( [h, ec]() mutable { @@ -84,7 +84,7 @@ struct async_system_handler : ::boost::process::detail::api::async_handler if (errored) return [](int exit_code, const std::error_code & ec){}; #endif - auto & h = init.handler; + auto & h = init.completion_handler; return [h](int exit_code, const std::error_code & ec) mutable { h(boost::system::error_code(ec.value(), boost::system::system_category()), exit_code); @@ -106,7 +106,7 @@ but is similar to the asynchronous functions in [boost.asio](http://www.boost.or It uses [asio::async_result](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/async_result.html) to determine the return value (from the second parameter, `exit_handler`). -\param ios A reference to an [io_service](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference.html) +\param ios A reference to an [io_context](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference.html) \param exit_handler The exit-handler for the signature `void(boost::system::error_code, int)` \note This function does not allow custom error handling, since those are done through the `exit_handler`. @@ -115,12 +115,12 @@ the return value (from the second parameter, `exit_handler`). #if defined(BOOST_PROCESS_DOXYGEN) template<typename ExitHandler, typename ...Args> inline boost::process::detail::dummy - async_system(boost::asio::io_service & ios, ExitHandler && exit_handler, Args && ...args); + async_system(boost::asio::io_context & ios, ExitHandler && exit_handler, Args && ...args); #endif template<typename ExitHandler, typename ...Args> inline BOOST_ASIO_INITFN_RESULT_TYPE(ExitHandler, void (boost::system::error_code, int)) - async_system(boost::asio::io_service & ios, ExitHandler && exit_handler, Args && ...args) + async_system(boost::asio::io_context & ios, ExitHandler && exit_handler, Args && ...args) { detail::async_system_handler<ExitHandler> async_h{ios, std::forward<ExitHandler>(exit_handler)}; diff --git a/boost/process/child.hpp b/boost/process/child.hpp index 980cecdae7..01cd93c385 100644 --- a/boost/process/child.hpp +++ b/boost/process/child.hpp @@ -35,6 +35,9 @@ child::child(Args&&...args) : child(::boost::process::detail::execute_impl(std::forward<Args>(args)...)) {} +///Typedef for the type of an pid_t +typedef ::boost::process::detail::api::pid_t pid_t; + #if defined(BOOST_PROCESS_DOXYGEN) /** The main class to hold a child process. It is simliar to [std::thread](http://en.cppreference.com/w/cpp/thread/thread), * in that it has a join and detach function. diff --git a/boost/process/cmd.hpp b/boost/process/cmd.hpp index 5985c81430..d894ec4d0a 100644 --- a/boost/process/cmd.hpp +++ b/boost/process/cmd.hpp @@ -1,122 +1,122 @@ -// 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_CMD_LINE_HPP
-#define BOOST_PROCESS_DETAIL_CMD_LINE_HPP
- -#include <boost/detail/winapi/config.hpp>
-#include <boost/process/detail/config.hpp>
-#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/traits/cmd_or_exe.hpp>
-#include <boost/process/detail/traits/wchar_t.hpp>
+// 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_CMD_LINE_HPP +#define BOOST_PROCESS_DETAIL_CMD_LINE_HPP + +#include <boost/winapi/config.hpp> +#include <boost/process/detail/config.hpp> +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/traits/cmd_or_exe.hpp> +#include <boost/process/detail/traits/wchar_t.hpp> -#if defined(BOOST_POSIX_API)
-#include <boost/process/detail/posix/cmd.hpp>
-#elif defined(BOOST_WINDOWS_API)
-#include <boost/process/detail/windows/cmd.hpp>
-#endif
+#if defined(BOOST_POSIX_API) +#include <boost/process/detail/posix/cmd.hpp> +#elif defined(BOOST_WINDOWS_API) +#include <boost/process/detail/windows/cmd.hpp> +#endif -/** \file boost/process/cmd.hpp
- *
- * This header provides the \xmlonly <globalname alt="boost::process::cmd">cmd</globalname>\endxmlonly property.
- *
-\xmlonly
-<programlisting>
-namespace boost {
- namespace process {
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::cmd">cmd</globalname>;
- }
-}
-</programlisting>
-\endxmlonly
-*/
+/** \file boost/process/cmd.hpp + * + * This header provides the \xmlonly <globalname alt="boost::process::cmd">cmd</globalname>\endxmlonly property. + * +\xmlonly +<programlisting> +namespace boost { + namespace process { + <emphasis>unspecified</emphasis> <globalname alt="boost::process::cmd">cmd</globalname>; + } +} +</programlisting> +\endxmlonly +*/ -namespace boost { namespace process { namespace detail {
+namespace boost { namespace process { namespace detail { -struct cmd_
-{
- constexpr cmd_() {}
+struct cmd_ +{ + constexpr cmd_() {} - template<typename Char>
- inline api::cmd_setter_<Char> operator()(const Char *s) const
- {
- return api::cmd_setter_<Char>(s);
- }
- template<typename Char>
- inline api::cmd_setter_<Char> operator= (const Char *s) const
- {
- return api::cmd_setter_<Char>(s);
- }
+ template<typename Char> + inline api::cmd_setter_<Char> operator()(const Char *s) const + { + return api::cmd_setter_<Char>(s); + } + template<typename Char> + inline api::cmd_setter_<Char> operator= (const Char *s) const + { + return api::cmd_setter_<Char>(s); + } - template<typename Char>
- inline api::cmd_setter_<Char> operator()(const std::basic_string<Char> &s) const
- {
- return api::cmd_setter_<Char>(s);
- }
- template<typename Char>
- inline api::cmd_setter_<Char> operator= (const std::basic_string<Char> &s) const
- {
- return api::cmd_setter_<Char>(s);
- }
-};
+ template<typename Char> + inline api::cmd_setter_<Char> operator()(const std::basic_string<Char> &s) const + { + return api::cmd_setter_<Char>(s); + } + template<typename Char> + inline api::cmd_setter_<Char> operator= (const std::basic_string<Char> &s) const + { + return api::cmd_setter_<Char>(s); + } +}; -template<> struct is_wchar_t<api::cmd_setter_<wchar_t>> : std::true_type {};
+template<> struct is_wchar_t<api::cmd_setter_<wchar_t>> : std::true_type {}; -template<>
-struct char_converter<char, api::cmd_setter_<wchar_t>>
-{
- static api::cmd_setter_<char> conv(const api::cmd_setter_<wchar_t> & in)
- {
- return { ::boost::process::detail::convert(in.str()) };
- }
-};
+template<> +struct char_converter<char, api::cmd_setter_<wchar_t>> +{ + static api::cmd_setter_<char> conv(const api::cmd_setter_<wchar_t> & in) + { + return { ::boost::process::detail::convert(in.str()) }; + } +}; -template<>
-struct char_converter<wchar_t, api::cmd_setter_<char>>
-{
- static api::cmd_setter_<wchar_t> conv(const api::cmd_setter_<char> & in)
- {
- return { ::boost::process::detail::convert(in.str()) };
- }
-};
+template<> +struct char_converter<wchar_t, api::cmd_setter_<char>> +{ + static api::cmd_setter_<wchar_t> conv(const api::cmd_setter_<char> & in) + { + return { ::boost::process::detail::convert(in.str()) }; + } +}; -}
+} -/** The cmd property allows to explicitly set commands for the execution.
+/** The cmd property allows to explicitly set commands for the execution. -The overload form applies when only one string is passed to a launching function.
-The string will be internally parsed and split at spaces.
+The overload form applies when only one string is passed to a launching function. +The string will be internally parsed and split at spaces. -The following expressions are valid, with `value` being either a C-String or
-a `std::basic_string` with `char` or `wchar_t`.
+The following expressions are valid, with `value` being either a C-String or +a `std::basic_string` with `char` or `wchar_t`. -\code{.cpp}
-cmd="value";
-cmd(value);
-\endcode
+\code{.cpp} +cmd="value"; +cmd(value); +\endcode -The property can only be used for assignments.
+The property can only be used for assignments. - */
-constexpr static ::boost::process::detail::cmd_ cmd;
+ */ +constexpr static ::boost::process::detail::cmd_ cmd; -}}
+}} -#endif
+#endif diff --git a/boost/process/detail/async_handler.hpp b/boost/process/detail/async_handler.hpp index 832a42014e..b4eaf9349a 100644 --- a/boost/process/detail/async_handler.hpp +++ b/boost/process/detail/async_handler.hpp @@ -27,37 +27,37 @@ namespace detail { #if defined(BOOST_POSIX_API) using ::boost::process::detail::posix::is_async_handler; -using ::boost::process::detail::posix::does_require_io_service; +using ::boost::process::detail::posix::does_require_io_context; #else using ::boost::process::detail::windows::is_async_handler; -using ::boost::process::detail::windows::does_require_io_service; +using ::boost::process::detail::windows::does_require_io_context; #endif template<typename ...Args> -struct has_io_service; +struct has_io_context; template<typename T, typename ...Args> -struct has_io_service<T, Args...> +struct has_io_context<T, Args...> { - typedef typename has_io_service<Args...>::type next; + typedef typename has_io_context<Args...>::type next; typedef typename std::is_same< typename std::remove_reference<T>::type, - boost::asio::io_service>::type is_ios; + boost::asio::io_context>::type is_ios; typedef typename std::conditional<is_ios::value, std::true_type, next>::type type; }; template<typename T> -struct has_io_service<T> +struct has_io_context<T> { typedef typename std::is_same< typename std::remove_reference<T>::type, - boost::asio::io_service>::type type; + boost::asio::io_context>::type type; }; template<typename ...Args> -using has_io_service_t = typename has_io_service<Args...>::type; +using has_io_context_t = typename has_io_context<Args...>::type; template<typename ...Args> struct has_async_handler; @@ -79,34 +79,34 @@ struct has_async_handler<T> }; template<typename ...Args> -struct needs_io_service; +struct needs_io_context; template<typename T, typename ...Args> -struct needs_io_service<T, Args...> +struct needs_io_context<T, Args...> { - typedef typename needs_io_service<Args...>::type next; - typedef typename does_require_io_service<T>::type is_ios; + typedef typename needs_io_context<Args...>::type next; + typedef typename does_require_io_context<T>::type is_ios; typedef typename std::conditional<is_ios::value, std::true_type, next>::type type; }; template<typename T> -struct needs_io_service<T> +struct needs_io_context<T> { - typedef typename does_require_io_service<T>::type type; + typedef typename does_require_io_context<T>::type type; }; template<typename ...Args> -boost::asio::io_service &get_io_service_var(boost::asio::io_service & f, Args&...) +boost::asio::io_context &get_io_context_var(boost::asio::io_context & f, Args&...) { return f; } template<typename First, typename ...Args> -boost::asio::io_service &get_io_service_var(First&, Args&...args) +boost::asio::io_context &get_io_context_var(First&, Args&...args) { - return get_io_service_var(args...); + return get_io_context_var(args...); } } diff --git a/boost/process/detail/basic_cmd.hpp b/boost/process/detail/basic_cmd.hpp index e387d9f0c5..3da51ffe1f 100644 --- a/boost/process/detail/basic_cmd.hpp +++ b/boost/process/detail/basic_cmd.hpp @@ -1,292 +1,292 @@ -// 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_BASIC_CMD_HPP_
-#define BOOST_PROCESS_DETAIL_BASIC_CMD_HPP_
- -#include <boost/process/detail/config.hpp>
- -#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/traits/cmd_or_exe.hpp>
-#include <boost/process/detail/traits/wchar_t.hpp>
- -#if defined( BOOST_WINDOWS_API )
-#include <boost/process/detail/windows/basic_cmd.hpp>
-#include <boost/process/detail/windows/cmd.hpp>
-#elif defined( BOOST_POSIX_API )
-#include <boost/process/detail/posix/basic_cmd.hpp>
-#include <boost/process/detail/posix/cmd.hpp>
-#endif
- -#include <boost/process/shell.hpp>
- -#include <iterator>
- - -namespace boost { namespace process { namespace detail {
- -template<typename Char>
-struct exe_setter_
-{
- typedef Char value_type;
- typedef std::basic_string<Char> string_type;
- - string_type exe_;
- exe_setter_(string_type && str) : exe_(std::move(str)) {}
- exe_setter_(const string_type & str) : exe_(str) {}
-};
- -template<> struct is_wchar_t<exe_setter_<wchar_t>> : std::true_type {};
- - -template<>
-struct char_converter<char, exe_setter_<wchar_t>>
-{
- static exe_setter_<char> conv(const exe_setter_<wchar_t> & in)
- {
- return {::boost::process::detail::convert(in.exe_)};
- }
-};
- -template<>
-struct char_converter<wchar_t, exe_setter_<char>>
-{
- static exe_setter_<wchar_t> conv(const exe_setter_<char> & in)
- {
- return {::boost::process::detail::convert(in.exe_)};
- }
-};
- - - -template <typename Char, bool Append >
-struct arg_setter_
-{
- using value_type = Char;
- using string_type = std::basic_string<value_type>;
- std::vector<string_type> _args;
- - typedef typename std::vector<string_type>::iterator iterator;
- typedef typename std::vector<string_type>::const_iterator const_iterator;
- - template<typename Iterator>
- arg_setter_(Iterator && begin, Iterator && end) : _args(begin, end) {}
- - template<typename Range>
- arg_setter_(Range && str) :
- _args(std::begin(str),
- std::end(str)) {}
- - iterator begin() {return _args.begin();}
- iterator end() {return _args.end();}
- const_iterator begin() const {return _args.begin();}
- const_iterator end() const {return _args.end();}
- arg_setter_(string_type & str) : _args{{str}} {}
- arg_setter_(string_type && s) : _args({std::move(s)}) {}
- arg_setter_(const string_type & s) : _args({s}) {}
- arg_setter_(const value_type* s) : _args({std::move(s)}) {}
- - template<std::size_t Size>
- arg_setter_(const value_type (&s) [Size]) : _args({s}) {}
-};
- -template<> struct is_wchar_t<arg_setter_<wchar_t, true >> : std::true_type {};
-template<> struct is_wchar_t<arg_setter_<wchar_t, false>> : std::true_type {};
- -template<>
-struct char_converter<char, arg_setter_<wchar_t, true>>
-{
- static arg_setter_<char, true> conv(const arg_setter_<wchar_t, true> & in)
- {
- std::vector<std::string> vec(in._args.size());
- std::transform(in._args.begin(), in._args.end(), vec.begin(),
- [](const std::wstring & ws)
- {
- return ::boost::process::detail::convert(ws);
- });
- return {vec};
- }
-};
- -template<>
-struct char_converter<wchar_t, arg_setter_<char, true>>
-{
- static arg_setter_<wchar_t, true> conv(const arg_setter_<char, true> & in)
- {
- std::vector<std::wstring> vec(in._args.size());
- std::transform(in._args.begin(), in._args.end(), vec.begin(),
- [](const std::string & ws)
- {
- return ::boost::process::detail::convert(ws);
- });
- - return {vec};
- }
-};
- -template<>
-struct char_converter<char, arg_setter_<wchar_t, false>>
-{
- static arg_setter_<char, false> conv(const arg_setter_<wchar_t, false> & in)
- {
- std::vector<std::string> vec(in._args.size());
- std::transform(in._args.begin(), in._args.end(), vec.begin(),
- [](const std::wstring & ws)
- {
- return ::boost::process::detail::convert(ws);
- });
- return {vec}; }
-};
- -template<>
-struct char_converter<wchar_t, arg_setter_<char, false>>
-{
- static arg_setter_<wchar_t, false> conv(const arg_setter_<char, false> & in)
- {
- std::vector<std::wstring> vec(in._args.size());
- std::transform(in._args.begin(), in._args.end(), vec.begin(),
- [](const std::string & ws)
- {
- return ::boost::process::detail::convert(ws);
- });
- return {vec};
- }
-};
- -using api::exe_cmd_init;
- -template<typename Char>
-struct exe_builder
-{
- //set by path, because that will not be interpreted as a cmd
- bool not_cmd = false;
- bool shell = false;
- using string_type = std::basic_string<Char>;
- string_type exe;
- std::vector<string_type> args;
- - void operator()(const boost::filesystem::path & data)
- {
- not_cmd = true;
- if (exe.empty())
- exe = data.native();
- else
- args.push_back(data.native());
- }
- - void operator()(const string_type & data)
- {
- if (exe.empty())
- exe = data;
- else
- args.push_back(data);
- }
- void operator()(const Char* data)
- {
- if (exe.empty())
- exe = data;
- else
- args.push_back(data);
- }
- void operator()(shell_) {shell = true;}
- void operator()(std::vector<string_type> && data)
- {
- if (data.empty())
- return;
- - auto itr = std::make_move_iterator(data.begin());
- auto end = std::make_move_iterator(data.end());
- - if (exe.empty())
- {
- exe = *itr;
- itr++;
- }
- args.insert(args.end(), itr, end);
- }
- - void operator()(const std::vector<string_type> & data)
- {
- if (data.empty())
- return;
- - auto itr = data.begin();
- auto end = data.end();
- - if (exe.empty())
- {
- exe = *itr;
- itr++;
- }
- args.insert(args.end(), itr, end);
- }
- void operator()(exe_setter_<Char> && data)
- {
- not_cmd = true;
- exe = std::move(data.exe_);
- }
- void operator()(const exe_setter_<Char> & data)
- {
- not_cmd = true;
- exe = data.exe_;
- }
- void operator()(arg_setter_<Char, false> && data)
- {
- args.assign(
- std::make_move_iterator(data._args.begin()),
- std::make_move_iterator(data._args.end()));
- }
- void operator()(arg_setter_<Char, true> && data)
- {
- args.insert(args.end(),
- std::make_move_iterator(data._args.begin()),
- std::make_move_iterator(data._args.end()));
- }
- void operator()(const arg_setter_<Char, false> & data)
- {
- args.assign(data._args.begin(), data._args.end());
- }
- void operator()(const arg_setter_<Char, true> & data)
- {
- args.insert(args.end(), data._args.begin(), data._args.end());
- }
- - api::exe_cmd_init<Char> get_initializer()
- {
- if (not_cmd || !args.empty())
- {
- if (shell)
- return api::exe_cmd_init<Char>::exe_args_shell(std::move(exe), std::move(args));
- else
- return api::exe_cmd_init<Char>::exe_args(std::move(exe), std::move(args));
- }
- else
- if (shell)
- return api::exe_cmd_init<Char>::cmd_shell(std::move(exe));
- else
- return api::exe_cmd_init<Char>::cmd(std::move(exe));
- - }
- typedef api::exe_cmd_init<Char> result_type;
-};
- -template<>
-struct initializer_builder<cmd_or_exe_tag<char>>
-{
- typedef exe_builder<char> type;
-};
- -template<>
-struct initializer_builder<cmd_or_exe_tag<wchar_t>>
-{
- typedef exe_builder<wchar_t> type;
-};
- -}}}
- - - -#endif /* BOOST_PROCESS_DETAIL_EXE_BUILDER_HPP_ */
+// 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_BASIC_CMD_HPP_ +#define BOOST_PROCESS_DETAIL_BASIC_CMD_HPP_ + +#include <boost/process/detail/config.hpp> + +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/traits/cmd_or_exe.hpp> +#include <boost/process/detail/traits/wchar_t.hpp> + +#if defined( BOOST_WINDOWS_API ) +#include <boost/process/detail/windows/basic_cmd.hpp> +#include <boost/process/detail/windows/cmd.hpp> +#elif defined( BOOST_POSIX_API ) +#include <boost/process/detail/posix/basic_cmd.hpp> +#include <boost/process/detail/posix/cmd.hpp> +#endif + +#include <boost/process/shell.hpp> + +#include <iterator> + + +namespace boost { namespace process { namespace detail { + +template<typename Char> +struct exe_setter_ +{ + typedef Char value_type; + typedef std::basic_string<Char> string_type; + + string_type exe_; + exe_setter_(string_type && str) : exe_(std::move(str)) {} + exe_setter_(const string_type & str) : exe_(str) {} +}; + +template<> struct is_wchar_t<exe_setter_<wchar_t>> : std::true_type {}; + + +template<> +struct char_converter<char, exe_setter_<wchar_t>> +{ + static exe_setter_<char> conv(const exe_setter_<wchar_t> & in) + { + return {::boost::process::detail::convert(in.exe_)}; + } +}; + +template<> +struct char_converter<wchar_t, exe_setter_<char>> +{ + static exe_setter_<wchar_t> conv(const exe_setter_<char> & in) + { + return {::boost::process::detail::convert(in.exe_)}; + } +}; + + + +template <typename Char, bool Append > +struct arg_setter_ +{ + using value_type = Char; + using string_type = std::basic_string<value_type>; + std::vector<string_type> _args; + + typedef typename std::vector<string_type>::iterator iterator; + typedef typename std::vector<string_type>::const_iterator const_iterator; + + template<typename Iterator> + arg_setter_(Iterator && begin, Iterator && end) : _args(begin, end) {} + + template<typename Range> + arg_setter_(Range && str) : + _args(std::begin(str), + std::end(str)) {} + + iterator begin() {return _args.begin();} + iterator end() {return _args.end();} + const_iterator begin() const {return _args.begin();} + const_iterator end() const {return _args.end();} + arg_setter_(string_type & str) : _args{{str}} {} + arg_setter_(string_type && s) : _args({std::move(s)}) {} + arg_setter_(const string_type & s) : _args({s}) {} + arg_setter_(const value_type* s) : _args({std::move(s)}) {} + + template<std::size_t Size> + arg_setter_(const value_type (&s) [Size]) : _args({s}) {} +}; + +template<> struct is_wchar_t<arg_setter_<wchar_t, true >> : std::true_type {}; +template<> struct is_wchar_t<arg_setter_<wchar_t, false>> : std::true_type {}; + +template<> +struct char_converter<char, arg_setter_<wchar_t, true>> +{ + static arg_setter_<char, true> conv(const arg_setter_<wchar_t, true> & in) + { + std::vector<std::string> vec(in._args.size()); + std::transform(in._args.begin(), in._args.end(), vec.begin(), + [](const std::wstring & ws) + { + return ::boost::process::detail::convert(ws); + }); + return {vec}; + } +}; + +template<> +struct char_converter<wchar_t, arg_setter_<char, true>> +{ + static arg_setter_<wchar_t, true> conv(const arg_setter_<char, true> & in) + { + std::vector<std::wstring> vec(in._args.size()); + std::transform(in._args.begin(), in._args.end(), vec.begin(), + [](const std::string & ws) + { + return ::boost::process::detail::convert(ws); + }); + + return {vec}; + } +}; + +template<> +struct char_converter<char, arg_setter_<wchar_t, false>> +{ + static arg_setter_<char, false> conv(const arg_setter_<wchar_t, false> & in) + { + std::vector<std::string> vec(in._args.size()); + std::transform(in._args.begin(), in._args.end(), vec.begin(), + [](const std::wstring & ws) + { + return ::boost::process::detail::convert(ws); + }); + return {vec}; } +}; + +template<> +struct char_converter<wchar_t, arg_setter_<char, false>> +{ + static arg_setter_<wchar_t, false> conv(const arg_setter_<char, false> & in) + { + std::vector<std::wstring> vec(in._args.size()); + std::transform(in._args.begin(), in._args.end(), vec.begin(), + [](const std::string & ws) + { + return ::boost::process::detail::convert(ws); + }); + return {vec}; + } +}; + +using api::exe_cmd_init; + +template<typename Char> +struct exe_builder +{ + //set by path, because that will not be interpreted as a cmd + bool not_cmd = false; + bool shell = false; + using string_type = std::basic_string<Char>; + string_type exe; + std::vector<string_type> args; + + void operator()(const boost::filesystem::path & data) + { + not_cmd = true; + if (exe.empty()) + exe = data.native(); + else + args.push_back(data.native()); + } + + void operator()(const string_type & data) + { + if (exe.empty()) + exe = data; + else + args.push_back(data); + } + void operator()(const Char* data) + { + if (exe.empty()) + exe = data; + else + args.push_back(data); + } + void operator()(shell_) {shell = true;} + void operator()(std::vector<string_type> && data) + { + if (data.empty()) + return; + + auto itr = std::make_move_iterator(data.begin()); + auto end = std::make_move_iterator(data.end()); + + if (exe.empty()) + { + exe = *itr; + itr++; + } + args.insert(args.end(), itr, end); + } + + void operator()(const std::vector<string_type> & data) + { + if (data.empty()) + return; + + auto itr = data.begin(); + auto end = data.end(); + + if (exe.empty()) + { + exe = *itr; + itr++; + } + args.insert(args.end(), itr, end); + } + void operator()(exe_setter_<Char> && data) + { + not_cmd = true; + exe = std::move(data.exe_); + } + void operator()(const exe_setter_<Char> & data) + { + not_cmd = true; + exe = data.exe_; + } + void operator()(arg_setter_<Char, false> && data) + { + args.assign( + std::make_move_iterator(data._args.begin()), + std::make_move_iterator(data._args.end())); + } + void operator()(arg_setter_<Char, true> && data) + { + args.insert(args.end(), + std::make_move_iterator(data._args.begin()), + std::make_move_iterator(data._args.end())); + } + void operator()(const arg_setter_<Char, false> & data) + { + args.assign(data._args.begin(), data._args.end()); + } + void operator()(const arg_setter_<Char, true> & data) + { + args.insert(args.end(), data._args.begin(), data._args.end()); + } + + api::exe_cmd_init<Char> get_initializer() + { + if (not_cmd || !args.empty()) + { + if (shell) + return api::exe_cmd_init<Char>::exe_args_shell(std::move(exe), std::move(args)); + else + return api::exe_cmd_init<Char>::exe_args(std::move(exe), std::move(args)); + } + else + if (shell) + return api::exe_cmd_init<Char>::cmd_shell(std::move(exe)); + else + return api::exe_cmd_init<Char>::cmd(std::move(exe)); + + } + typedef api::exe_cmd_init<Char> result_type; +}; + +template<> +struct initializer_builder<cmd_or_exe_tag<char>> +{ + typedef exe_builder<char> type; +}; + +template<> +struct initializer_builder<cmd_or_exe_tag<wchar_t>> +{ + typedef exe_builder<wchar_t> type; +}; + +}}} + + + +#endif /* BOOST_PROCESS_DETAIL_EXE_BUILDER_HPP_ */ diff --git a/boost/process/detail/child_decl.hpp b/boost/process/detail/child_decl.hpp index 3483f7c4b8..24603ffb45 100644 --- a/boost/process/detail/child_decl.hpp +++ b/boost/process/detail/child_decl.hpp @@ -65,7 +65,8 @@ public: child(child && lhs) noexcept : _child_handle(std::move(lhs._child_handle)), _exit_status(std::move(lhs._exit_status)), - _attached (lhs._attached) + _attached (lhs._attached), + _terminated (lhs._terminated) { lhs._attached = false; } @@ -79,6 +80,7 @@ public: _child_handle= std::move(lhs._child_handle); _exit_status = std::move(lhs._exit_status); _attached = lhs._attached; + _terminated = lhs._terminated; lhs._attached = false; return *this; }; @@ -103,7 +105,7 @@ public: { if (valid() && !_exited()) { - int code; + int code = -1; auto res = boost::process::detail::api::is_running(_child_handle, code); if (!res && !_exited()) _exit_status->store(code); diff --git a/boost/process/detail/config.hpp b/boost/process/detail/config.hpp index 2e280c1d53..e668811cd5 100644 --- a/boost/process/detail/config.hpp +++ b/boost/process/detail/config.hpp @@ -31,7 +31,7 @@ extern char **environ; #endif #elif defined(BOOST_WINDOWS_API) -#include <boost/detail/winapi/get_last_error.hpp> +#include <boost/winapi/get_last_error.hpp> #else #error "System API not supported by boost.process" #endif @@ -53,7 +53,7 @@ inline std::error_code get_last_error() noexcept } //copied from linux spec. -#if defined (__USE_XOPEN_EXTENDED) && !defined (__USE_XOPEN2K8) || defined( __USE_BSD) +#if (_XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && !(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) #define BOOST_POSIX_HAS_VFORK 1 #endif @@ -63,7 +63,7 @@ namespace api = windows; inline std::error_code get_last_error() noexcept { - return std::error_code(::boost::detail::winapi::GetLastError(), std::system_category()); + return std::error_code(::boost::winapi::GetLastError(), std::system_category()); } #endif @@ -72,6 +72,11 @@ inline void throw_last_error(const std::string & msg) throw process_error(get_last_error(), msg); } +inline void throw_last_error(const char * msg) +{ + throw process_error(get_last_error(), msg); +} + inline void throw_last_error() { throw process_error(get_last_error()); diff --git a/boost/process/detail/handler.hpp b/boost/process/detail/handler.hpp index 360c59f81a..1cc5d624b7 100644 --- a/boost/process/detail/handler.hpp +++ b/boost/process/detail/handler.hpp @@ -1,75 +1,75 @@ -// 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)
+// 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_HANDLER_HPP_
-#define BOOST_PROCESS_DETAIL_HANDLER_HPP_
+#ifndef BOOST_PROCESS_DETAIL_HANDLER_HPP_ +#define BOOST_PROCESS_DETAIL_HANDLER_HPP_ -#include <boost/process/detail/config.hpp>
+#include <boost/process/detail/config.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
+#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 -namespace boost { namespace process { namespace detail {
+namespace boost { namespace process { namespace detail { -//extended handler base.
-typedef api::handler_base_ext handler;
+//extended handler base. +typedef api::handler_base_ext handler; -template <class Handler>
-struct on_setup_ : handler
-{
- explicit on_setup_(Handler handler) : handler_(handler) {}
+template <class Handler> +struct on_setup_ : handler +{ + explicit on_setup_(Handler handler) : handler_(handler) {} - template <class Executor>
- void on_setup(Executor &e)
- {
- handler_(e);
- }
-private:
- Handler handler_;
-};
+ template <class Executor> + void on_setup(Executor &e) + { + handler_(e); + } +private: + Handler handler_; +}; -template <class Handler>
-struct on_error_ : handler
-{
- explicit on_error_(Handler handler) : handler_(handler) {}
+template <class Handler> +struct on_error_ : handler +{ + explicit on_error_(Handler handler) : handler_(handler) {} - template <class Executor>
- void on_error(Executor &e, const std::error_code &ec)
- {
- handler_(e, ec);
- }
-private:
- Handler handler_;
-};
+ template <class Executor> + void on_error(Executor &e, const std::error_code &ec) + { + handler_(e, ec); + } +private: + Handler handler_; +}; -template <class Handler>
-struct on_success_ : handler
-{
- explicit on_success_(Handler handler) : handler_(handler) {}
+template <class Handler> +struct on_success_ : handler +{ + explicit on_success_(Handler handler) : handler_(handler) {} - template <class Executor>
- void on_success(Executor &e)
- {
- handler_(e);
- }
-private:
- Handler handler_;
-};
+ template <class Executor> + void on_success(Executor &e) + { + handler_(e); + } +private: + Handler handler_; +}; -}
+} -}}
+}} -#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
+#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */ diff --git a/boost/process/detail/posix/asio_fwd.hpp b/boost/process/detail/posix/asio_fwd.hpp index 06d5c19214..faa7a9d7a2 100644 --- a/boost/process/detail/posix/asio_fwd.hpp +++ b/boost/process/detail/posix/asio_fwd.hpp @@ -20,34 +20,33 @@ template<typename Allocator> class basic_streambuf; typedef basic_streambuf<std::allocator<char>> streambuf; -class io_service; +class io_context; +#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) class signal_set_service; template <typename SignalSetService> class basic_signal_set; typedef basic_signal_set<signal_set_service> signal_set; +#else /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */ +class signal_set; +#endif /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */ template <typename Handler> class basic_yield_context; namespace posix { +#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) class stream_descriptor_service; template <typename StreamDesscriptorService> class basic_stream_descriptor; typedef basic_stream_descriptor<stream_descriptor_service> stream_descriptor; - - - -class object_handle_service; - -template <typename ObjectHandleService> -class basic_object_handle; - -typedef basic_object_handle<object_handle_service> object_handle; +#else /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */ +class stream_descriptor; +#endif /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */ } //posix } //asio diff --git a/boost/process/detail/posix/async_handler.hpp b/boost/process/detail/posix/async_handler.hpp index a61cff3372..e25860ad69 100644 --- a/boost/process/detail/posix/async_handler.hpp +++ b/boost/process/detail/posix/async_handler.hpp @@ -1,40 +1,40 @@ -// 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)
+// 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_POSIX_ASYNC_HANDLER_HPP_
-#define BOOST_PROCESS_POSIX_ASYNC_HANDLER_HPP_
+#ifndef BOOST_PROCESS_POSIX_ASYNC_HANDLER_HPP_ +#define BOOST_PROCESS_POSIX_ASYNC_HANDLER_HPP_ -#include <boost/process/detail/posix/handler.hpp>
-#include <type_traits>
+#include <boost/process/detail/posix/handler.hpp> +#include <type_traits> -namespace boost { namespace process { namespace detail { namespace posix {
+namespace boost { namespace process { namespace detail { namespace posix { -struct require_io_service {};
+struct require_io_context {}; -struct async_handler : handler_base_ext, require_io_service
-{
-};
+struct async_handler : handler_base_ext, require_io_context +{ +}; -template<typename T>
-struct is_async_handler : std::is_base_of<async_handler, T> {};
-template<typename T>
-struct is_async_handler<T&> : std::is_base_of<async_handler, T> {};
-template<typename T>
-struct is_async_handler<const T&> : std::is_base_of<async_handler, T> {};
+template<typename T> +struct is_async_handler : std::is_base_of<async_handler, T> {}; +template<typename T> +struct is_async_handler<T&> : std::is_base_of<async_handler, T> {}; +template<typename T> +struct is_async_handler<const T&> : std::is_base_of<async_handler, T> {}; -template<typename T>
-struct does_require_io_service : std::is_base_of<require_io_service, T> {};
+template<typename T> +struct does_require_io_context : std::is_base_of<require_io_context, T> {}; -template<typename T>
-struct does_require_io_service<T&> : std::is_base_of<require_io_service, T> {};
+template<typename T> +struct does_require_io_context<T&> : std::is_base_of<require_io_context, T> {}; -template<typename T>
-struct does_require_io_service<const T&> : std::is_base_of<require_io_service, T> {};
+template<typename T> +struct does_require_io_context<const T&> : std::is_base_of<require_io_context, T> {}; -}}}}
+}}}} -#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */
+#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */ diff --git a/boost/process/detail/posix/async_in.hpp b/boost/process/detail/posix/async_in.hpp index 9814c593f2..1c1e2f40fb 100644 --- a/boost/process/detail/posix/async_in.hpp +++ b/boost/process/detail/posix/async_in.hpp @@ -1,95 +1,95 @@ -// 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
-//
-// 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_POSIX_ASYNC_IN_HPP
-#define BOOST_PROCESS_DETAIL_POSIX_ASYNC_IN_HPP
- -#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/posix/async_handler.hpp>
-#include <boost/asio/write.hpp>
-#include <boost/process/async_pipe.hpp>
-#include <memory>
-#include <future>
- -namespace boost { namespace process { namespace detail { namespace posix {
- - -template<typename Buffer>
-struct async_in_buffer : ::boost::process::detail::posix::handler_base_ext,
- ::boost::process::detail::posix::require_io_service
-{
- Buffer & buf;
- - std::shared_ptr<std::promise<void>> promise;
- async_in_buffer operator>(std::future<void> & fut)
- {
- promise = std::make_shared<std::promise<void>>();
- fut = promise->get_future(); return std::move(*this);
- }
- - std::shared_ptr<boost::process::async_pipe> pipe;
- - async_in_buffer(Buffer & buf) : buf(buf)
- {
- }
- template <typename Executor>
- inline void on_success(Executor &exec)
- {
- auto pipe = this->pipe;
- if (this->promise)
- {
- auto promise = this->promise;
- - boost::asio::async_write(*pipe, buf,
- [pipe, promise](const boost::system::error_code & ec, std::size_t)
- {
- if (ec && (ec.value() != EBADF) && (ec.value() != EPERM) && (ec.value() != ENOENT))
- {
- std::error_code e(ec.value(), std::system_category());
- promise->set_exception(std::make_exception_ptr(process_error(e)));
- }
- else
- promise->set_value();
- });
- }
- else
- boost::asio::async_write(*pipe, buf,
- [pipe](const boost::system::error_code&ec, std::size_t size){});
- - std::move(*pipe).source().close();
- - this->pipe = nullptr;
- }
- - template<typename Executor>
- void on_error(Executor &, const std::error_code &) const
- {
- std::move(*pipe).source().close();
- }
- - template<typename Executor>
- void on_setup(Executor & exec)
- {
- pipe = std::make_shared<boost::process::async_pipe>(get_io_service(exec.seq));
- }
- - template <typename Executor>
- void on_exec_setup(Executor &exec)
- {
- if (::dup2(pipe->native_source(), STDIN_FILENO) == -1)
- exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- - ::close(pipe->native_source());
- }
-};
- - -}}}}
- -#endif
+// 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 +// +// 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_POSIX_ASYNC_IN_HPP +#define BOOST_PROCESS_DETAIL_POSIX_ASYNC_IN_HPP + +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/posix/async_handler.hpp> +#include <boost/asio/write.hpp> +#include <boost/process/async_pipe.hpp> +#include <memory> +#include <future> + +namespace boost { namespace process { namespace detail { namespace posix { + + +template<typename Buffer> +struct async_in_buffer : ::boost::process::detail::posix::handler_base_ext, + ::boost::process::detail::posix::require_io_context +{ + Buffer & buf; + + std::shared_ptr<std::promise<void>> promise; + async_in_buffer operator>(std::future<void> & fut) + { + promise = std::make_shared<std::promise<void>>(); + fut = promise->get_future(); return std::move(*this); + } + + std::shared_ptr<boost::process::async_pipe> pipe; + + async_in_buffer(Buffer & buf) : buf(buf) + { + } + template <typename Executor> + inline void on_success(Executor &exec) + { + auto pipe = this->pipe; + if (this->promise) + { + auto promise = this->promise; + + boost::asio::async_write(*pipe, buf, + [pipe, promise](const boost::system::error_code & ec, std::size_t) + { + if (ec && (ec.value() != EBADF) && (ec.value() != EPERM) && (ec.value() != ENOENT)) + { + std::error_code e(ec.value(), std::system_category()); + promise->set_exception(std::make_exception_ptr(process_error(e))); + } + else + promise->set_value(); + }); + } + else + boost::asio::async_write(*pipe, buf, + [pipe](const boost::system::error_code&ec, std::size_t size){}); + + std::move(*pipe).source().close(); + + this->pipe = nullptr; + } + + template<typename Executor> + void on_error(Executor &, const std::error_code &) const + { + std::move(*pipe).source().close(); + } + + template<typename Executor> + void on_setup(Executor & exec) + { + pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq)); + } + + template <typename Executor> + void on_exec_setup(Executor &exec) + { + if (::dup2(pipe->native_source(), STDIN_FILENO) == -1) + exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + + ::close(pipe->native_source()); + } +}; + + +}}}} + +#endif diff --git a/boost/process/detail/posix/async_out.hpp b/boost/process/detail/posix/async_out.hpp index b0f7876714..c448490e67 100644 --- a/boost/process/detail/posix/async_out.hpp +++ b/boost/process/detail/posix/async_out.hpp @@ -1,170 +1,170 @@ -// 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
-//
-// 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)
+// 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 +// +// 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_POSIX_ASYNC_OUT_HPP
-#define BOOST_PROCESS_DETAIL_POSIX_ASYNC_OUT_HPP
- - -#include <boost/process/detail/posix/handler.hpp>
-#include <boost/asio/posix/stream_descriptor.hpp>
-#include <boost/asio/read.hpp>
-#include <boost/process/async_pipe.hpp>
-#include <istream>
-#include <memory>
-#include <exception>
-#include <future>
- -namespace boost { namespace process { namespace detail { namespace posix {
- - -inline int apply_out_handles(int handle, std::integral_constant<int, 1>, std::integral_constant<int, -1>)
-{
- return ::dup2(handle, STDOUT_FILENO);
-}
- -inline int apply_out_handles(int handle, std::integral_constant<int, 2>, std::integral_constant<int, -1>)
-{
- return ::dup2(handle, STDERR_FILENO);
-}
- -inline int apply_out_handles(int handle, std::integral_constant<int, 1>, std::integral_constant<int, 2>)
-{
- if (::dup2(handle, STDOUT_FILENO) == -1)
- return -1;
- if (::dup2(handle, STDERR_FILENO) == -1)
- return -1;
- - return 0;
-}
- -template<int p1, int p2, typename Buffer>
-struct async_out_buffer : ::boost::process::detail::posix::handler_base_ext,
- ::boost::process::detail::posix::require_io_service
-{
- Buffer & buf;
- - std::shared_ptr<boost::process::async_pipe> pipe;
- - - async_out_buffer(Buffer & buf) : buf(buf)
- {
- }
- - template <typename Executor>
- inline void on_success(Executor &exec)
- {
- auto pipe = this->pipe;
- boost::asio::async_read(*pipe, buf,
- [pipe](const boost::system::error_code&, std::size_t size){});
- - this->pipe = nullptr;
- std::move(*pipe).sink().close();
- }
- - template<typename Executor>
- void on_error(Executor &, const std::error_code &) const
- {
- std::move(*pipe).sink().close();
- }
- - template<typename Executor>
- void on_setup(Executor & exec)
- {
- pipe = std::make_shared<boost::process::async_pipe>(get_io_service(exec.seq));
- }
- - - template <typename Executor>
- void on_exec_setup(Executor &exec)
- {
- int res = apply_out_handles(pipe->native_sink(),
- std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
- if (res == -1)
- exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- - ::close(pipe->native_sink());
- }
-};
- - - - -template<int p1, int p2, typename Type>
-struct async_out_future : ::boost::process::detail::posix::handler_base_ext,
- ::boost::process::detail::posix::require_io_service
-{
- std::shared_ptr<std::promise<Type>> promise = std::make_shared<std::promise<Type>>();
- - std::shared_ptr<boost::asio::streambuf> buffer = std::make_shared<boost::asio::streambuf>();
- - std::shared_ptr<boost::process::async_pipe> pipe;
- - async_out_future(std::future<Type> & fut)
- {
- fut = promise->get_future();
- }
- template <typename Executor>
- inline void on_success(Executor &exec)
- {
- auto pipe = this->pipe;
- - auto buffer = this->buffer;
- auto promise = this->promise;
- - boost::asio::async_read(*pipe, *buffer,
- [pipe, buffer, promise](const boost::system::error_code& ec, std::size_t size)
- {
- if (ec && (ec.value() != ENOENT))
- {
- std::error_code e(ec.value(), std::system_category());
- promise->set_exception(std::make_exception_ptr(process_error(e)));
- }
- else
- {
- std::istream is (buffer.get());
- Type arg;
- arg.resize(buffer->size());
- is.read(&*arg.begin(), buffer->size());
- promise->set_value(std::move(arg));
- }
- });
- - std::move(*pipe).sink().close();
- this->pipe = nullptr;
- }
- - template<typename Executor>
- void on_error(Executor &, const std::error_code &) const
- {
- std::move(*pipe).sink().close();
- }
- - template<typename Executor>
- void on_setup(Executor & exec)
- {
- pipe = std::make_shared<boost::process::async_pipe>(get_io_service(exec.seq));
- }
- - template <typename Executor>
- void on_exec_setup(Executor &exec)
- {
- - int res = apply_out_handles(pipe->native_sink(),
- std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
- if (res == -1)
- exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- - ::close(pipe->native_sink());
- }
- -};
- -}}}}
- -#endif
+#ifndef BOOST_PROCESS_DETAIL_POSIX_ASYNC_OUT_HPP +#define BOOST_PROCESS_DETAIL_POSIX_ASYNC_OUT_HPP + + +#include <boost/process/detail/posix/handler.hpp> +#include <boost/asio/posix/stream_descriptor.hpp> +#include <boost/asio/read.hpp> +#include <boost/process/async_pipe.hpp> +#include <istream> +#include <memory> +#include <exception> +#include <future> + +namespace boost { namespace process { namespace detail { namespace posix { + + +inline int apply_out_handles(int handle, std::integral_constant<int, 1>, std::integral_constant<int, -1>) +{ + return ::dup2(handle, STDOUT_FILENO); +} + +inline int apply_out_handles(int handle, std::integral_constant<int, 2>, std::integral_constant<int, -1>) +{ + return ::dup2(handle, STDERR_FILENO); +} + +inline int apply_out_handles(int handle, std::integral_constant<int, 1>, std::integral_constant<int, 2>) +{ + if (::dup2(handle, STDOUT_FILENO) == -1) + return -1; + if (::dup2(handle, STDERR_FILENO) == -1) + return -1; + + return 0; +} + +template<int p1, int p2, typename Buffer> +struct async_out_buffer : ::boost::process::detail::posix::handler_base_ext, + ::boost::process::detail::posix::require_io_context +{ + Buffer & buf; + + std::shared_ptr<boost::process::async_pipe> pipe; + + + async_out_buffer(Buffer & buf) : buf(buf) + { + } + + template <typename Executor> + inline void on_success(Executor &exec) + { + auto pipe = this->pipe; + boost::asio::async_read(*pipe, buf, + [pipe](const boost::system::error_code&, std::size_t size){}); + + this->pipe = nullptr; + std::move(*pipe).sink().close(); + } + + template<typename Executor> + void on_error(Executor &, const std::error_code &) const + { + std::move(*pipe).sink().close(); + } + + template<typename Executor> + void on_setup(Executor & exec) + { + pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq)); + } + + + template <typename Executor> + void on_exec_setup(Executor &exec) + { + int res = apply_out_handles(pipe->native_sink(), + std::integral_constant<int, p1>(), std::integral_constant<int, p2>()); + if (res == -1) + exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + + ::close(pipe->native_sink()); + } +}; + + + + +template<int p1, int p2, typename Type> +struct async_out_future : ::boost::process::detail::posix::handler_base_ext, + ::boost::process::detail::posix::require_io_context +{ + std::shared_ptr<std::promise<Type>> promise = std::make_shared<std::promise<Type>>(); + + std::shared_ptr<boost::asio::streambuf> buffer = std::make_shared<boost::asio::streambuf>(); + + std::shared_ptr<boost::process::async_pipe> pipe; + + async_out_future(std::future<Type> & fut) + { + fut = promise->get_future(); + } + template <typename Executor> + inline void on_success(Executor &exec) + { + auto pipe = this->pipe; + + auto buffer = this->buffer; + auto promise = this->promise; + + boost::asio::async_read(*pipe, *buffer, + [pipe, buffer, promise](const boost::system::error_code& ec, std::size_t size) + { + if (ec && (ec.value() != ENOENT)) + { + std::error_code e(ec.value(), std::system_category()); + promise->set_exception(std::make_exception_ptr(process_error(e))); + } + else + { + std::istream is (buffer.get()); + Type arg; + arg.resize(buffer->size()); + is.read(&*arg.begin(), buffer->size()); + promise->set_value(std::move(arg)); + } + }); + + std::move(*pipe).sink().close(); + this->pipe = nullptr; + } + + template<typename Executor> + void on_error(Executor &, const std::error_code &) const + { + std::move(*pipe).sink().close(); + } + + template<typename Executor> + void on_setup(Executor & exec) + { + pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq)); + } + + template <typename Executor> + void on_exec_setup(Executor &exec) + { + + int res = apply_out_handles(pipe->native_sink(), + std::integral_constant<int, p1>(), std::integral_constant<int, p2>()); + if (res == -1) + exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + + ::close(pipe->native_sink()); + } + +}; + +}}}} + +#endif diff --git a/boost/process/detail/posix/async_pipe.hpp b/boost/process/detail/posix/async_pipe.hpp index d849559c20..8f138bdfa3 100644 --- a/boost/process/detail/posix/async_pipe.hpp +++ b/boost/process/detail/posix/async_pipe.hpp @@ -11,6 +11,7 @@ #include <boost/asio/posix/stream_descriptor.hpp> #include <system_error> #include <string> +#include <utility> namespace boost { namespace process { namespace detail { namespace posix { @@ -22,10 +23,10 @@ public: typedef int native_handle_type; typedef ::boost::asio::posix::stream_descriptor handle_type; - inline async_pipe(boost::asio::io_service & ios) : async_pipe(ios, ios) {} + inline async_pipe(boost::asio::io_context & ios) : async_pipe(ios, ios) {} - inline async_pipe(boost::asio::io_service & ios_source, - boost::asio::io_service & ios_sink) : _source(ios_source), _sink(ios_sink) + inline async_pipe(boost::asio::io_context & ios_source, + boost::asio::io_context & ios_sink) : _source(ios_source), _sink(ios_sink) { int fds[2]; if (::pipe(fds) == -1) @@ -34,11 +35,11 @@ public: _source.assign(fds[0]); _sink .assign(fds[1]); }; - inline async_pipe(boost::asio::io_service & ios, const std::string & name) + inline async_pipe(boost::asio::io_context & ios, const std::string & name) : async_pipe(ios, ios, name) {} - inline async_pipe(boost::asio::io_service & ios_source, - boost::asio::io_service & io_sink, const std::string & name); + inline async_pipe(boost::asio::io_context & ios_source, + boost::asio::io_context & io_sink, const std::string & name); inline async_pipe(const async_pipe& lhs); async_pipe(async_pipe&& lhs) : _source(std::move(lhs._source)), _sink(std::move(lhs._sink)) { @@ -47,15 +48,15 @@ public: } template<class CharT, class Traits = std::char_traits<CharT>> - explicit async_pipe(::boost::asio::io_service & ios_source, - ::boost::asio::io_service & ios_sink, + explicit async_pipe(::boost::asio::io_context & ios_source, + ::boost::asio::io_context & ios_sink, const basic_pipe<CharT, Traits> & p) : _source(ios_source, p.native_source()), _sink(ios_sink, p.native_sink()) { } template<class CharT, class Traits = std::char_traits<CharT>> - explicit async_pipe(boost::asio::io_service & ios, const basic_pipe<CharT, Traits> & p) + explicit async_pipe(boost::asio::io_context & ios, const basic_pipe<CharT, Traits> & p) : async_pipe(ios, ios, p) { } @@ -68,10 +69,10 @@ public: ~async_pipe() { - if (_sink .native() != -1) - ::close(_sink.native()); - if (_source.native() != -1) - ::close(_source.native()); + if (_sink .native_handle() != -1) + ::close(_sink.native_handle()); + if (_source.native_handle() != -1) + ::close(_source.native_handle()); } template<class CharT, class Traits = std::char_traits<CharT>> @@ -108,9 +109,9 @@ public: void async_close() { if (_sink.is_open()) - _sink.get_io_service(). post([this]{_sink.close();}); + _sink.get_io_context(). post([this]{_sink.close();}); if (_source.is_open()) - _source.get_io_service().post([this]{_source.close();}); + _source.get_io_context().post([this]{_source.close();}); } template<typename MutableBufferSequence> @@ -124,8 +125,8 @@ public: return _sink.write_some(buffers); } - native_handle_type native_source() const {return const_cast<boost::asio::posix::stream_descriptor&>(_source).native();} - native_handle_type native_sink () const {return const_cast<boost::asio::posix::stream_descriptor&>(_sink ).native();} + native_handle_type native_source() const {return const_cast<boost::asio::posix::stream_descriptor&>(_source).native_handle();} + native_handle_type native_sink () const {return const_cast<boost::asio::posix::stream_descriptor&>(_sink ).native_handle();} template<typename MutableBufferSequence, typename ReadHandler> @@ -156,32 +157,32 @@ public: handle_type && sink() && { return std::move(_sink); } handle_type && source()&& { return std::move(_source); } - handle_type source(::boost::asio::io_service& ios) && + handle_type source(::boost::asio::io_context& ios) && { ::boost::asio::posix::stream_descriptor stolen(ios, _source.release()); return stolen; } - handle_type sink (::boost::asio::io_service& ios) && + handle_type sink (::boost::asio::io_context& ios) && { ::boost::asio::posix::stream_descriptor stolen(ios, _sink.release()); return stolen; } - handle_type source(::boost::asio::io_service& ios) const & + handle_type source(::boost::asio::io_context& ios) const & { - auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native(); + auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native_handle(); return ::boost::asio::posix::stream_descriptor(ios, ::dup(source_in)); } - handle_type sink (::boost::asio::io_service& ios) const & + handle_type sink (::boost::asio::io_context& ios) const & { - auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native(); + auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native_handle(); return ::boost::asio::posix::stream_descriptor(ios, ::dup(sink_in)); } }; -async_pipe::async_pipe(boost::asio::io_service & ios_source, - boost::asio::io_service & ios_sink, +async_pipe::async_pipe(boost::asio::io_context & ios_source, + boost::asio::io_context & ios_sink, const std::string & name) : _source(ios_source), _sink(ios_sink) { auto fifo = mkfifo(name.c_str(), 0666 ); @@ -205,19 +206,19 @@ async_pipe::async_pipe(boost::asio::io_service & ios_source, } async_pipe::async_pipe(const async_pipe & p) : - _source(const_cast<async_pipe&>(p)._source.get_io_service()), - _sink( const_cast<async_pipe&>(p)._sink.get_io_service()) + _source(const_cast<async_pipe&>(p)._source.get_io_context()), + _sink( const_cast<async_pipe&>(p)._sink.get_io_context()) { //cannot get the handle from a const object. - auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native(); - auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native(); + auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native_handle(); + auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native_handle(); if (source_in == -1) _source.assign(-1); else { _source.assign(::dup(source_in)); - if (_source.native()== -1) + if (_source.native_handle()== -1) ::boost::process::detail::throw_last_error("dup()"); } @@ -226,7 +227,7 @@ async_pipe::async_pipe(const async_pipe & p) : else { _sink.assign(::dup(sink_in)); - if (_sink.native() == -1) + if (_sink.native_handle() == -1) ::boost::process::detail::throw_last_error("dup()"); } } @@ -237,8 +238,8 @@ async_pipe& async_pipe::operator=(const async_pipe & p) int sink; //cannot get the handle from a const object. - auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native(); - auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native(); + auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native_handle(); + auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native_handle(); if (source_in == -1) source = -1; else @@ -264,16 +265,8 @@ async_pipe& async_pipe::operator=(const async_pipe & p) async_pipe& async_pipe::operator=(async_pipe && lhs) { - if (_source.native_handle() == -1) - ::close(_source.native()); - - if (_sink.native_handle() == -1) - ::close(_sink.native()); - - _source.assign(lhs._source.native_handle()); - _sink .assign(lhs._sink .native_handle()); - lhs._source.assign(-1); - lhs._sink .assign(-1); + std::swap(_source, lhs._source); + std::swap(_sink, lhs._sink); return *this; } @@ -284,8 +277,8 @@ async_pipe::operator basic_pipe<CharT, Traits>() const int sink; //cannot get the handle from a const object. - auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native(); - auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native(); + auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native_handle(); + auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native_handle(); if (source_in == -1) diff --git a/boost/process/detail/posix/basic_pipe.hpp b/boost/process/detail/posix/basic_pipe.hpp index 77fc90a4c1..14d140f1cc 100644 --- a/boost/process/detail/posix/basic_pipe.hpp +++ b/boost/process/detail/posix/basic_pipe.hpp @@ -29,7 +29,7 @@ class basic_pipe int _sink = -1; public: explicit basic_pipe(int source, int sink) : _source(source), _sink(sink) {} - explicit basic_pipe(int source, int sink, const std::string & name) : _source(source), _sink(sink) {} + explicit basic_pipe(int source, int sink, const std::string&) : _source(source), _sink(sink) {} typedef CharT char_type ; typedef Traits traits_type; typedef typename Traits::int_type int_type ; @@ -105,8 +105,10 @@ public: void close() { - ::close(_source); - ::close(_sink); + if (_source != -1) + ::close(_source); + if (_sink != -1) + ::close(_sink); _source = -1; _sink = -1; } diff --git a/boost/process/detail/posix/child_handle.hpp b/boost/process/detail/posix/child_handle.hpp index 44ec43ea68..8ce246d00a 100644 --- a/boost/process/detail/posix/child_handle.hpp +++ b/boost/process/detail/posix/child_handle.hpp @@ -44,7 +44,7 @@ struct child_handle return pid; } bool in_group() const {return true;} - bool in_group(std::error_code &ec) const noexcept {return true;} + bool in_group(std::error_code&) const noexcept {return true;} typedef int process_handle_t; process_handle_t process_handle() const { return pid; } diff --git a/boost/process/detail/posix/environment.hpp b/boost/process/detail/posix/environment.hpp index 1011c03a9d..58334741ae 100644 --- a/boost/process/detail/posix/environment.hpp +++ b/boost/process/detail/posix/environment.hpp @@ -1,322 +1,322 @@ -// 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_POSIX_ENVIRONMENT_HPP_
-#define BOOST_PROCESS_DETAIL_POSIX_ENVIRONMENT_HPP_
- -#include <string>
-#include <vector>
-#include <unordered_map>
-#include <boost/process/detail/config.hpp>
-#include <algorithm>
-#include <cstdlib>
-#include <boost/process/locale.hpp>
- - -namespace boost { namespace process { namespace detail { namespace posix {
- -template<typename Char>
-class native_environment_impl
-{
- static std::vector<std::basic_string<Char>> _load()
- {
- std::vector<std::basic_string<Char>> val;
- auto p = environ;
- while (*p != nullptr)
- {
- std::string str = *p;
- val.push_back(::boost::process::detail::convert(str));
- p++;
- }
- return val;
- }
- static std::vector<Char*> _load_var(std::vector<std::basic_string<Char>> & vec)
- {
- std::vector<Char*> val;
- val.resize(vec.size() + 1);
- std::transform(vec.begin(), vec.end(), val.begin(),
- [](std::basic_string<Char> & str)
- {
- return &str.front();
- });
- val.back() = nullptr;
- return val;
- }
- std::vector<std::basic_string<Char>> _buffer = _load();
- std::vector<Char*> _impl = _load_var(_buffer);
-public:
- using char_type = Char;
- using pointer_type = const char_type*;
- using string_type = std::basic_string<char_type>;
- using native_handle_type = char_type **;
- - void reload()
- {
- _buffer = _load();
- _impl = _load_var(_buffer);
- }
- - string_type get(const pointer_type id) { return get(string_type(id)); }
- void set(const pointer_type id, const pointer_type value)
- {
- set(string_type(id), string_type(value));
- }
- void reset(const pointer_type id) { reset(string_type(id)); }
- - string_type get(const string_type & id)
- {
- std::string id_c = ::boost::process::detail::convert(id);
- std::string g = ::getenv(id_c.c_str());
- return ::boost::process::detail::convert(g.c_str());
- }
- void set(const string_type & id, const string_type & value)
- {
- std::string id_c = ::boost::process::detail::convert(id.c_str());
- std::string value_c = ::boost::process::detail::convert(value.c_str());
- auto res = ::setenv(id_c.c_str(), value_c.c_str(), true);
- if (res != 0)
- boost::process::detail::throw_last_error();
- }
- void reset(const string_type & id)
- {
- std::string id_c = ::boost::process::detail::convert(id.c_str());
- auto res = ::unsetenv(id_c.c_str());
- if (res != 0)
- ::boost::process::detail::throw_last_error();
- }
- - native_environment_impl() = default;
- native_environment_impl(const native_environment_impl& ) = delete;
- native_environment_impl(native_environment_impl && ) = default;
- native_environment_impl & operator=(const native_environment_impl& ) = delete;
- native_environment_impl & operator=(native_environment_impl && ) = default;
- native_handle_type _env_impl = _impl.data();
- - native_handle_type native_handle() const {return environ;}
-};
- -template<>
-class native_environment_impl<char>
-{
-public:
- using char_type = char;
- using pointer_type = const char_type*;
- using string_type = std::basic_string<char_type>;
- using native_handle_type = char_type **;
- - void reload() {this->_env_impl = ::environ;}
- - string_type get(const pointer_type id) { return getenv(id); }
- void set(const pointer_type id, const pointer_type value)
- {
- auto res = ::setenv(id, value, 1);
- if (res != 0)
- boost::process::detail::throw_last_error();
- reload();
- }
- void reset(const pointer_type id)
- {
- auto res = ::unsetenv(id);
- if (res != 0)
- boost::process::detail::throw_last_error();
- reload();
- }
- - string_type get(const string_type & id) {return get(id.c_str());}
- void set(const string_type & id, const string_type & value) {set(id.c_str(), value.c_str()); }
- void reset(const string_type & id) {reset(id.c_str());}
- - native_environment_impl() = default;
- native_environment_impl(const native_environment_impl& ) = delete;
- native_environment_impl(native_environment_impl && ) = default;
- native_environment_impl & operator=(const native_environment_impl& ) = delete;
- native_environment_impl & operator=(native_environment_impl && ) = default;
- native_handle_type _env_impl = environ;
- - native_handle_type native_handle() const {return ::environ;}
-};
- - - -template<typename Char>
-struct basic_environment_impl
-{
- std::vector<std::basic_string<Char>> _data {};
- static std::vector<Char*> _load_var(std::vector<std::basic_string<Char>> & data);
- std::vector<Char*> _env_arr{_load_var(_data)};
-public:
- using char_type = Char;
- using pointer_type = const char_type*;
- using string_type = std::basic_string<char_type>;
- using native_handle_type = Char**;
- void reload()
- {
- _env_arr = _load_var(_data);
- _env_impl = _env_arr.data();
- }
- - string_type get(const pointer_type id) {return get(string_type(id));}
- void set(const pointer_type id, const pointer_type value) {set(string_type(id), value);}
- void reset(const pointer_type id) {reset(string_type(id));}
- - string_type get(const string_type & id);
- void set(const string_type & id, const string_type & value);
- void reset(const string_type & id);
- - basic_environment_impl(const native_environment_impl<Char> & nei);
- basic_environment_impl() = default;
- basic_environment_impl(const basic_environment_impl& rhs)
- : _data(rhs._data)
- {
- - }
- basic_environment_impl(basic_environment_impl && ) = default;
- basic_environment_impl & operator=(const basic_environment_impl& rhs)
- {
- _data = rhs._data;
- _env_arr = _load_var(_data);
- _env_impl = &*_env_arr.begin();
- return *this;
- }
- basic_environment_impl & operator=(basic_environment_impl && ) = default;
- - template<typename CharR>
- explicit inline basic_environment_impl(
- const basic_environment_impl<CharR>& rhs,
- const ::boost::process::codecvt_type & cv = ::boost::process::codecvt())
- : _data(rhs._data.size())
- {
- std::transform(rhs._data.begin(), rhs._data.end(), _data.begin(),
- [&](const std::basic_string<CharR> & st)
- {
- return ::boost::process::detail::convert(st, cv);
- }
- - );
- reload();
- }
- - template<typename CharR>
- basic_environment_impl & operator=(const basic_environment_impl<CharR>& rhs)
- {
- _data = ::boost::process::detail::convert(rhs._data);
- _env_arr = _load_var(&*_data.begin());
- _env_impl = &*_env_arr.begin();
- return *this;
- }
- - Char ** _env_impl = &*_env_arr.data();
- - native_handle_type native_handle() const {return &_data.front();}
-};
- - -template<typename Char>
-basic_environment_impl<Char>::basic_environment_impl(const native_environment_impl<Char> & nei)
-{
- auto beg = nei.native_handle();
- - auto end = beg;
- while (*end != nullptr)
- end++;
- this->_data.assign(beg, end);
- reload();
-}
- - -template<typename Char>
-inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_type
-{
- auto itr = std::find_if(_data.begin(), _data.end(),
- [&](const string_type & st)
- {
- if (st.size() <= id.size())
- return false;
- return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>());
- }
- );
- - if (itr == _data.end())
- {
- return "";
- }
- else return
- itr->data() + id.size(); //id=Thingy -> +2 points to T
-}
- -template<typename Char>
-inline void basic_environment_impl<Char>::set(const string_type &id, const string_type &value)
-{
- auto itr = std::find_if(_data.begin(), _data.end(),
- [&](const string_type & st)
- {
- if (st.size() <= id.size())
- return false;
- return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>());
- }
- );
- - if (itr != _data.end())
- *itr = id + equal_sign<Char>() + value;
- else
- _data.push_back(id + equal_sign<Char>() + value);
- - reload();
-}
- -template<typename Char>
-inline void basic_environment_impl<Char>::reset(const string_type &id)
-{
- auto itr = std::find_if(_data.begin(), _data.end(),
- [&](const string_type & st)
- {
- if (st.size() <= id.size())
- return false;
- return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>());
- }
- );
- if (itr != _data.end())
- {
- _data.erase(itr);//and remove it
- }
-
- reload();
- - -}
- -template<typename Char>
-std::vector<Char*> basic_environment_impl<Char>::_load_var(std::vector<std::basic_string<Char>> & data)
-{
- std::vector<Char*> ret;
- ret.reserve(data.size() +1);
- - for (auto & val : data)
- ret.push_back(&val.front());
- - ret.push_back(nullptr);
- return ret;
-}
- -template<typename T> constexpr T env_seperator();
-template<> constexpr char env_seperator() {return ':'; }
-template<> constexpr wchar_t env_seperator() {return L':'; }
- - -typedef int native_handle_t;
- -inline int get_id() {return getpid(); }
-inline int native_handle() {return getpid(); }
- -}
- -}
-}
-}
- - - - -#endif /* BOOST_PROCESS_DETAIL_WINDOWS_ENV_STORAGE_HPP_ */
+// 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_POSIX_ENVIRONMENT_HPP_ +#define BOOST_PROCESS_DETAIL_POSIX_ENVIRONMENT_HPP_ + +#include <string> +#include <vector> +#include <unordered_map> +#include <boost/process/detail/config.hpp> +#include <algorithm> +#include <cstdlib> +#include <boost/process/locale.hpp> + + +namespace boost { namespace process { namespace detail { namespace posix { + +template<typename Char> +class native_environment_impl +{ + static std::vector<std::basic_string<Char>> _load() + { + std::vector<std::basic_string<Char>> val; + auto p = environ; + while (*p != nullptr) + { + std::string str = *p; + val.push_back(::boost::process::detail::convert(str)); + p++; + } + return val; + } + static std::vector<Char*> _load_var(std::vector<std::basic_string<Char>> & vec) + { + std::vector<Char*> val; + val.resize(vec.size() + 1); + std::transform(vec.begin(), vec.end(), val.begin(), + [](std::basic_string<Char> & str) + { + return &str.front(); + }); + val.back() = nullptr; + return val; + } + std::vector<std::basic_string<Char>> _buffer = _load(); + std::vector<Char*> _impl = _load_var(_buffer); +public: + using char_type = Char; + using pointer_type = const char_type*; + using string_type = std::basic_string<char_type>; + using native_handle_type = char_type **; + + void reload() + { + _buffer = _load(); + _impl = _load_var(_buffer); + } + + string_type get(const pointer_type id) { return get(string_type(id)); } + void set(const pointer_type id, const pointer_type value) + { + set(string_type(id), string_type(value)); + } + void reset(const pointer_type id) { reset(string_type(id)); } + + string_type get(const string_type & id) + { + std::string id_c = ::boost::process::detail::convert(id); + std::string g = ::getenv(id_c.c_str()); + return ::boost::process::detail::convert(g.c_str()); + } + void set(const string_type & id, const string_type & value) + { + std::string id_c = ::boost::process::detail::convert(id.c_str()); + std::string value_c = ::boost::process::detail::convert(value.c_str()); + auto res = ::setenv(id_c.c_str(), value_c.c_str(), true); + if (res != 0) + boost::process::detail::throw_last_error(); + } + void reset(const string_type & id) + { + std::string id_c = ::boost::process::detail::convert(id.c_str()); + auto res = ::unsetenv(id_c.c_str()); + if (res != 0) + ::boost::process::detail::throw_last_error(); + } + + native_environment_impl() = default; + native_environment_impl(const native_environment_impl& ) = delete; + native_environment_impl(native_environment_impl && ) = default; + native_environment_impl & operator=(const native_environment_impl& ) = delete; + native_environment_impl & operator=(native_environment_impl && ) = default; + native_handle_type _env_impl = _impl.data(); + + native_handle_type native_handle() const {return environ;} +}; + +template<> +class native_environment_impl<char> +{ +public: + using char_type = char; + using pointer_type = const char_type*; + using string_type = std::basic_string<char_type>; + using native_handle_type = char_type **; + + void reload() {this->_env_impl = ::environ;} + + string_type get(const pointer_type id) { return getenv(id); } + void set(const pointer_type id, const pointer_type value) + { + auto res = ::setenv(id, value, 1); + if (res != 0) + boost::process::detail::throw_last_error(); + reload(); + } + void reset(const pointer_type id) + { + auto res = ::unsetenv(id); + if (res != 0) + boost::process::detail::throw_last_error(); + reload(); + } + + string_type get(const string_type & id) {return get(id.c_str());} + void set(const string_type & id, const string_type & value) {set(id.c_str(), value.c_str()); } + void reset(const string_type & id) {reset(id.c_str());} + + native_environment_impl() = default; + native_environment_impl(const native_environment_impl& ) = delete; + native_environment_impl(native_environment_impl && ) = default; + native_environment_impl & operator=(const native_environment_impl& ) = delete; + native_environment_impl & operator=(native_environment_impl && ) = default; + native_handle_type _env_impl = environ; + + native_handle_type native_handle() const {return ::environ;} +}; + + + +template<typename Char> +struct basic_environment_impl +{ + std::vector<std::basic_string<Char>> _data {}; + static std::vector<Char*> _load_var(std::vector<std::basic_string<Char>> & data); + std::vector<Char*> _env_arr{_load_var(_data)}; +public: + using char_type = Char; + using pointer_type = const char_type*; + using string_type = std::basic_string<char_type>; + using native_handle_type = Char**; + void reload() + { + _env_arr = _load_var(_data); + _env_impl = _env_arr.data(); + } + + string_type get(const pointer_type id) {return get(string_type(id));} + void set(const pointer_type id, const pointer_type value) {set(string_type(id), value);} + void reset(const pointer_type id) {reset(string_type(id));} + + string_type get(const string_type & id); + void set(const string_type & id, const string_type & value); + void reset(const string_type & id); + + basic_environment_impl(const native_environment_impl<Char> & nei); + basic_environment_impl() = default; + basic_environment_impl(const basic_environment_impl& rhs) + : _data(rhs._data) + { + + } + basic_environment_impl(basic_environment_impl && ) = default; + basic_environment_impl & operator=(const basic_environment_impl& rhs) + { + _data = rhs._data; + _env_arr = _load_var(_data); + _env_impl = &*_env_arr.begin(); + return *this; + } + basic_environment_impl & operator=(basic_environment_impl && ) = default; + + template<typename CharR> + explicit inline basic_environment_impl( + const basic_environment_impl<CharR>& rhs, + const ::boost::process::codecvt_type & cv = ::boost::process::codecvt()) + : _data(rhs._data.size()) + { + std::transform(rhs._data.begin(), rhs._data.end(), _data.begin(), + [&](const std::basic_string<CharR> & st) + { + return ::boost::process::detail::convert(st, cv); + } + + ); + reload(); + } + + template<typename CharR> + basic_environment_impl & operator=(const basic_environment_impl<CharR>& rhs) + { + _data = ::boost::process::detail::convert(rhs._data); + _env_arr = _load_var(&*_data.begin()); + _env_impl = &*_env_arr.begin(); + return *this; + } + + Char ** _env_impl = &*_env_arr.data(); + + native_handle_type native_handle() const {return &_data.front();} +}; + + +template<typename Char> +basic_environment_impl<Char>::basic_environment_impl(const native_environment_impl<Char> & nei) +{ + auto beg = nei.native_handle(); + + auto end = beg; + while (*end != nullptr) + end++; + this->_data.assign(beg, end); + reload(); +} + + +template<typename Char> +inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_type +{ + auto itr = std::find_if(_data.begin(), _data.end(), + [&](const string_type & st) + { + if (st.size() <= id.size()) + return false; + return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>()); + } + ); + + if (itr == _data.end()) + { + return ""; + } + else return + itr->data() + id.size(); //id=Thingy -> +2 points to T +} + +template<typename Char> +inline void basic_environment_impl<Char>::set(const string_type &id, const string_type &value) +{ + auto itr = std::find_if(_data.begin(), _data.end(), + [&](const string_type & st) + { + if (st.size() <= id.size()) + return false; + return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>()); + } + ); + + if (itr != _data.end()) + *itr = id + equal_sign<Char>() + value; + else + _data.push_back(id + equal_sign<Char>() + value); + + reload(); +} + +template<typename Char> +inline void basic_environment_impl<Char>::reset(const string_type &id) +{ + auto itr = std::find_if(_data.begin(), _data.end(), + [&](const string_type & st) + { + if (st.size() <= id.size()) + return false; + return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>()); + } + ); + if (itr != _data.end()) + { + _data.erase(itr);//and remove it + } + + reload(); + + +} + +template<typename Char> +std::vector<Char*> basic_environment_impl<Char>::_load_var(std::vector<std::basic_string<Char>> & data) +{ + std::vector<Char*> ret; + ret.reserve(data.size() +1); + + for (auto & val : data) + ret.push_back(&val.front()); + + ret.push_back(nullptr); + return ret; +} + +template<typename T> constexpr T env_seperator(); +template<> constexpr char env_seperator() {return ':'; } +template<> constexpr wchar_t env_seperator() {return L':'; } + + +typedef int native_handle_t; + +inline int get_id() {return getpid(); } +inline int native_handle() {return getpid(); } + +} + +} +} +} + + + + +#endif /* BOOST_PROCESS_DETAIL_WINDOWS_ENV_STORAGE_HPP_ */ diff --git a/boost/process/detail/posix/executor.hpp b/boost/process/detail/posix/executor.hpp index 5d03fd184e..b3781f2f04 100644 --- a/boost/process/detail/posix/executor.hpp +++ b/boost/process/detail/posix/executor.hpp @@ -180,7 +180,7 @@ template<typename Sequence> class executor { template<typename HasHandler, typename UseVFork> - void internal_error_handle(const std::error_code &ec, const char* msg, HasHandler, boost::mpl::true_, UseVFork) {} + void internal_error_handle(const std::error_code&, const char*, HasHandler, boost::mpl::true_, UseVFork) {} int _pipe_sink = -1; @@ -233,7 +233,8 @@ class executor void check_error(boost::mpl::true_) {}; void check_error(boost::mpl::false_) { - throw process_error(_ec, _msg); + if (_ec) + throw process_error(_ec, _msg); } typedef typename ::boost::process::detail::has_error_handler<Sequence>::type has_error_handler; diff --git a/boost/process/detail/posix/file_descriptor.hpp b/boost/process/detail/posix/file_descriptor.hpp index 72552444b0..0dcb99caf8 100644 --- a/boost/process/detail/posix/file_descriptor.hpp +++ b/boost/process/detail/posix/file_descriptor.hpp @@ -1,76 +1,76 @@ -// 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_POSIX_FILE_DESCRIPTOR_HPP_
-#define BOOST_PROCESS_DETAIL_POSIX_FILE_DESCRIPTOR_HPP_
- -#include <fcntl.h>
-#include <string>
-#include <boost/filesystem/path.hpp>
- -namespace boost { namespace process { namespace detail { namespace posix {
- -struct file_descriptor
-{
- enum mode_t
- {
- read = 1,
- write = 2,
- read_write = 3
- };
- - - file_descriptor() = default;
- explicit file_descriptor(const boost::filesystem::path& p, mode_t mode = read_write)
- : file_descriptor(p.native(), mode)
- {
- }
- - explicit file_descriptor(const std::string & path , mode_t mode = read_write)
- : file_descriptor(path.c_str(), mode) {}
- - - explicit file_descriptor(const char* path, mode_t mode = read_write)
- : _handle(create_file(path, mode))
- {
- - }
- - file_descriptor(const file_descriptor & ) = delete;
- file_descriptor(file_descriptor && ) = default;
- - file_descriptor& operator=(const file_descriptor & ) = delete;
- file_descriptor& operator=(file_descriptor && ) = default;
- - ~file_descriptor()
- {
- if (_handle != -1)
- ::close(_handle);
- }
- - int handle() const { return _handle;}
- -private:
- static int create_file(const char* name, mode_t mode )
- {
- switch(mode)
- {
- case read:
- return ::open(name, O_RDONLY);
- case write:
- return ::open(name, O_WRONLY | O_CREAT, 0660);
- case read_write:
- return ::open(name, O_RDWR | O_CREAT, 0660);
- default:
- return -1;
- }
- }
- - int _handle = -1;
-};
- -}}}}
- -#endif /* BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ */
+// 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_POSIX_FILE_DESCRIPTOR_HPP_ +#define BOOST_PROCESS_DETAIL_POSIX_FILE_DESCRIPTOR_HPP_ + +#include <fcntl.h> +#include <string> +#include <boost/filesystem/path.hpp> + +namespace boost { namespace process { namespace detail { namespace posix { + +struct file_descriptor +{ + enum mode_t + { + read = 1, + write = 2, + read_write = 3 + }; + + + file_descriptor() = default; + explicit file_descriptor(const boost::filesystem::path& p, mode_t mode = read_write) + : file_descriptor(p.native(), mode) + { + } + + explicit file_descriptor(const std::string & path , mode_t mode = read_write) + : file_descriptor(path.c_str(), mode) {} + + + explicit file_descriptor(const char* path, mode_t mode = read_write) + : _handle(create_file(path, mode)) + { + + } + + file_descriptor(const file_descriptor & ) = delete; + file_descriptor(file_descriptor && ) = default; + + file_descriptor& operator=(const file_descriptor & ) = delete; + file_descriptor& operator=(file_descriptor && ) = default; + + ~file_descriptor() + { + if (_handle != -1) + ::close(_handle); + } + + int handle() const { return _handle;} + +private: + static int create_file(const char* name, mode_t mode ) + { + switch(mode) + { + case read: + return ::open(name, O_RDONLY); + case write: + return ::open(name, O_WRONLY | O_CREAT, 0660); + case read_write: + return ::open(name, O_RDWR | O_CREAT, 0660); + default: + return -1; + } + } + + int _handle = -1; +}; + +}}}} + +#endif /* BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ */ diff --git a/boost/process/detail/posix/file_in.hpp b/boost/process/detail/posix/file_in.hpp index c3ceeeead2..7ddd71684b 100644 --- a/boost/process/detail/posix/file_in.hpp +++ b/boost/process/detail/posix/file_in.hpp @@ -1,40 +1,40 @@ -// 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
-//
-// 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_POSIX_FILE_IN_HPP
-#define BOOST_PROCESS_DETAIL_POSIX_FILE_IN_HPP
- -#include <boost/process/pipe.hpp>
-#include <boost/process/detail/posix/handler.hpp>
-#include <boost/process/detail/posix/file_descriptor.hpp>
-#include <cstdio>
-#include <unistd.h>
- -namespace boost { namespace process { namespace detail { namespace posix {
- -struct file_in : handler_base_ext
-{
- file_descriptor file;
- int handle = file.handle();
- - template<typename T>
- file_in(T&& t) : file(std::forward<T>(t)) {}
- file_in(FILE * f) : handle(fileno(f)) {}
- - template <class WindowsExecutor>
- void on_exec_setup(WindowsExecutor &e) const
- {
- if (::dup2(handle, STDIN_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- }
-};
- -}}}}
- -#endif
+// 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 +// +// 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_POSIX_FILE_IN_HPP +#define BOOST_PROCESS_DETAIL_POSIX_FILE_IN_HPP + +#include <boost/process/pipe.hpp> +#include <boost/process/detail/posix/handler.hpp> +#include <boost/process/detail/posix/file_descriptor.hpp> +#include <cstdio> +#include <unistd.h> + +namespace boost { namespace process { namespace detail { namespace posix { + +struct file_in : handler_base_ext +{ + file_descriptor file; + int handle = file.handle(); + + template<typename T> + file_in(T&& t) : file(std::forward<T>(t)) {} + file_in(FILE * f) : handle(fileno(f)) {} + + template <class WindowsExecutor> + void on_exec_setup(WindowsExecutor &e) const + { + if (::dup2(handle, STDIN_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + } +}; + +}}}} + +#endif diff --git a/boost/process/detail/posix/file_out.hpp b/boost/process/detail/posix/file_out.hpp index 6fef732598..8e3d4eb716 100644 --- a/boost/process/detail/posix/file_out.hpp +++ b/boost/process/detail/posix/file_out.hpp @@ -1,65 +1,65 @@ -// 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)
+// 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_POSIX_FILE_OUT_HPP
-#define BOOST_PROCESS_POSIX_FILE_OUT_HPP
+#ifndef BOOST_PROCESS_POSIX_FILE_OUT_HPP +#define BOOST_PROCESS_POSIX_FILE_OUT_HPP -#include <boost/process/detail/posix/handler.hpp>
-#include <boost/process/detail/posix/file_descriptor.hpp>
+#include <boost/process/detail/posix/handler.hpp> +#include <boost/process/detail/posix/file_descriptor.hpp> -#include <unistd.h>
-namespace boost { namespace process { namespace detail { namespace posix {
+#include <unistd.h> +namespace boost { namespace process { namespace detail { namespace posix { -template<int p1, int p2>
-struct file_out : handler_base_ext
-{
- file_descriptor file;
- int handle = file.handle();
+template<int p1, int p2> +struct file_out : handler_base_ext +{ + file_descriptor file; + int handle = file.handle(); - template<typename T>
- file_out(T&& t) : file(std::forward<T>(t), file_descriptor::write), handle(file.handle()) {}
- file_out(FILE * f) : handle(fileno(f)) {}
+ template<typename T> + file_out(T&& t) : file(std::forward<T>(t), file_descriptor::write), handle(file.handle()) {} + file_out(FILE * f) : handle(fileno(f)) {} - template <typename Executor>
- void on_exec_setup(Executor &e) const;
-};
+ template <typename Executor> + void on_exec_setup(Executor &e) const; +}; -template<>
-template<typename Executor>
-void file_out<1,-1>::on_exec_setup(Executor &e) const
-{
- if (::dup2(handle, STDOUT_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
-}
+template<> +template<typename Executor> +void file_out<1,-1>::on_exec_setup(Executor &e) const +{ + if (::dup2(handle, STDOUT_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); +} -template<>
-template<typename Executor>
-void file_out<2,-1>::on_exec_setup(Executor &e) const
-{
- if (::dup2(handle, STDERR_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
-}
+template<> +template<typename Executor> +void file_out<2,-1>::on_exec_setup(Executor &e) const +{ + if (::dup2(handle, STDERR_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); +} -template<>
-template<typename Executor>
-void file_out<1,2>::on_exec_setup(Executor &e) const
-{
- if (::dup2(handle, STDOUT_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
+template<> +template<typename Executor> +void file_out<1,2>::on_exec_setup(Executor &e) const +{ + if (::dup2(handle, STDOUT_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); - if (::dup2(handle, STDERR_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
+ if (::dup2(handle, STDERR_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); -}
+} -}}}}
+}}}} -#endif
+#endif diff --git a/boost/process/detail/posix/group_ref.hpp b/boost/process/detail/posix/group_ref.hpp index d46e631fe7..730450fe11 100644 --- a/boost/process/detail/posix/group_ref.hpp +++ b/boost/process/detail/posix/group_ref.hpp @@ -28,7 +28,7 @@ struct group_ref : handler_base_ext {} template <class Executor> - void on_exec_setup(Executor& exec) const + void on_exec_setup(Executor&) const { if (grp.grp == -1) ::setpgid(0, 0); diff --git a/boost/process/detail/posix/handler.hpp b/boost/process/detail/posix/handler.hpp index 506db4e649..5ca3989a0f 100644 --- a/boost/process/detail/posix/handler.hpp +++ b/boost/process/detail/posix/handler.hpp @@ -1,74 +1,74 @@ -// 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)
+// 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_POSIX_HANDLER_HPP_
-#define BOOST_PROCESS_DETAIL_POSIX_HANDLER_HPP_
+#ifndef BOOST_PROCESS_DETAIL_POSIX_HANDLER_HPP_ +#define BOOST_PROCESS_DETAIL_POSIX_HANDLER_HPP_ -#include <boost/process/detail/handler_base.hpp>
+#include <boost/process/detail/handler_base.hpp> -namespace boost { namespace process { namespace detail { namespace posix {
+namespace boost { namespace process { namespace detail { namespace posix { -//does not extend anything.
-struct handler_base_ext : handler_base
-{
- template<typename Executor>
- void on_fork_error (Executor &, const std::error_code&) const {}
+//does not extend anything. +struct handler_base_ext : handler_base +{ + template<typename Executor> + void on_fork_error (Executor &, const std::error_code&) const {} - template<typename Executor>
- void on_exec_setup (Executor &) const {}
+ template<typename Executor> + void on_exec_setup (Executor &) const {} - template<typename Executor>
- void on_exec_error (Executor &, const std::error_code&) const {}
-};
+ template<typename Executor> + void on_exec_error (Executor &, const std::error_code&) const {} +}; -template <class Handler>
-struct on_fork_error_ : handler_base_ext
-{
- explicit on_fork_error_(Handler handler) : handler_(handler) {}
+template <class Handler> +struct on_fork_error_ : handler_base_ext +{ + explicit on_fork_error_(Handler handler) : handler_(handler) {} - template <class Executor>
- void on_fork_error(Executor &e, const std::error_code &ec) const
- {
- handler_(e, ec);
- }
-private:
- Handler handler_;
-};
+ template <class Executor> + void on_fork_error(Executor &e, const std::error_code &ec) const + { + handler_(e, ec); + } +private: + Handler handler_; +}; -template <class Handler>
-struct on_exec_setup_ : handler_base_ext
-{
- explicit on_exec_setup_(Handler handler) : handler_(handler) {}
+template <class Handler> +struct on_exec_setup_ : handler_base_ext +{ + explicit on_exec_setup_(Handler handler) : handler_(handler) {} - template <class Executor>
- void on_exec_setup(Executor &e) const
- {
- handler_(e);
- }
-private:
- Handler handler_;
-};
+ template <class Executor> + void on_exec_setup(Executor &e) const + { + handler_(e); + } +private: + Handler handler_; +}; -template <class Handler>
-struct on_exec_error_ : handler_base_ext
-{
- explicit on_exec_error_(Handler handler) : handler_(handler) {}
+template <class Handler> +struct on_exec_error_ : handler_base_ext +{ + explicit on_exec_error_(Handler handler) : handler_(handler) {} - template <class Executor>
- void on_exec_error(Executor &e, const std::error_code &ec) const
- {
- handler_(e, ec);
- }
-private:
- Handler handler_;
-};
+ template <class Executor> + void on_exec_error(Executor &e, const std::error_code &ec) const + { + handler_(e, ec); + } +private: + Handler handler_; +}; -}}}}
+}}}} -#endif /* BOOST_PROCESS_DETAIL_POSIX_HANDLER_HPP_ */
+#endif /* BOOST_PROCESS_DETAIL_POSIX_HANDLER_HPP_ */ diff --git a/boost/process/detail/posix/io_service_ref.hpp b/boost/process/detail/posix/io_context_ref.hpp index ced1d51033..603fd59a16 100644 --- a/boost/process/detail/posix/io_service_ref.hpp +++ b/boost/process/detail/posix/io_context_ref.hpp @@ -1,155 +1,114 @@ -// 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_POSIX_IO_SERVICE_REF_HPP_
-#define BOOST_PROCESS_POSIX_IO_SERVICE_REF_HPP_
- -#include <boost/process/detail/posix/handler.hpp>
-#include <boost/process/detail/posix/async_handler.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/signal_set.hpp>
- -#include <boost/fusion/algorithm/iteration/for_each.hpp>
-#include <boost/fusion/algorithm/transformation/filter_if.hpp>
-#include <boost/fusion/algorithm/transformation/transform.hpp>
-#include <boost/fusion/view/transform_view.hpp>
-#include <boost/fusion/container/vector/convert.hpp>
- - -#include <functional>
-#include <type_traits>
-#include <memory>
-#include <vector>
-#include <sys/wait.h>
- -namespace boost { namespace process { namespace detail { namespace posix {
- -template<typename Executor>
-struct on_exit_handler_transformer
-{
- Executor & exec;
- on_exit_handler_transformer(Executor & exec) : exec(exec) {}
- template<typename Sig>
- struct result;
- - template<typename T>
- struct result<on_exit_handler_transformer<Executor>(T&)>
- {
- typedef typename T::on_exit_handler_t type;
- };
- - template<typename T>
- auto operator()(T& t) const -> typename T::on_exit_handler_t
- {
- return t.on_exit_handler(exec);
- }
-};
- -template<typename Executor>
-struct async_handler_collector
-{
- Executor & exec;
- std::vector<std::function<void(int, const std::error_code & ec)>> &handlers;
- - - async_handler_collector(Executor & exec,
- std::vector<std::function<void(int, const std::error_code & ec)>> &handlers)
- : exec(exec), handlers(handlers) {}
- - template<typename T>
- void operator()(T & t) const
- {
- handlers.push_back(t.on_exit_handler(exec));
- };
-};
- -//Also set's up waiting for the exit, so it can close async stuff.
-struct io_service_ref : handler_base_ext
-{
- io_service_ref(boost::asio::io_service & ios) : ios(ios)
- {
- - }
- boost::asio::io_service &get() {return ios;};
- - boost::asio::signal_set *signal_p = nullptr;
- - template <class Executor>
- void on_setup(Executor& exec)
- {
- //must be on the heap so I can move it into the lambda.
- auto asyncs = boost::fusion::filter_if<
- is_async_handler<
- typename std::remove_reference< boost::mpl::_ > ::type
- >>(exec.seq);
- - //ok, check if there are actually any.
- if (boost::fusion::empty(asyncs))
- return;
- - std::vector<std::function<void(int, const std::error_code & ec)>> funcs;
- funcs.reserve(boost::fusion::size(asyncs));
- boost::fusion::for_each(asyncs, async_handler_collector<Executor>(exec, funcs));
- - wait_handler wh(std::move(funcs), ios, exec.exit_status);
- - signal_p = wh.signal_.get();
- signal_p->async_wait(std::move(wh));
- - }
- - template <class Executor>
- void on_error(Executor & exec, const std::error_code & ec) const
- {
- if (signal_p != nullptr)
- {
- boost::system::error_code ec;
- signal_p->cancel(ec);
- }
- }
- - struct wait_handler
- {
- std::shared_ptr<boost::asio::signal_set> signal_;
- std::vector<std::function<void(int, const std::error_code & ec)>> funcs;
- std::shared_ptr<std::atomic<int>> exit_status;
- - wait_handler(const wait_handler & ) = default;
- wait_handler(wait_handler && ) = default;
- wait_handler(
- std::vector<std::function<void(int, const std::error_code & ec)>> && funcs,
- boost::asio::io_service & ios,
- const std::shared_ptr<std::atomic<int>> &exit_status)
- : signal_(new boost::asio::signal_set(ios, SIGCHLD)),
- funcs(std::move(funcs)),
- exit_status(exit_status)
- {
- - }
- void operator()(const boost::system::error_code & ec_in, int /*signal*/)
- {
- if (ec_in.value() == boost::asio::error::operation_aborted)
- return;
- - - int status;
- ::wait(&status);
- - std::error_code ec(ec_in.value(), std::system_category());
- int val = WEXITSTATUS(status);
- exit_status->store(status);
- - for (auto & func : funcs)
- func(val, ec);
- }
- - };
-private:
- boost::asio::io_service &ios;
-};
- -}}}}
- -#endif /* BOOST_PROCESS_WINDOWS_IO_SERVICE_REF_HPP_ */
+// 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_POSIX_IO_CONTEXT_REF_HPP_ +#define BOOST_PROCESS_POSIX_IO_CONTEXT_REF_HPP_ + +#include <boost/process/detail/posix/handler.hpp> +#include <boost/process/detail/posix/async_handler.hpp> +#include <boost/asio/io_context.hpp> + +#include <boost/fusion/algorithm/iteration/for_each.hpp> +#include <boost/fusion/algorithm/transformation/filter_if.hpp> +#include <boost/fusion/algorithm/transformation/transform.hpp> +#include <boost/fusion/view/transform_view.hpp> +#include <boost/fusion/container/vector/convert.hpp> + + +#include <boost/process/detail/posix/sigchld_service.hpp> + +#include <functional> +#include <type_traits> +#include <memory> +#include <vector> +#include <sys/wait.h> + +namespace boost { namespace process { namespace detail { namespace posix { + +template<typename Executor> +struct on_exit_handler_transformer +{ + Executor & exec; + on_exit_handler_transformer(Executor & exec) : exec(exec) {} + template<typename Sig> + struct result; + + template<typename T> + struct result<on_exit_handler_transformer<Executor>(T&)> + { + typedef typename T::on_exit_handler_t type; + }; + + template<typename T> + auto operator()(T& t) const -> typename T::on_exit_handler_t + { + return t.on_exit_handler(exec); + } +}; + +template<typename Executor> +struct async_handler_collector +{ + Executor & exec; + std::vector<std::function<void(int, const std::error_code & ec)>> &handlers; + + + async_handler_collector(Executor & exec, + std::vector<std::function<void(int, const std::error_code & ec)>> &handlers) + : exec(exec), handlers(handlers) {} + + template<typename T> + void operator()(T & t) const + { + handlers.push_back(t.on_exit_handler(exec)); + }; +}; + +//Also set's up waiting for the exit, so it can close async stuff. +struct io_context_ref : handler_base_ext +{ + io_context_ref(boost::asio::io_context & ios) : ios(ios) + { + + } + boost::asio::io_context &get() {return ios;}; + + template <class Executor> + void on_success(Executor& exec) + { + //must be on the heap so I can move it into the lambda. + auto asyncs = boost::fusion::filter_if< + is_async_handler< + typename std::remove_reference< boost::mpl::_ > ::type + >>(exec.seq); + + //ok, check if there are actually any. + if (boost::fusion::empty(asyncs)) + return; + + std::vector<std::function<void(int, const std::error_code & ec)>> funcs; + funcs.reserve(boost::fusion::size(asyncs)); + boost::fusion::for_each(asyncs, async_handler_collector<Executor>(exec, funcs)); + + auto & es = exec.exit_status; + + auto wh = [funcs, es](int val, const std::error_code & ec) + { + es->store(val); + for (auto & func : funcs) + func(WEXITSTATUS(val), ec); + }; + + sigchld_service.async_wait(exec.pid, std::move(wh)); + } + +private: + boost::asio::io_context &ios; + boost::process::detail::posix::sigchld_service &sigchld_service = boost::asio::use_service<boost::process::detail::posix::sigchld_service>(ios); +}; + +}}}} + +#endif /* BOOST_PROCESS_WINDOWS_IO_CONTEXT_REF_HPP_ */ diff --git a/boost/process/detail/posix/null_in.hpp b/boost/process/detail/posix/null_in.hpp index 9f082054c6..33ced810b1 100644 --- a/boost/process/detail/posix/null_in.hpp +++ b/boost/process/detail/posix/null_in.hpp @@ -1,35 +1,35 @@ -// 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
-//
-// 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)
+// 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 +// +// 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_POSIX_NULL_IN_HPP
-#define BOOST_PROCESS_DETAIL_POSIX_NULL_IN_HPP
+#ifndef BOOST_PROCESS_DETAIL_POSIX_NULL_IN_HPP +#define BOOST_PROCESS_DETAIL_POSIX_NULL_IN_HPP -#include <boost/process/pipe.hpp>
-#include <boost/process/detail/posix/handler.hpp>
-#include <boost/process/detail/posix/file_descriptor.hpp>
-#include <unistd.h>
+#include <boost/process/pipe.hpp> +#include <boost/process/detail/posix/handler.hpp> +#include <boost/process/detail/posix/file_descriptor.hpp> +#include <unistd.h> -namespace boost { namespace process { namespace detail { namespace posix {
+namespace boost { namespace process { namespace detail { namespace posix { -struct null_in : handler_base_ext
-{
- file_descriptor source{"/dev/null", file_descriptor::read};
+struct null_in : handler_base_ext +{ + file_descriptor source{"/dev/null", file_descriptor::read}; -public:
- template <class Executor>
- void on_exec_setup(Executor &e) const
- {
- if (::dup2(source.handle(), STDIN_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- }
-};
+public: + template <class Executor> + void on_exec_setup(Executor &e) const + { + if (::dup2(source.handle(), STDIN_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + } +}; -}}}}
+}}}} -#endif
+#endif diff --git a/boost/process/detail/posix/null_out.hpp b/boost/process/detail/posix/null_out.hpp index ed4f915f35..3874475f4d 100644 --- a/boost/process/detail/posix/null_out.hpp +++ b/boost/process/detail/posix/null_out.hpp @@ -1,58 +1,58 @@ -// 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_POSIX_PIPE_OUT_HPP
-#define BOOST_PROCESS_POSIX_PIPE_OUT_HPP
- -#include <boost/process/detail/posix/handler.hpp>
-#include <boost/process/detail/posix/file_descriptor.hpp>
- -#include <unistd.h>
-namespace boost { namespace process { namespace detail { namespace posix {
- -template<int p1, int p2>
-struct null_out : handler_base_ext
-{
- file_descriptor sink{"/dev/null", file_descriptor::write};
-
- template <typename Executor>
- void on_exec_setup(Executor &e) const;
-};
- -template<>
-template<typename Executor>
-void null_out<1,-1>::on_exec_setup(Executor &e) const
-{
- if (::dup2(sink.handle(), STDOUT_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
-}
- -template<>
-template<typename Executor>
-void null_out<2,-1>::on_exec_setup(Executor &e) const
-{
- if (::dup2(sink.handle(), STDERR_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
-}
- -template<>
-template<typename Executor>
-void null_out<1,2>::on_exec_setup(Executor &e) const
-{
- if (::dup2(sink.handle(), STDOUT_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- - if (::dup2(sink.handle(), STDERR_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
-}
- -}}}}
- -#endif
+// 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_POSIX_PIPE_OUT_HPP +#define BOOST_PROCESS_POSIX_PIPE_OUT_HPP + +#include <boost/process/detail/posix/handler.hpp> +#include <boost/process/detail/posix/file_descriptor.hpp> + +#include <unistd.h> +namespace boost { namespace process { namespace detail { namespace posix { + +template<int p1, int p2> +struct null_out : handler_base_ext +{ + file_descriptor sink{"/dev/null", file_descriptor::write}; + + template <typename Executor> + void on_exec_setup(Executor &e) const; +}; + +template<> +template<typename Executor> +void null_out<1,-1>::on_exec_setup(Executor &e) const +{ + if (::dup2(sink.handle(), STDOUT_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); +} + +template<> +template<typename Executor> +void null_out<2,-1>::on_exec_setup(Executor &e) const +{ + if (::dup2(sink.handle(), STDERR_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); +} + +template<> +template<typename Executor> +void null_out<1,2>::on_exec_setup(Executor &e) const +{ + if (::dup2(sink.handle(), STDOUT_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + + if (::dup2(sink.handle(), STDERR_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); +} + +}}}} + +#endif diff --git a/boost/process/detail/posix/on_exit.hpp b/boost/process/detail/posix/on_exit.hpp index d3160aff32..eb79a81b6b 100644 --- a/boost/process/detail/posix/on_exit.hpp +++ b/boost/process/detail/posix/on_exit.hpp @@ -1,35 +1,35 @@ -// 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)
+// 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_POSIX_ON_EXIT_HPP_
-#define BOOST_PROCESS_POSIX_ON_EXIT_HPP_
+#ifndef BOOST_PROCESS_POSIX_ON_EXIT_HPP_ +#define BOOST_PROCESS_POSIX_ON_EXIT_HPP_ -#include <boost/process/detail/config.hpp>
-#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/posix/async_handler.hpp>
-#include <system_error>
-#include <functional>
+#include <boost/process/detail/config.hpp> +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/posix/async_handler.hpp> +#include <system_error> +#include <functional> -namespace boost { namespace process { namespace detail { namespace posix {
+namespace boost { namespace process { namespace detail { namespace posix { -struct on_exit_ : boost::process::detail::posix::async_handler
-{
- std::function<void(int, const std::error_code&)> handler;
- on_exit_(const std::function<void(int, const std::error_code&)> & handler) : handler(handler)
- {
+struct on_exit_ : boost::process::detail::posix::async_handler +{ + std::function<void(int, const std::error_code&)> handler; + on_exit_(const std::function<void(int, const std::error_code&)> & handler) : handler(handler) + { - }
+ } - template<typename Executor>
- std::function<void(int, const std::error_code&)> on_exit_handler(Executor & exec)
- {
- return handler;
+ template<typename Executor> + std::function<void(int, const std::error_code&)> on_exit_handler(Executor&) + { + return handler; - };
-};
+ }; +}; -}}}}
-#endif /* BOOST_PROCESS_POSIX_ON_EXIT_HPP_ */
+}}}} +#endif /* BOOST_PROCESS_POSIX_ON_EXIT_HPP_ */ diff --git a/boost/process/detail/posix/pipe_in.hpp b/boost/process/detail/posix/pipe_in.hpp index fa294cf310..18ca856573 100644 --- a/boost/process/detail/posix/pipe_in.hpp +++ b/boost/process/detail/posix/pipe_in.hpp @@ -1,90 +1,90 @@ -// 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
-//
-// 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_POSIX_PIPE_IN_HPP
-#define BOOST_PROCESS_POSIX_PIPE_IN_HPP
- -#include <boost/process/pipe.hpp>
-#include <boost/process/detail/posix/handler.hpp>
-#include <unistd.h>
- - -namespace boost { namespace process { namespace detail { namespace posix {
- -struct pipe_in : handler_base_ext
-{
- int source;
- int sink; //opposite end
- - pipe_in(int sink, int source) : source(source), sink(sink) {}
- - - template<typename T>
- pipe_in(T & p) : source(p.native_source()), sink(p.native_sink())
- {
- p.assign_source(-1);
- }
- - template<typename Executor>
- void on_error(Executor &, const std::error_code &) const
- {
- ::close(source);
- }
- - template<typename Executor>
- void on_success(Executor &) const
- {
- ::close(source);
- }
- - template <class Executor>
- void on_exec_setup(Executor &e) const
- {
- if (::dup2(source, STDIN_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- ::close(source);
- ::close(sink);
- }
- -};
- -class async_pipe;
- -struct async_pipe_in : public pipe_in
-{
- async_pipe &pipe;
- - template<typename AsyncPipe>
- async_pipe_in(AsyncPipe & p) : pipe_in(p.native_sink(), p.native_source()), pipe(p)
- {
- }
- - template<typename Pipe, typename Executor>
- static void close(Pipe & pipe, Executor &)
- {
- boost::system::error_code ec;
- std::move(pipe).source().close(ec);
- }
- - template<typename Executor>
- void on_error(Executor & exec, const std::error_code &)
- {
- close(pipe, exec);
- }
- - template<typename Executor>
- void on_success(Executor &exec)
- {
- close(pipe, exec);
- }
-};
- -}}}}
- -#endif
+// 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 +// +// 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_POSIX_PIPE_IN_HPP +#define BOOST_PROCESS_POSIX_PIPE_IN_HPP + +#include <boost/process/pipe.hpp> +#include <boost/process/detail/posix/handler.hpp> +#include <unistd.h> + + +namespace boost { namespace process { namespace detail { namespace posix { + +struct pipe_in : handler_base_ext +{ + int source; + int sink; //opposite end + + pipe_in(int sink, int source) : source(source), sink(sink) {} + + + template<typename T> + pipe_in(T & p) : source(p.native_source()), sink(p.native_sink()) + { + p.assign_source(-1); + } + + template<typename Executor> + void on_error(Executor &, const std::error_code &) const + { + ::close(source); + } + + template<typename Executor> + void on_success(Executor &) const + { + ::close(source); + } + + template <class Executor> + void on_exec_setup(Executor &e) const + { + if (::dup2(source, STDIN_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + ::close(source); + ::close(sink); + } + +}; + +class async_pipe; + +struct async_pipe_in : public pipe_in +{ + async_pipe &pipe; + + template<typename AsyncPipe> + async_pipe_in(AsyncPipe & p) : pipe_in(p.native_sink(), p.native_source()), pipe(p) + { + } + + template<typename Pipe, typename Executor> + static void close(Pipe & pipe, Executor &) + { + boost::system::error_code ec; + std::move(pipe).source().close(ec); + } + + template<typename Executor> + void on_error(Executor & exec, const std::error_code &) + { + close(pipe, exec); + } + + template<typename Executor> + void on_success(Executor &exec) + { + close(pipe, exec); + } +}; + +}}}} + +#endif diff --git a/boost/process/detail/posix/pipe_out.hpp b/boost/process/detail/posix/pipe_out.hpp index 0148c19d26..9f7da9464b 100644 --- a/boost/process/detail/posix/pipe_out.hpp +++ b/boost/process/detail/posix/pipe_out.hpp @@ -1,116 +1,116 @@ -// 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_POSIX_PIPE_OUT_HPP
-#define BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP
- -#include <boost/process/pipe.hpp>
-#include <boost/process/detail/posix/handler.hpp>
-#include <unistd.h>
- -namespace boost { namespace process { namespace detail { namespace posix {
- -template<int p1, int p2>
-struct pipe_out : handler_base_ext
-{
- int sink;
- int source; //opposite end
- - pipe_out(int sink, int source) : sink(sink), source(source) {}
- - template<typename T>
- pipe_out(T & p) : sink(p.native_sink()), source(p.native_source())
- {
- p.assign_sink(-1);
- }
- - template<typename Executor>
- void on_error(Executor &, const std::error_code &) const
- {
- ::close(sink);
- }
- - template<typename Executor>
- void on_success(Executor &) const
- {
- ::close(sink);
- }
- - template <typename Executor>
- void on_exec_setup(Executor &e) const;
-};
- -template<>
-template<typename Executor>
-void pipe_out<1,-1>::on_exec_setup(Executor &e) const
-{
- if (::dup2(sink, STDOUT_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup3() failed");
- ::close(sink);
- ::close(source);
-}
- -template<>
-template<typename Executor>
-void pipe_out<2,-1>::on_exec_setup(Executor &e) const
-{
- if (::dup2(sink, STDERR_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- ::close(sink);
- ::close(source);
-}
- -template<>
-template<typename Executor>
-void pipe_out<1,2>::on_exec_setup(Executor &e) const
-{
- if (::dup2(sink, STDOUT_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- if (::dup2(sink, STDERR_FILENO) == -1)
- e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
- ::close(sink);
- ::close(source);
-}
- -class async_pipe;
- -template<int p1, int p2>
-struct async_pipe_out : public pipe_out<p1, p2>
-{
- async_pipe &pipe;
- template<typename AsyncPipe>
- async_pipe_out(AsyncPipe & p) : pipe_out<p1, p2>(p.native_sink(), p.native_source()), pipe(p)
- {
- }
- - template<typename Pipe, typename Executor>
- static void close(Pipe & pipe, Executor &)
- {
- boost::system::error_code ec;
- std::move(pipe).sink().close(ec);
- }
- - template<typename Executor>
- void on_error(Executor & exec, const std::error_code &)
- {
- close(pipe, exec);
- }
- - template<typename Executor>
- void on_success(Executor &exec)
- {
- close(pipe, exec);
- }
-};
- - -}}}}
- -#endif
+// 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_POSIX_PIPE_OUT_HPP +#define BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP + +#include <boost/process/pipe.hpp> +#include <boost/process/detail/posix/handler.hpp> +#include <unistd.h> + +namespace boost { namespace process { namespace detail { namespace posix { + +template<int p1, int p2> +struct pipe_out : handler_base_ext +{ + int sink; + int source; //opposite end + + pipe_out(int sink, int source) : sink(sink), source(source) {} + + template<typename T> + pipe_out(T & p) : sink(p.native_sink()), source(p.native_source()) + { + p.assign_sink(-1); + } + + template<typename Executor> + void on_error(Executor &, const std::error_code &) const + { + ::close(sink); + } + + template<typename Executor> + void on_success(Executor &) const + { + ::close(sink); + } + + template <typename Executor> + void on_exec_setup(Executor &e) const; +}; + +template<> +template<typename Executor> +void pipe_out<1,-1>::on_exec_setup(Executor &e) const +{ + if (::dup2(sink, STDOUT_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup3() failed"); + ::close(sink); + ::close(source); +} + +template<> +template<typename Executor> +void pipe_out<2,-1>::on_exec_setup(Executor &e) const +{ + if (::dup2(sink, STDERR_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + ::close(sink); + ::close(source); +} + +template<> +template<typename Executor> +void pipe_out<1,2>::on_exec_setup(Executor &e) const +{ + if (::dup2(sink, STDOUT_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + if (::dup2(sink, STDERR_FILENO) == -1) + e.set_error(::boost::process::detail::get_last_error(), "dup2() failed"); + ::close(sink); + ::close(source); +} + +class async_pipe; + +template<int p1, int p2> +struct async_pipe_out : public pipe_out<p1, p2> +{ + async_pipe &pipe; + template<typename AsyncPipe> + async_pipe_out(AsyncPipe & p) : pipe_out<p1, p2>(p.native_sink(), p.native_source()), pipe(p) + { + } + + template<typename Pipe, typename Executor> + static void close(Pipe & pipe, Executor &) + { + boost::system::error_code ec; + std::move(pipe).sink().close(ec); + } + + template<typename Executor> + void on_error(Executor & exec, const std::error_code &) + { + close(pipe, exec); + } + + template<typename Executor> + void on_success(Executor &exec) + { + close(pipe, exec); + } +}; + + +}}}} + +#endif diff --git a/boost/process/detail/posix/search_path.hpp b/boost/process/detail/posix/search_path.hpp index 1ce5c65575..633cf0702e 100644 --- a/boost/process/detail/posix/search_path.hpp +++ b/boost/process/detail/posix/search_path.hpp @@ -24,7 +24,6 @@ inline boost::filesystem::path search_path( const boost::filesystem::path &filename, const std::vector<boost::filesystem::path> &path) { - std::string result; for (const boost::filesystem::path & pp : path) { auto p = pp / filename; diff --git a/boost/process/detail/posix/sigchld_service.hpp b/boost/process/detail/posix/sigchld_service.hpp new file mode 100644 index 0000000000..7fee01e075 --- /dev/null +++ b/boost/process/detail/posix/sigchld_service.hpp @@ -0,0 +1,113 @@ +// Copyright (c) 2017 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_POSIX_SIGCHLD_SERVICE_HPP_ +#define BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_ + +#include <boost/asio/signal_set.hpp> +#include <boost/asio/strand.hpp> +#include <boost/optional.hpp> +#include <signal.h> +#include <functional> +#include <sys/wait.h> + +namespace boost { namespace process { namespace detail { namespace posix { + +class sigchld_service : public boost::asio::detail::service_base<sigchld_service> +{ + boost::asio::io_context::strand _strand{get_io_context()}; + boost::asio::signal_set _signal_set{get_io_context(), SIGCHLD}; + + std::vector<std::pair<::pid_t, std::function<void(int, std::error_code)>>> _receivers; + inline void _handle_signal(const boost::system::error_code & ec); +public: + sigchld_service(boost::asio::io_context & io_context) + : boost::asio::detail::service_base<sigchld_service>(io_context) + { + } + + template <typename SignalHandler> + BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler, + void (int, std::error_code)) + async_wait(::pid_t pid, SignalHandler && handler) + { + boost::asio::async_completion< + SignalHandler, void(boost::system::error_code)> init{handler}; + auto & h = init.completion_handler; + _strand.post( + [this, pid, h] + { + if (_receivers.empty()) + _signal_set.async_wait( + [this](const boost::system::error_code & ec, int) + { + _strand.post([this,ec]{this->_handle_signal(ec);}); + }); + _receivers.emplace_back(pid, h); + }); + + return init.result.get(); + } + void shutdown_service() override + { + _receivers.clear(); + } + + void cancel() + { + _signal_set.cancel(); + } + void cancel(boost::system::error_code & ec) + { + _signal_set.cancel(ec); + } +}; + + +void sigchld_service::_handle_signal(const boost::system::error_code & ec) +{ + std::error_code ec_{ec.value(), std::system_category()}; + + if (ec_) + { + for (auto & r : _receivers) + r.second(-1, ec_); + return; + } + int status; + int pid = ::waitpid(0, &status, WNOHANG); + + auto itr = std::find_if(_receivers.begin(), _receivers.end(), + [&pid](const std::pair<::pid_t, std::function<void(int, std::error_code)>> & p) + { + return p.first == pid; + }); + if (itr != _receivers.cend()) + { + _strand.get_io_context().wrap(itr->second)(status, ec_); + _receivers.erase(itr); + } + if (!_receivers.empty()) + { + _signal_set.async_wait( + [this](const boost::system::error_code & ec, int) + { + _strand.post([ec]{}); + this->_handle_signal(ec); + }); + } +} + + +} +} +} +} + + + + +#endif diff --git a/boost/process/detail/posix/wait_for_exit.hpp b/boost/process/detail/posix/wait_for_exit.hpp index bf25e2a3d8..308aaf6908 100644 --- a/boost/process/detail/posix/wait_for_exit.hpp +++ b/boost/process/detail/posix/wait_for_exit.hpp @@ -15,7 +15,7 @@ #include <system_error> #include <sys/types.h> #include <sys/wait.h> - +#include <unistd.h> namespace boost { namespace process { namespace detail { namespace posix { @@ -26,9 +26,11 @@ inline void wait(const child_handle &p, int & exit_code) do { ret = ::waitpid(p.pid, &status, 0); - } while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status))); + } while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status))); if (ret == -1) boost::process::detail::throw_last_error("waitpid(2) failed"); + if (WIFSIGNALED(status)) + throw process_error(std::error_code(), "process terminated due to receipt of a signal"); exit_code = status; } @@ -41,7 +43,7 @@ inline void wait(const child_handle &p, int & exit_code, std::error_code &ec) no { ret = ::waitpid(p.pid, &status, 0); } - while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status))); + while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status))); if (ret == -1) ec = boost::process::detail::get_last_error(); @@ -67,26 +69,27 @@ inline bool wait_for( auto start = std::chrono::system_clock::now(); auto time_out = start + rel_time; - bool time_out_occured = false; + bool timed_out; do { - ret = ::waitpid(p.pid, &status, WUNTRACED | WNOHANG); - if (std::chrono::system_clock::now() >= time_out) + ret = ::waitpid(p.pid, &status, WNOHANG); + if (ret == 0) { - time_out_occured = true; - break; + timed_out = std::chrono::system_clock::now() >= time_out; + if (timed_out) + return false; } } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status))); - + while ((ret == 0) || + ((ret == -1) && errno == EINTR) || + ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); if (ret == -1) boost::process::detail::throw_last_error("waitpid(2) failed"); - + exit_code = status; - return !time_out_occured; + return true; } @@ -103,20 +106,25 @@ inline bool wait_for( auto start = std::chrono::system_clock::now(); auto time_out = start + rel_time; + bool timed_out; - bool time_out_occured = false; do { - ret = ::waitpid(p.pid, &status, WUNTRACED | WNOHANG); - if (std::chrono::system_clock::now() >= time_out) + ret = ::waitpid(p.pid, &status, WNOHANG); + if (ret == 0) { - time_out_occured = true; - break; + timed_out = std::chrono::system_clock::now() >= time_out; + if (timed_out) + return false; } } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status))); + while ((ret == 0) || + (((ret == -1) && errno == EINTR) || + ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status)))); + + if (timed_out && (ret == -1)) + return false; if (ret == -1) ec = boost::process::detail::get_last_error(); @@ -126,68 +134,79 @@ inline bool wait_for( exit_code = status; } - return !time_out_occured; + return true; } -template< class Rep, class Period > +template< class Clock, class Duration > inline bool wait_until( const child_handle &p, int & exit_code, - const std::chrono::duration<Rep, Period>& time_out) + const std::chrono::time_point<Clock, Duration>& time_out) { pid_t ret; int status; - bool time_out_occured = false; + bool timed_out; do { - ret = ::waitpid(p.pid, &status, WUNTRACED | WNOHANG); - if (std::chrono::system_clock::now() >= time_out) + ret = ::waitpid(p.pid, &status, WNOHANG); + if (ret == 0) { - time_out_occured = true; - break; + timed_out = std::chrono::system_clock::now() >= time_out; + if (timed_out) + return false; } - } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status))); + } + while ((ret == 0) || + (((ret == -1) && errno == EINTR) || + ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status)))); + if (timed_out && !WIFEXITED(status)) + return false; + if (ret == -1) boost::process::detail::throw_last_error("waitpid(2) failed"); - exit_code = status; - return !time_out_occured; + return true; } -template< class Rep, class Period > +template< class Clock, class Duration > inline bool wait_until( const child_handle &p, int & exit_code, - const std::chrono::duration<Rep, Period>& time_out, + const std::chrono::time_point<Clock, Duration>& time_out, std::error_code & ec) noexcept { pid_t ret; int status; - bool time_out_occured = false; + bool timed_out; + do { - ret = ::waitpid(p.pid, &status, WUNTRACED | WNOHANG); - if (std::chrono::system_clock::now() >= time_out) + ret = ::waitpid(p.pid, &status, WNOHANG); + if (ret == 0) { - time_out_occured = true; - break; + timed_out = std::chrono::system_clock::now() >= time_out; + if (timed_out) + return false; } } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status))); + while ((ret == 0) || + (((ret == -1) && errno == EINTR) || + ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status)))); + + + if (timed_out && !WIFEXITED(status)) + return false; if (ret == -1) ec = boost::process::detail::get_last_error(); @@ -197,7 +216,7 @@ inline bool wait_until( exit_code = status; } - return !time_out_occured; + return true; } }}}} diff --git a/boost/process/detail/posix/wait_group.hpp b/boost/process/detail/posix/wait_group.hpp index 8b768ffc14..172fe06b5b 100644 --- a/boost/process/detail/posix/wait_group.hpp +++ b/boost/process/detail/posix/wait_group.hpp @@ -25,9 +25,11 @@ inline void wait(const group_handle &p) do { ret = ::waitpid(-p.grp, &status, 0); - } while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status))); + } while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status))); if (ret == -1) boost::process::detail::throw_last_error("waitpid(2) failed"); + if (WIFSIGNALED(status)) + throw process_error(std::error_code(), "process group terminated due to receipt of a signal"); } inline void wait(const group_handle &p, std::error_code &ec) noexcept @@ -39,10 +41,12 @@ inline void wait(const group_handle &p, std::error_code &ec) noexcept { ret = ::waitpid(-p.grp, &status, 0); } - while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status))); + while (((ret == -1) && (errno == EINTR)) || (ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status))); if (ret == -1) ec = boost::process::detail::get_last_error(); + else if (WIFSIGNALED(status)) + ec = std::make_error_code(std::errc::no_such_process); else ec.clear(); @@ -70,13 +74,14 @@ inline bool wait_for( break; } } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status))); + while (((ret == -1) && errno == EINTR) || + ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); if (ret == -1) boost::process::detail::throw_last_error("waitpid(2) failed"); - + if (WIFSIGNALED(status)) + throw process_error(std::error_code(), "process group terminated due to receipt of a signal"); return !time_out_occured; } @@ -105,12 +110,14 @@ inline bool wait_for( break; } } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status))); + while (((ret == -1) && errno == EINTR) || + ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); if (ret == -1) ec = boost::process::detail::get_last_error(); + else if (WIFSIGNALED(status)) + ec = std::make_error_code(std::errc::no_such_process); else ec.clear(); @@ -128,8 +135,6 @@ inline bool wait_until( pid_t ret; int status; - auto start = std::chrono::system_clock::now(); - bool time_out_occured = false; do { @@ -140,12 +145,14 @@ inline bool wait_until( break; } } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status))); + while (((ret == -1) && errno == EINTR) || + ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); if (ret == -1) boost::process::detail::throw_last_error("waitpid(2) failed"); + if (WIFSIGNALED(status)) + throw process_error(std::error_code(), "process group terminated due to receipt of a signal"); return !time_out_occured; @@ -162,8 +169,6 @@ inline bool wait_until( pid_t ret; int status; - auto start = std::chrono::system_clock::now(); - bool time_out_occured = false; do { @@ -174,12 +179,14 @@ inline bool wait_until( break; } } - while (((ret == -1) && errno == EINTR) || - ((ret != -1) && !WIFEXITED(status))); + while (((ret == -1) && errno == EINTR) || + ((ret != -1) && !WIFEXITED(status) && !WIFSIGNALED(status))); if (ret == -1) ec = boost::process::detail::get_last_error(); + else if (WIFSIGNALED(status)) + ec = std::make_error_code(std::errc::no_such_process); else ec.clear(); diff --git a/boost/process/detail/traits.hpp b/boost/process/detail/traits.hpp index a1b0e6b19b..83789d9d0a 100644 --- a/boost/process/detail/traits.hpp +++ b/boost/process/detail/traits.hpp @@ -1,17 +1,17 @@ -// 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)
+// 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_TRAITS_HPP_
-#define BOOST_PROCESS_TRAITS_HPP_
+#ifndef BOOST_PROCESS_TRAITS_HPP_ +#define BOOST_PROCESS_TRAITS_HPP_ -#include <boost/process/detail/traits/decl.hpp>
-#include <boost/process/detail/traits/async.hpp>
-#include <boost/process/detail/traits/cmd_or_exe.hpp>
-#include <boost/process/detail/traits/env.hpp>
-#include <boost/process/detail/traits/error.hpp>
-#include <boost/process/detail/traits/wchar_t.hpp>
+#include <boost/process/detail/traits/decl.hpp> +#include <boost/process/detail/traits/async.hpp> +#include <boost/process/detail/traits/cmd_or_exe.hpp> +#include <boost/process/detail/traits/env.hpp> +#include <boost/process/detail/traits/error.hpp> +#include <boost/process/detail/traits/wchar_t.hpp> -#endif /* BOOST_PROCESS_TRAITS_HPP_ */
+#endif /* BOOST_PROCESS_TRAITS_HPP_ */ diff --git a/boost/process/detail/traits/async.hpp b/boost/process/detail/traits/async.hpp index da7ed79aae..380f9f3209 100644 --- a/boost/process/detail/traits/async.hpp +++ b/boost/process/detail/traits/async.hpp @@ -1,34 +1,34 @@ -// 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)
+// 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_TRAITS_ASYNC_HPP_
-#define BOOST_PROCESS_DETAIL_TRAITS_ASYNC_HPP_
+#ifndef BOOST_PROCESS_DETAIL_TRAITS_ASYNC_HPP_ +#define BOOST_PROCESS_DETAIL_TRAITS_ASYNC_HPP_ -#include <boost/process/detail/config.hpp>
-#include <boost/process/detail/traits/decl.hpp>
+#include <boost/process/detail/config.hpp> +#include <boost/process/detail/traits/decl.hpp> -namespace boost { namespace asio {
+namespace boost { namespace asio { -class io_service;
-}}
+class io_context; +}} -namespace boost { namespace process { namespace detail {
+namespace boost { namespace process { namespace detail { -struct async_tag {};
+struct async_tag {}; -template<>
-struct initializer_builder<async_tag>;
+template<> +struct initializer_builder<async_tag>; -template<> struct initializer_tag<::boost::asio::io_service> { typedef async_tag type;};
+template<> struct initializer_tag<::boost::asio::io_context> { typedef async_tag type;}; -}}}
+}}} -#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
+#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */ diff --git a/boost/process/detail/traits/cmd_or_exe.hpp b/boost/process/detail/traits/cmd_or_exe.hpp index f6a8ae7cd3..1c627122de 100644 --- a/boost/process/detail/traits/cmd_or_exe.hpp +++ b/boost/process/detail/traits/cmd_or_exe.hpp @@ -1,85 +1,85 @@ -// 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)
+// 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_TRAITS_CMD_OR_EXE_HPP_
-#define BOOST_PROCESS_DETAIL_TRAITS_CMD_OR_EXE_HPP_
+#ifndef BOOST_PROCESS_DETAIL_TRAITS_CMD_OR_EXE_HPP_ +#define BOOST_PROCESS_DETAIL_TRAITS_CMD_OR_EXE_HPP_ -#include <string>
-#include <vector>
-#include <type_traits>
-#include <initializer_list>
-#include <boost/filesystem/path.hpp>
-#include <boost/process/detail/traits/decl.hpp>
-namespace boost { namespace process { namespace detail {
+#include <string> +#include <vector> +#include <type_traits> +#include <initializer_list> +#include <boost/filesystem/path.hpp> +#include <boost/process/detail/traits/decl.hpp> +namespace boost { namespace process { namespace detail { -template<typename Char>
-struct cmd_or_exe_tag {};
+template<typename Char> +struct cmd_or_exe_tag {}; -struct shell_;
+struct shell_; -template<> struct initializer_tag<const char* > { typedef cmd_or_exe_tag<char> type;};
-template<> struct initializer_tag<const wchar_t* > { typedef cmd_or_exe_tag<wchar_t> type;};
+template<> struct initializer_tag<const char* > { typedef cmd_or_exe_tag<char> type;}; +template<> struct initializer_tag<const wchar_t* > { typedef cmd_or_exe_tag<wchar_t> type;}; -template<> struct initializer_tag<char* > { typedef cmd_or_exe_tag<char> type;};
-template<> struct initializer_tag<wchar_t* > { typedef cmd_or_exe_tag<wchar_t> type;};
+template<> struct initializer_tag<char* > { typedef cmd_or_exe_tag<char> type;}; +template<> struct initializer_tag<wchar_t* > { typedef cmd_or_exe_tag<wchar_t> type;}; -template<std::size_t Size> struct initializer_tag<const char [Size]> { typedef cmd_or_exe_tag<char> type;};
-template<std::size_t Size> struct initializer_tag<const wchar_t [Size]> { typedef cmd_or_exe_tag<wchar_t> type;};
+template<std::size_t Size> struct initializer_tag<const char [Size]> { typedef cmd_or_exe_tag<char> type;}; +template<std::size_t Size> struct initializer_tag<const wchar_t [Size]> { typedef cmd_or_exe_tag<wchar_t> type;}; -template<std::size_t Size> struct initializer_tag<const char (&)[Size]> { typedef cmd_or_exe_tag<char> type;};
-template<std::size_t Size> struct initializer_tag<const wchar_t (&)[Size]> { typedef cmd_or_exe_tag<wchar_t> type;};
+template<std::size_t Size> struct initializer_tag<const char (&)[Size]> { typedef cmd_or_exe_tag<char> type;}; +template<std::size_t Size> struct initializer_tag<const wchar_t (&)[Size]> { typedef cmd_or_exe_tag<wchar_t> type;}; -template<> struct initializer_tag<std::basic_string<char >> { typedef cmd_or_exe_tag<char> type;};
-template<> struct initializer_tag<std::basic_string<wchar_t >> { typedef cmd_or_exe_tag<wchar_t> type;};
+template<> struct initializer_tag<std::basic_string<char >> { typedef cmd_or_exe_tag<char> type;}; +template<> struct initializer_tag<std::basic_string<wchar_t >> { typedef cmd_or_exe_tag<wchar_t> type;}; -template<> struct initializer_tag<std::vector<std::basic_string<char >>> { typedef cmd_or_exe_tag<char> type;};
-template<> struct initializer_tag<std::vector<std::basic_string<wchar_t >>> { typedef cmd_or_exe_tag<wchar_t> type;};
+template<> struct initializer_tag<std::vector<std::basic_string<char >>> { typedef cmd_or_exe_tag<char> type;}; +template<> struct initializer_tag<std::vector<std::basic_string<wchar_t >>> { typedef cmd_or_exe_tag<wchar_t> type;}; -template<> struct initializer_tag<std::initializer_list<std::basic_string<char >>> { typedef cmd_or_exe_tag<char> type;};
-template<> struct initializer_tag<std::initializer_list<std::basic_string<wchar_t >>> { typedef cmd_or_exe_tag<wchar_t> type;};
+template<> struct initializer_tag<std::initializer_list<std::basic_string<char >>> { typedef cmd_or_exe_tag<char> type;}; +template<> struct initializer_tag<std::initializer_list<std::basic_string<wchar_t >>> { typedef cmd_or_exe_tag<wchar_t> type;}; -template<> struct initializer_tag<std::vector<char *>> { typedef cmd_or_exe_tag<char> type;};
-template<> struct initializer_tag<std::vector<wchar_t *>> { typedef cmd_or_exe_tag<wchar_t> type;};
+template<> struct initializer_tag<std::vector<char *>> { typedef cmd_or_exe_tag<char> type;}; +template<> struct initializer_tag<std::vector<wchar_t *>> { typedef cmd_or_exe_tag<wchar_t> type;}; -template<> struct initializer_tag<std::initializer_list<char *>> { typedef cmd_or_exe_tag<char> type;};
-template<> struct initializer_tag<std::initializer_list<wchar_t *>> { typedef cmd_or_exe_tag<wchar_t> type;};
+template<> struct initializer_tag<std::initializer_list<char *>> { typedef cmd_or_exe_tag<char> type;}; +template<> struct initializer_tag<std::initializer_list<wchar_t *>> { typedef cmd_or_exe_tag<wchar_t> type;}; -template<> struct initializer_tag<std::initializer_list<const char *>> { typedef cmd_or_exe_tag<char> type;};
-template<> struct initializer_tag<std::initializer_list<const wchar_t *>> { typedef cmd_or_exe_tag<wchar_t> type;};
+template<> struct initializer_tag<std::initializer_list<const char *>> { typedef cmd_or_exe_tag<char> type;}; +template<> struct initializer_tag<std::initializer_list<const wchar_t *>> { typedef cmd_or_exe_tag<wchar_t> type;}; -template<> struct initializer_tag<shell_>
-{
- typedef cmd_or_exe_tag<typename boost::filesystem::path::value_type> type;
-};
+template<> struct initializer_tag<shell_> +{ + typedef cmd_or_exe_tag<typename boost::filesystem::path::value_type> type; +}; -template<> struct initializer_tag<boost::filesystem::path>
-{
- typedef cmd_or_exe_tag<typename boost::filesystem::path::value_type> type;
-};
+template<> struct initializer_tag<boost::filesystem::path> +{ + typedef cmd_or_exe_tag<typename boost::filesystem::path::value_type> type; +}; -template <typename Char>
-struct exe_setter_;
-template <typename Char, bool Append = false>
-struct arg_setter_;
+template <typename Char> +struct exe_setter_; +template <typename Char, bool Append = false> +struct arg_setter_; -template <typename Char, bool Append>
-struct initializer_tag<arg_setter_<Char, Append>> { typedef cmd_or_exe_tag<Char> type;};
+template <typename Char, bool Append> +struct initializer_tag<arg_setter_<Char, Append>> { typedef cmd_or_exe_tag<Char> type;}; -template<typename Char> struct initializer_tag<exe_setter_<Char>> { typedef cmd_or_exe_tag<Char> type;};
+template<typename Char> struct initializer_tag<exe_setter_<Char>> { typedef cmd_or_exe_tag<Char> type;}; -template<>
-struct initializer_builder<cmd_or_exe_tag<char>>;
+template<> +struct initializer_builder<cmd_or_exe_tag<char>>; -template<>
-struct initializer_builder<cmd_or_exe_tag<wchar_t>>;
+template<> +struct initializer_builder<cmd_or_exe_tag<wchar_t>>; -}}}
+}}} -#endif /* BOOST_PROCESS_DETAIL_STRING_TRAITS_HPP_ */
+#endif /* BOOST_PROCESS_DETAIL_STRING_TRAITS_HPP_ */ diff --git a/boost/process/detail/traits/decl.hpp b/boost/process/detail/traits/decl.hpp index 48f8022f73..6062b22646 100644 --- a/boost/process/detail/traits/decl.hpp +++ b/boost/process/detail/traits/decl.hpp @@ -1,76 +1,76 @@ -// 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)
+// 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_TRAITS_DECL_HPP_
-#define BOOST_PROCESS_DETAIL_TRAITS_DECL_HPP_
+#ifndef BOOST_PROCESS_DETAIL_TRAITS_DECL_HPP_ +#define BOOST_PROCESS_DETAIL_TRAITS_DECL_HPP_ -#include <boost/process/detail/config.hpp>
-#include <boost/none.hpp>
-#include <type_traits>
+#include <boost/process/detail/config.hpp> +#include <boost/none.hpp> +#include <type_traits> -#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
+#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 -namespace boost { namespace process { namespace detail {
+namespace boost { namespace process { namespace detail { -template<typename T>
-struct is_initializer : std::is_base_of<handler_base, T> {};
+template<typename T> +struct is_initializer : std::is_base_of<handler_base, T> {}; -template<typename T>
-struct is_initializer<T&> : std::is_base_of<handler_base, T> {};
+template<typename T> +struct is_initializer<T&> : std::is_base_of<handler_base, T> {}; -template<typename T>
-struct initializer_tag;// { typedef void type; };
+template<typename T> +struct initializer_tag;// { typedef void type; }; -//remove const
-template<typename T>
-struct initializer_tag<const T> { typedef typename initializer_tag<T>::type type; };
+//remove const +template<typename T> +struct initializer_tag<const T> { typedef typename initializer_tag<T>::type type; }; -//remove &
-template<typename T>
-struct initializer_tag<T&> { typedef typename initializer_tag<T>::type type; };
+//remove & +template<typename T> +struct initializer_tag<T&> { typedef typename initializer_tag<T>::type type; }; -//remove const &
-template<typename T>
-struct initializer_tag<const T&> { typedef typename initializer_tag<T>::type type; };
+//remove const & +template<typename T> +struct initializer_tag<const T&> { typedef typename initializer_tag<T>::type type; }; -template<typename T>
-struct initializer_builder;
+template<typename T> +struct initializer_builder; -template<typename First, typename ...Args>
-struct valid_argument_list;
+template<typename First, typename ...Args> +struct valid_argument_list; -template<typename First>
-struct valid_argument_list<First>
-{
- constexpr static bool value = is_initializer<First>::value || !std::is_void<typename initializer_tag<First>::type>::value;
- typedef std::integral_constant<bool, value> type;
-};
+template<typename First> +struct valid_argument_list<First> +{ + constexpr static bool value = is_initializer<First>::value || !std::is_void<typename initializer_tag<First>::type>::value; + typedef std::integral_constant<bool, value> type; +}; -template<typename First, typename ...Args>
-struct valid_argument_list
-{
- constexpr static bool my_value = is_initializer<First>::value || !std::is_void<typename initializer_tag<First>::type>::value;
- constexpr static bool value = valid_argument_list<Args...>::value && my_value;
- typedef std::integral_constant<bool, value> type;
-};
+template<typename First, typename ...Args> +struct valid_argument_list +{ + constexpr static bool my_value = is_initializer<First>::value || !std::is_void<typename initializer_tag<First>::type>::value; + constexpr static bool value = valid_argument_list<Args...>::value && my_value; + typedef std::integral_constant<bool, value> type; +}; -}}}
+}}} -#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
+#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */ diff --git a/boost/process/detail/traits/env.hpp b/boost/process/detail/traits/env.hpp index ccdcad046a..fdcf8add03 100644 --- a/boost/process/detail/traits/env.hpp +++ b/boost/process/detail/traits/env.hpp @@ -1,53 +1,53 @@ -// 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)
+// 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_TRAITS_ENV_HPP_
-#define BOOST_PROCESS_DETAIL_TRAITS_ENV_HPP_
+#ifndef BOOST_PROCESS_DETAIL_TRAITS_ENV_HPP_ +#define BOOST_PROCESS_DETAIL_TRAITS_ENV_HPP_ -#include <boost/process/detail/traits/decl.hpp>
+#include <boost/process/detail/traits/decl.hpp> -namespace boost { namespace process {
+namespace boost { namespace process { -template<typename Char>
-class basic_environment;
+template<typename Char> +class basic_environment; -template<typename Char>
-class basic_native_environment;
+template<typename Char> +class basic_native_environment; -namespace detail {
+namespace detail { -template<typename Char>
-struct env_tag {};
+template<typename Char> +struct env_tag {}; -template<typename Char> struct env_set;
-template<typename Char> struct env_append;
+template<typename Char> struct env_set; +template<typename Char> struct env_append; -template<typename Char> struct env_reset;
-template<typename Char> struct env_init;
+template<typename Char> struct env_reset; +template<typename Char> struct env_init; -template<typename Char> struct initializer_tag<env_set<Char>> { typedef env_tag<Char> type; };
-template<typename Char> struct initializer_tag<env_append<Char>> { typedef env_tag<Char> type; };
+template<typename Char> struct initializer_tag<env_set<Char>> { typedef env_tag<Char> type; }; +template<typename Char> struct initializer_tag<env_append<Char>> { typedef env_tag<Char> type; }; -template<typename Char> struct initializer_tag<env_reset<Char>> { typedef env_tag<Char> type;};
-template<typename Char> struct initializer_tag<env_init <Char>> { typedef env_tag<Char> type;};
+template<typename Char> struct initializer_tag<env_reset<Char>> { typedef env_tag<Char> type;}; +template<typename Char> struct initializer_tag<env_init <Char>> { typedef env_tag<Char> type;}; -template<typename Char> struct initializer_tag<::boost::process::basic_environment<Char>> { typedef env_tag<Char> type; };
-template<typename Char> struct initializer_tag<::boost::process::basic_native_environment<Char>> { typedef env_tag<Char> type; };
+template<typename Char> struct initializer_tag<::boost::process::basic_environment<Char>> { typedef env_tag<Char> type; }; +template<typename Char> struct initializer_tag<::boost::process::basic_native_environment<Char>> { typedef env_tag<Char> type; }; -template<> struct initializer_builder<env_tag<char>>;
-template<> struct initializer_builder<env_tag<wchar_t>>;
+template<> struct initializer_builder<env_tag<char>>; +template<> struct initializer_builder<env_tag<wchar_t>>; -}
+} -}}
+}} -#endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENV_HPP_ */
+#endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENV_HPP_ */ diff --git a/boost/process/detail/traits/error.hpp b/boost/process/detail/traits/error.hpp index 2d1912bda9..d2f7d5e48d 100644 --- a/boost/process/detail/traits/error.hpp +++ b/boost/process/detail/traits/error.hpp @@ -1,27 +1,27 @@ -// 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)
+// 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_TRAITS_ERROR_HPP_
-#define BOOST_PROCESS_DETAIL_TRAITS_ERROR_HPP_
+#ifndef BOOST_PROCESS_DETAIL_TRAITS_ERROR_HPP_ +#define BOOST_PROCESS_DETAIL_TRAITS_ERROR_HPP_ -#include <boost/process/detail/config.hpp>
-#include <system_error>
-#include <boost/process/detail/traits/decl.hpp>
+#include <boost/process/detail/config.hpp> +#include <system_error> +#include <boost/process/detail/traits/decl.hpp> -namespace boost { namespace process { namespace detail {
+namespace boost { namespace process { namespace detail { -struct error_tag;
+struct error_tag; -template<>
-struct initializer_tag<std::error_code>;
+template<> +struct initializer_tag<std::error_code>; -}}}
+}}} -#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
+#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */ diff --git a/boost/process/detail/windows/asio_fwd.hpp b/boost/process/detail/windows/asio_fwd.hpp index f7667db101..0c388548fc 100644 --- a/boost/process/detail/windows/asio_fwd.hpp +++ b/boost/process/detail/windows/asio_fwd.hpp @@ -19,27 +19,35 @@ template<typename Allocator> class basic_streambuf; typedef basic_streambuf<std::allocator<char>> streambuf; -class io_service; +class io_context; template <typename Handler> class basic_yield_context; namespace windows { +#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) class stream_handle_service; template <typename StreamHandleService> class basic_stream_handle; typedef basic_stream_handle<stream_handle_service> stream_handle; +#else /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */ +class stream_handle; +#endif /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */ +#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) class object_handle_service; template <typename ObjectHandleService> class basic_object_handle; typedef basic_object_handle<object_handle_service> object_handle; +#else /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */ +class object_handle; +#endif /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */ } //windows } //asio diff --git a/boost/process/detail/windows/async_handler.hpp b/boost/process/detail/windows/async_handler.hpp index 197c264126..ad0410ebac 100644 --- a/boost/process/detail/windows/async_handler.hpp +++ b/boost/process/detail/windows/async_handler.hpp @@ -1,40 +1,40 @@ -// 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)
+// 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_WINDOWS_ASYNC_HANDLER_HPP_
-#define BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_
+#ifndef BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ +#define BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ -#include <boost/process/detail/windows/handler.hpp>
-#include <type_traits>
+#include <boost/process/detail/windows/handler.hpp> +#include <type_traits> -namespace boost { namespace process { namespace detail { namespace windows {
+namespace boost { namespace process { namespace detail { namespace windows { -struct require_io_service {};
+struct require_io_context {}; -struct async_handler : handler_base_ext, require_io_service
-{
-};
+struct async_handler : handler_base_ext, require_io_context +{ +}; -template<typename T>
-struct is_async_handler : std::is_base_of<async_handler, T> {};
-template<typename T>
-struct is_async_handler<T&> : std::is_base_of<async_handler, T> {};
-template<typename T>
-struct is_async_handler<const T&> : std::is_base_of<async_handler, T> {};
+template<typename T> +struct is_async_handler : std::is_base_of<async_handler, T> {}; +template<typename T> +struct is_async_handler<T&> : std::is_base_of<async_handler, T> {}; +template<typename T> +struct is_async_handler<const T&> : std::is_base_of<async_handler, T> {}; -template<typename T>
-struct does_require_io_service : std::is_base_of<require_io_service, T> {};
+template<typename T> +struct does_require_io_context : std::is_base_of<require_io_context, T> {}; -template<typename T>
-struct does_require_io_service<T&> : std::is_base_of<require_io_service, T> {};
+template<typename T> +struct does_require_io_context<T&> : std::is_base_of<require_io_context, T> {}; -template<typename T>
-struct does_require_io_service<const T&> : std::is_base_of<require_io_service, T> {};
+template<typename T> +struct does_require_io_context<const T&> : std::is_base_of<require_io_context, T> {}; -}}}}
+}}}} -#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */
+#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */ diff --git a/boost/process/detail/windows/async_in.hpp b/boost/process/detail/windows/async_in.hpp index 4c498612d3..fc38dcdc34 100644 --- a/boost/process/detail/windows/async_in.hpp +++ b/boost/process/detail/windows/async_in.hpp @@ -1,105 +1,105 @@ -// 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
-//
-// 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_WINDOWS_INITIALIZERS_ASYNC_IN_HPP
-#define BOOST_PROCESS_WINDOWS_INITIALIZERS_ASYNC_IN_HPP
- -#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/handles.hpp>
-#include <boost/detail/winapi/handle_info.hpp>
-#include <boost/detail/winapi/error_codes.hpp>
- -#include <boost/asio/write.hpp>
-#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/windows/async_handler.hpp>
-#include <boost/process/detail/windows/asio_fwd.hpp>
-#include <boost/process/async_pipe.hpp>
-#include <memory>
-#include <future>
- - -namespace boost { namespace process { namespace detail { namespace windows {
- - -template<typename Buffer>
-struct async_in_buffer : ::boost::process::detail::windows::handler_base_ext,
- ::boost::process::detail::windows::require_io_service
-{
- Buffer & buf;
- - std::shared_ptr<std::promise<void>> promise;
- async_in_buffer operator>(std::future<void> & fut)
- {
- promise = std::make_shared<std::promise<void>>();
- fut = promise->get_future(); return std::move(*this);
- }
- - std::shared_ptr<boost::process::async_pipe> pipe;
- - async_in_buffer(Buffer & buf) : buf(buf)
- {
- }
- template <typename Executor>
- inline void on_success(Executor&)
- {
- auto pipe = this->pipe;
- - if (this->promise)
- {
- auto promise = this->promise;
- - boost::asio::async_write(*pipe, buf,
- [promise](const boost::system::error_code & ec, std::size_t)
- {
- if (ec && (ec.value() != ::boost::detail::winapi::ERROR_BROKEN_PIPE_))
- {
- std::error_code e(ec.value(), std::system_category());
- promise->set_exception(std::make_exception_ptr(process_error(e)));
- }
- promise->set_value();
- });
- }
- else
- boost::asio::async_write(*pipe, buf,
- [pipe](const boost::system::error_code&, std::size_t){});
- - std::move(*pipe).source().close();
- - - this->pipe = nullptr;
- }
- - template<typename Executor>
- void on_error(Executor &, const std::error_code &) const
- {
- ::boost::detail::winapi::CloseHandle(pipe->native_source());
- }
- - template <typename WindowsExecutor>
- void on_setup(WindowsExecutor &exec)
- {
- if (!pipe)
- pipe = std::make_shared<boost::process::async_pipe>(get_io_service(exec.seq));
- - ::boost::detail::winapi::HANDLE_ source_handle = std::move(*pipe).source().native_handle();
- - boost::detail::winapi::SetHandleInformation(source_handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - exec.startup_info.hStdInput = source_handle;
- exec.startup_info.dwFlags |= boost::detail::winapi::STARTF_USESTDHANDLES_;
- exec.inherit_handles = true;
- }
-};
- - -}}}}
- -#endif
+// 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 +// +// 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_WINDOWS_INITIALIZERS_ASYNC_IN_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_ASYNC_IN_HPP + +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/handle_info.hpp> +#include <boost/winapi/error_codes.hpp> + +#include <boost/asio/write.hpp> +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/windows/async_handler.hpp> +#include <boost/process/detail/windows/asio_fwd.hpp> +#include <boost/process/async_pipe.hpp> +#include <memory> +#include <future> + + +namespace boost { namespace process { namespace detail { namespace windows { + + +template<typename Buffer> +struct async_in_buffer : ::boost::process::detail::windows::handler_base_ext, + ::boost::process::detail::windows::require_io_context +{ + Buffer & buf; + + std::shared_ptr<std::promise<void>> promise; + async_in_buffer operator>(std::future<void> & fut) + { + promise = std::make_shared<std::promise<void>>(); + fut = promise->get_future(); return std::move(*this); + } + + std::shared_ptr<boost::process::async_pipe> pipe; + + async_in_buffer(Buffer & buf) : buf(buf) + { + } + template <typename Executor> + inline void on_success(Executor&) + { + auto pipe = this->pipe; + + if (this->promise) + { + auto promise = this->promise; + + boost::asio::async_write(*pipe, buf, + [promise](const boost::system::error_code & ec, std::size_t) + { + if (ec && (ec.value() != ::boost::winapi::ERROR_BROKEN_PIPE_)) + { + std::error_code e(ec.value(), std::system_category()); + promise->set_exception(std::make_exception_ptr(process_error(e))); + } + promise->set_value(); + }); + } + else + boost::asio::async_write(*pipe, buf, + [pipe](const boost::system::error_code&, std::size_t){}); + + std::move(*pipe).source().close(); + + + this->pipe = nullptr; + } + + template<typename Executor> + void on_error(Executor &, const std::error_code &) const + { + ::boost::winapi::CloseHandle(pipe->native_source()); + } + + template <typename WindowsExecutor> + void on_setup(WindowsExecutor &exec) + { + if (!pipe) + pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq)); + + ::boost::winapi::HANDLE_ source_handle = std::move(*pipe).source().native_handle(); + + boost::winapi::SetHandleInformation(source_handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + exec.startup_info.hStdInput = source_handle; + exec.startup_info.dwFlags |= boost::winapi::STARTF_USESTDHANDLES_; + exec.inherit_handles = true; + } +}; + + +}}}} + +#endif diff --git a/boost/process/detail/windows/async_out.hpp b/boost/process/detail/windows/async_out.hpp index 435f56ebd6..6bcb5e82ae 100644 --- a/boost/process/detail/windows/async_out.hpp +++ b/boost/process/detail/windows/async_out.hpp @@ -1,176 +1,179 @@ -// 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
-//
-// 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_WINDOWS_INITIALIZERS_ASYNC_OUT_HPP
-#define BOOST_PROCESS_WINDOWS_INITIALIZERS_ASYNC_OUT_HPP
- -#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/handles.hpp>
-#include <boost/detail/winapi/handle_info.hpp>
-#include <boost/asio/read.hpp>
-#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/windows/asio_fwd.hpp>
-#include <boost/detail/winapi/error_codes.hpp>
- -#include <istream>
-#include <memory>
-#include <exception>
-#include <future>
- - -namespace boost { namespace process { namespace detail { namespace windows {
- - -template <typename Executor>
-inline void apply_out_handles(Executor &e, void* handle, std::integral_constant<int, 1>, std::integral_constant<int, -1>)
-{
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - e.startup_info.hStdOutput = handle;
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
-}
- -template <typename Executor>
-inline void apply_out_handles(Executor &e, void* handle, std::integral_constant<int, 2>, std::integral_constant<int, -1>)
-{
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - - e.startup_info.hStdError = handle;
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
-}
- -template <typename Executor>
-inline void apply_out_handles(Executor &e, void* handle, std::integral_constant<int, 1>, std::integral_constant<int, 2>)
-{
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - e.startup_info.hStdOutput = handle;
- e.startup_info.hStdError = handle;
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
-}
- -template<int p1, int p2, typename Buffer>
-struct async_out_buffer : ::boost::process::detail::windows::handler_base_ext,
- ::boost::process::detail::windows::require_io_service
-{
- Buffer & buf;
- - std::shared_ptr<boost::process::async_pipe> pipe;
- - - async_out_buffer(Buffer & buf) : buf(buf)
- {
- }
- template <typename Executor>
- inline void on_success(Executor&)
- {
- auto pipe = this->pipe;
- boost::asio::async_read(*pipe, buf,
- [pipe](const boost::system::error_code&, std::size_t){});
- std::move(*pipe).sink().close();
- this->pipe = nullptr;
- - }
- - template<typename Executor>
- void on_error(Executor &, const std::error_code &) const
- {
- std::move(*pipe).sink().close();
- }
- - template <typename WindowsExecutor>
- void on_setup(WindowsExecutor &exec)
- {
- if (!pipe)
- pipe = std::make_shared<boost::process::async_pipe>(get_io_service(exec.seq));
- apply_out_handles(exec, std::move(*pipe).sink().native_handle(),
- std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
- }
-};
- - - -template<int p1, int p2, typename Type>
-struct async_out_future : ::boost::process::detail::windows::handler_base_ext,
- ::boost::process::detail::windows::require_io_service
-{
- std::shared_ptr<boost::process::async_pipe> pipe;
- std::shared_ptr<std::promise<Type>> promise = std::make_shared<std::promise<Type>>();
- std::shared_ptr<boost::asio::streambuf> buffer = std::make_shared<boost::asio::streambuf>();
- - - async_out_future(std::future<Type> & fut)
- {
- fut = promise->get_future();
- }
- template <typename Executor>
- inline void on_success(Executor&)
- {
- auto pipe = this->pipe;
- auto buffer = this->buffer;
- auto promise = this->promise;
- std::move(*pipe).sink().close();
- boost::asio::async_read(*pipe, *buffer,
- [pipe, buffer, promise](const boost::system::error_code& ec, std::size_t)
- {
- if (ec && (ec.value() != ::boost::detail::winapi::ERROR_BROKEN_PIPE_))
- {
- std::error_code e(ec.value(), std::system_category());
- promise->set_exception(std::make_exception_ptr(process_error(e)));
- }
- else
- {
- std::istream is (buffer.get());
- Type arg;
- arg.resize(buffer->size());
- is.read(&*arg.begin(), buffer->size());
- - promise->set_value(std::move(arg));
- - - }
- });
- this->pipe = nullptr;
- this->buffer = nullptr;
- this->promise = nullptr;
- - - }
- - template<typename Executor>
- void on_error(Executor &, const std::error_code &) const
- {
- std::move(*pipe).sink().close();
- }
- - template <typename WindowsExecutor>
- void on_setup(WindowsExecutor &exec)
- {
- if (!pipe)
- pipe = std::make_shared<boost::process::async_pipe>(get_io_service(exec.seq));
- - apply_out_handles(exec, std::move(*pipe).sink().native_handle(),
- std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
- }
-};
- - -}}}}
- -#endif
+// 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 +// +// 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_WINDOWS_INITIALIZERS_ASYNC_OUT_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_ASYNC_OUT_HPP + +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/handle_info.hpp> +#include <boost/winapi/error_codes.hpp> +#include <boost/asio/read.hpp> +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/windows/asio_fwd.hpp> + +#include <istream> +#include <memory> +#include <exception> +#include <future> + + +namespace boost { namespace process { namespace detail { namespace windows { + + +template <typename Executor> +inline void apply_out_handles(Executor &e, void* handle, std::integral_constant<int, 1>, std::integral_constant<int, -1>) +{ + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + e.startup_info.hStdOutput = handle; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; +} + +template <typename Executor> +inline void apply_out_handles(Executor &e, void* handle, std::integral_constant<int, 2>, std::integral_constant<int, -1>) +{ + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + + e.startup_info.hStdError = handle; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; +} + +template <typename Executor> +inline void apply_out_handles(Executor &e, void* handle, std::integral_constant<int, 1>, std::integral_constant<int, 2>) +{ + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + e.startup_info.hStdOutput = handle; + e.startup_info.hStdError = handle; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; +} + +template<int p1, int p2, typename Buffer> +struct async_out_buffer : ::boost::process::detail::windows::handler_base_ext, + ::boost::process::detail::windows::require_io_context +{ + Buffer & buf; + + std::shared_ptr<boost::process::async_pipe> pipe; + + + async_out_buffer(Buffer & buf) : buf(buf) + { + } + template <typename Executor> + inline void on_success(Executor&) + { + auto pipe = this->pipe; + boost::asio::async_read(*pipe, buf, + [pipe](const boost::system::error_code&, std::size_t){}); + std::move(*pipe).sink().close(); + this->pipe = nullptr; + + } + + template<typename Executor> + void on_error(Executor &, const std::error_code &) const + { + std::move(*pipe).sink().close(); + } + + template <typename WindowsExecutor> + void on_setup(WindowsExecutor &exec) + { + if (!pipe) + pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq)); + apply_out_handles(exec, std::move(*pipe).sink().native_handle(), + std::integral_constant<int, p1>(), std::integral_constant<int, p2>()); + } +}; + + + +template<int p1, int p2, typename Type> +struct async_out_future : ::boost::process::detail::windows::handler_base_ext, + ::boost::process::detail::windows::require_io_context +{ + std::shared_ptr<boost::process::async_pipe> pipe; + std::shared_ptr<std::promise<Type>> promise = std::make_shared<std::promise<Type>>(); + std::shared_ptr<boost::asio::streambuf> buffer = std::make_shared<boost::asio::streambuf>(); + + + async_out_future(std::future<Type> & fut) + { + fut = promise->get_future(); + } + template <typename Executor> + inline void on_success(Executor&) + { + auto pipe = this->pipe; + auto buffer = this->buffer; + auto promise = this->promise; + std::move(*pipe).sink().close(); + boost::asio::async_read(*pipe, *buffer, + [pipe, buffer, promise](const boost::system::error_code& ec, std::size_t) + { + if (ec && (ec.value() != ::boost::winapi::ERROR_BROKEN_PIPE_)) + { + std::error_code e(ec.value(), std::system_category()); + promise->set_exception(std::make_exception_ptr(process_error(e))); + } + else + { + std::istream is (buffer.get()); + Type arg; + if (buffer->size() > 0) + { + arg.resize(buffer->size()); + is.read(&*arg.begin(), buffer->size()); + } + + promise->set_value(std::move(arg)); + + + } + }); + this->pipe = nullptr; + this->buffer = nullptr; + this->promise = nullptr; + + + } + + template<typename Executor> + void on_error(Executor &, const std::error_code &) const + { + std::move(*pipe).sink().close(); + } + + template <typename WindowsExecutor> + void on_setup(WindowsExecutor &exec) + { + if (!pipe) + pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq)); + + apply_out_handles(exec, std::move(*pipe).sink().native_handle(), + std::integral_constant<int, p1>(), std::integral_constant<int, p2>()); + } +}; + + +}}}} + +#endif diff --git a/boost/process/detail/windows/async_pipe.hpp b/boost/process/detail/windows/async_pipe.hpp index ca4f3559d0..6cae1a584f 100644 --- a/boost/process/detail/windows/async_pipe.hpp +++ b/boost/process/detail/windows/async_pipe.hpp @@ -6,15 +6,16 @@ #ifndef BOOST_PROCESS_DETAIL_WINDOWS_ASYNC_PIPE_HPP_ #define BOOST_PROCESS_DETAIL_WINDOWS_ASYNC_PIPE_HPP_ -#include <boost/detail/winapi/basic_types.hpp> -#include <boost/detail/winapi/pipes.hpp> -#include <boost/detail/winapi/handles.hpp> -#include <boost/detail/winapi/file_management.hpp> -#include <boost/detail/winapi/get_last_error.hpp> -#include <boost/detail/winapi/access_rights.hpp> -#include <boost/detail/winapi/process.hpp> +#include <boost/winapi/basic_types.hpp> +#include <boost/winapi/pipes.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/file_management.hpp> +#include <boost/winapi/get_last_error.hpp> +#include <boost/winapi/access_rights.hpp> +#include <boost/winapi/process.hpp> #include <boost/process/detail/windows/basic_pipe.hpp> #include <boost/asio/windows/stream_handle.hpp> +#include <atomic> #include <system_error> #include <string> @@ -24,9 +25,9 @@ inline std::string make_pipe_name() { std::string name = "\\\\.\\pipe\\boost_process_auto_pipe_"; - auto pid = ::boost::detail::winapi::GetCurrentProcessId(); + auto pid = ::boost::winapi::GetCurrentProcessId(); - static unsigned long long cnt = 0; + static std::atomic_size_t cnt = 0; name += std::to_string(pid); name += "_"; name += std::to_string(cnt++); @@ -39,33 +40,33 @@ class async_pipe ::boost::asio::windows::stream_handle _source; ::boost::asio::windows::stream_handle _sink ; public: - typedef ::boost::detail::winapi::HANDLE_ native_handle_type; + typedef ::boost::winapi::HANDLE_ native_handle_type; typedef ::boost::asio::windows::stream_handle handle_type; - inline async_pipe(boost::asio::io_service & ios, + inline async_pipe(boost::asio::io_context & ios, const std::string & name = make_pipe_name()) : async_pipe(ios, ios, name) {} - inline async_pipe(boost::asio::io_service & ios_source, - boost::asio::io_service & ios_sink, + inline async_pipe(boost::asio::io_context & ios_source, + boost::asio::io_context & ios_sink, const std::string & name = make_pipe_name()); inline async_pipe(const async_pipe& rhs); async_pipe(async_pipe&& rhs) : _source(std::move(rhs._source)), _sink(std::move(rhs._sink)) { - rhs._source.assign (::boost::detail::winapi::INVALID_HANDLE_VALUE_); - rhs._sink .assign (::boost::detail::winapi::INVALID_HANDLE_VALUE_); + rhs._source.assign (::boost::winapi::INVALID_HANDLE_VALUE_); + rhs._sink .assign (::boost::winapi::INVALID_HANDLE_VALUE_); } template<class CharT, class Traits = std::char_traits<CharT>> - explicit async_pipe(::boost::asio::io_service & ios_source, - ::boost::asio::io_service & ios_sink, + explicit async_pipe(::boost::asio::io_context & ios_source, + ::boost::asio::io_context & ios_sink, const basic_pipe<CharT, Traits> & p) : _source(ios_source, p.native_source()), _sink(ios_sink, p.native_sink()) { } template<class CharT, class Traits = std::char_traits<CharT>> - explicit async_pipe(boost::asio::io_service & ios, const basic_pipe<CharT, Traits> & p) + explicit async_pipe(boost::asio::io_context & ios, const basic_pipe<CharT, Traits> & p) : async_pipe(ios, ios, p) { } @@ -78,10 +79,8 @@ public: ~async_pipe() { - if (_sink .native() != ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - ::boost::detail::winapi::CloseHandle(_sink.native()); - if (_source.native() != ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - ::boost::detail::winapi::CloseHandle(_source.native()); + boost::system::error_code ec; + close(ec); } template<class CharT, class Traits = std::char_traits<CharT>> @@ -100,12 +99,12 @@ public: if (_sink.is_open()) { _sink.close(); - _sink = handle_type(_sink.get_io_service()); + _sink = handle_type(_sink.get_io_context()); } if (_source.is_open()) { _source.close(); - _source = handle_type(_source.get_io_service()); + _source = handle_type(_source.get_io_context()); } } void close(boost::system::error_code & ec) @@ -113,12 +112,12 @@ public: if (_sink.is_open()) { _sink.close(ec); - _sink = handle_type(_sink.get_io_service()); + _sink = handle_type(_sink.get_io_context()); } if (_source.is_open()) { _source.close(ec); - _source = handle_type(_source.get_io_service()); + _source = handle_type(_source.get_io_context()); } } @@ -129,9 +128,9 @@ public: void async_close() { if (_sink.is_open()) - _sink.get_io_service(). post([this]{_sink.close();}); + _sink.get_io_context(). post([this]{_sink.close();}); if (_source.is_open()) - _source.get_io_service().post([this]{_source.close();}); + _source.get_io_context().post([this]{_source.close();}); } template<typename MutableBufferSequence> @@ -145,8 +144,8 @@ public: return _sink.write_some(buffers); } - native_handle_type native_source() const {return const_cast<boost::asio::windows::stream_handle&>(_source).native();} - native_handle_type native_sink () const {return const_cast<boost::asio::windows::stream_handle&>(_sink ).native();} + native_handle_type native_source() const {return const_cast<boost::asio::windows::stream_handle&>(_source).native_handle();} + native_handle_type native_sink () const {return const_cast<boost::asio::windows::stream_handle&>(_sink ).native_handle();} template<typename MutableBufferSequence, typename ReadHandler> @@ -176,47 +175,47 @@ public: handle_type && source() && { return std::move(_source); } handle_type && sink() && { return std::move(_sink); } - handle_type source(::boost::asio::io_service& ios) && + handle_type source(::boost::asio::io_context& ios) && { ::boost::asio::windows::stream_handle stolen(ios, _source.native_handle()); - _source.assign(::boost::detail::winapi::INVALID_HANDLE_VALUE_); + _source.assign(::boost::winapi::INVALID_HANDLE_VALUE_); return stolen; } - handle_type sink (::boost::asio::io_service& ios) && + handle_type sink (::boost::asio::io_context& ios) && { ::boost::asio::windows::stream_handle stolen(ios, _sink.native_handle()); - _sink.assign(::boost::detail::winapi::INVALID_HANDLE_VALUE_); + _sink.assign(::boost::winapi::INVALID_HANDLE_VALUE_); return stolen; } - handle_type source(::boost::asio::io_service& ios) const & + handle_type source(::boost::asio::io_context& ios) const & { - auto proc = ::boost::detail::winapi::GetCurrentProcess(); + auto proc = ::boost::winapi::GetCurrentProcess(); - ::boost::detail::winapi::HANDLE_ source; - auto source_in = const_cast<handle_type&>(_source).native(); - if (source_in == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + ::boost::winapi::HANDLE_ source; + auto source_in = const_cast<handle_type&>(_source).native_handle(); + if (source_in == ::boost::winapi::INVALID_HANDLE_VALUE_) + source = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, source_in, proc, &source, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); return ::boost::asio::windows::stream_handle(ios, source); } - handle_type sink (::boost::asio::io_service& ios) const & + handle_type sink (::boost::asio::io_context& ios) const & { - auto proc = ::boost::detail::winapi::GetCurrentProcess(); + auto proc = ::boost::winapi::GetCurrentProcess(); - ::boost::detail::winapi::HANDLE_ sink; - auto sink_in = const_cast<handle_type&>(_sink).native(); - if (sink_in == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + ::boost::winapi::HANDLE_ sink; + auto sink_in = const_cast<handle_type&>(_sink).native_handle(); + if (sink_in == ::boost::winapi::INVALID_HANDLE_VALUE_) + sink = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, sink_in, proc, &sink, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); return ::boost::asio::windows::stream_handle(ios, sink); @@ -226,32 +225,32 @@ public: async_pipe::async_pipe(const async_pipe& p) : - _source(const_cast<handle_type&>(p._source).get_io_service()), - _sink (const_cast<handle_type&>(p._sink).get_io_service()) + _source(const_cast<handle_type&>(p._source).get_io_context()), + _sink (const_cast<handle_type&>(p._sink).get_io_context()) { - auto proc = ::boost::detail::winapi::GetCurrentProcess(); + auto proc = ::boost::winapi::GetCurrentProcess(); - ::boost::detail::winapi::HANDLE_ source; - ::boost::detail::winapi::HANDLE_ sink; + ::boost::winapi::HANDLE_ source; + ::boost::winapi::HANDLE_ sink; //cannot get the handle from a const object. - auto source_in = const_cast<handle_type&>(p._source).native(); - auto sink_in = const_cast<handle_type&>(p._sink).native(); + auto source_in = const_cast<handle_type&>(p._source).native_handle(); + auto sink_in = const_cast<handle_type&>(p._sink).native_handle(); - if (source_in == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + if (source_in == ::boost::winapi::INVALID_HANDLE_VALUE_) + source = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, source_in, proc, &source, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); - if (sink_in == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + if (sink_in == ::boost::winapi::INVALID_HANDLE_VALUE_) + sink = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, sink_in, proc, &sink, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); _source.assign(source); @@ -259,32 +258,32 @@ async_pipe::async_pipe(const async_pipe& p) : } -async_pipe::async_pipe(boost::asio::io_service & ios_source, - boost::asio::io_service & ios_sink, +async_pipe::async_pipe(boost::asio::io_context & ios_source, + boost::asio::io_context & ios_sink, const std::string & name) : _source(ios_source), _sink(ios_sink) { static constexpr int FILE_FLAG_OVERLAPPED_ = 0x40000000; //temporary - ::boost::detail::winapi::HANDLE_ source = ::boost::detail::winapi::create_named_pipe( + ::boost::winapi::HANDLE_ source = ::boost::winapi::create_named_pipe( name.c_str(), - ::boost::detail::winapi::PIPE_ACCESS_INBOUND_ + ::boost::winapi::PIPE_ACCESS_INBOUND_ | FILE_FLAG_OVERLAPPED_, //write flag 0, 1, 8192, 8192, 0, nullptr); - if (source == boost::detail::winapi::INVALID_HANDLE_VALUE_) + if (source == boost::winapi::INVALID_HANDLE_VALUE_) ::boost::process::detail::throw_last_error("create_named_pipe(" + name + ") failed"); _source.assign(source); - ::boost::detail::winapi::HANDLE_ sink = boost::detail::winapi::create_file( + ::boost::winapi::HANDLE_ sink = boost::winapi::create_file( name.c_str(), - ::boost::detail::winapi::GENERIC_WRITE_, 0, nullptr, - ::boost::detail::winapi::OPEN_EXISTING_, + ::boost::winapi::GENERIC_WRITE_, 0, nullptr, + ::boost::winapi::OPEN_EXISTING_, FILE_FLAG_OVERLAPPED_, //to allow read nullptr); - if (sink == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) + if (sink == ::boost::winapi::INVALID_HANDLE_VALUE_) ::boost::process::detail::throw_last_error("create_file() failed"); _sink.assign(sink); @@ -292,79 +291,79 @@ async_pipe::async_pipe(boost::asio::io_service & ios_source, async_pipe& async_pipe::operator=(const async_pipe & p) { - auto proc = ::boost::detail::winapi::GetCurrentProcess(); + auto proc = ::boost::winapi::GetCurrentProcess(); - ::boost::detail::winapi::HANDLE_ source; - ::boost::detail::winapi::HANDLE_ sink; + ::boost::winapi::HANDLE_ source; + ::boost::winapi::HANDLE_ sink; //cannot get the handle from a const object. auto &source_in = const_cast<::boost::asio::windows::stream_handle &>(p._source); auto &sink_in = const_cast<::boost::asio::windows::stream_handle &>(p._sink); - if (source_in.native() == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( - proc, source_in.native(), proc, &source, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + if (source_in.native_handle() == ::boost::winapi::INVALID_HANDLE_VALUE_) + source = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( + proc, source_in.native_handle(), proc, &source, 0, + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); - if (sink_in.native() == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( - proc, sink_in.native(), proc, &sink, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + if (sink_in.native_handle() == ::boost::winapi::INVALID_HANDLE_VALUE_) + sink = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( + proc, sink_in.native_handle(), proc, &sink, 0, + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); - //so we also assign the io_service - _source = ::boost::asio::windows::stream_handle(source_in.get_io_service(), source); - _sink = ::boost::asio::windows::stream_handle(source_in.get_io_service(), sink); + //so we also assign the io_context + _source = ::boost::asio::windows::stream_handle(source_in.get_io_context(), source); + _sink = ::boost::asio::windows::stream_handle(source_in.get_io_context(), sink); return *this; } async_pipe& async_pipe::operator=(async_pipe && rhs) { - if (_source.native_handle() != ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - ::boost::detail::winapi::CloseHandle(_source.native()); + if (_source.native_handle() != ::boost::winapi::INVALID_HANDLE_VALUE_) + ::boost::winapi::CloseHandle(_source.native_handle()); - if (_sink.native_handle() != ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - ::boost::detail::winapi::CloseHandle(_sink.native()); + if (_sink.native_handle() != ::boost::winapi::INVALID_HANDLE_VALUE_) + ::boost::winapi::CloseHandle(_sink.native_handle()); _source.assign(rhs._source.native_handle()); _sink .assign(rhs._sink .native_handle()); - rhs._source.assign(::boost::detail::winapi::INVALID_HANDLE_VALUE_); - rhs._sink .assign(::boost::detail::winapi::INVALID_HANDLE_VALUE_); + rhs._source.assign(::boost::winapi::INVALID_HANDLE_VALUE_); + rhs._sink .assign(::boost::winapi::INVALID_HANDLE_VALUE_); return *this; } template<class CharT, class Traits> async_pipe::operator basic_pipe<CharT, Traits>() const { - auto proc = ::boost::detail::winapi::GetCurrentProcess(); + auto proc = ::boost::winapi::GetCurrentProcess(); - ::boost::detail::winapi::HANDLE_ source; - ::boost::detail::winapi::HANDLE_ sink; + ::boost::winapi::HANDLE_ source; + ::boost::winapi::HANDLE_ sink; //cannot get the handle from a const object. - auto source_in = const_cast<::boost::asio::windows::stream_handle &>(_source).native(); - auto sink_in = const_cast<::boost::asio::windows::stream_handle &>(_sink).native(); + auto source_in = const_cast<::boost::asio::windows::stream_handle &>(_source).native_handle(); + auto sink_in = const_cast<::boost::asio::windows::stream_handle &>(_sink).native_handle(); - if (source_in == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + if (source_in == ::boost::winapi::INVALID_HANDLE_VALUE_) + source = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, source_in, proc, &source, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); - if (sink_in == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + if (sink_in == ::boost::winapi::INVALID_HANDLE_VALUE_) + sink = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, sink_in, proc, &sink, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); return basic_pipe<CharT, Traits>{source, sink}; diff --git a/boost/process/detail/windows/basic_cmd.hpp b/boost/process/detail/windows/basic_cmd.hpp index 176a052368..fdd0b94469 100644 --- a/boost/process/detail/windows/basic_cmd.hpp +++ b/boost/process/detail/windows/basic_cmd.hpp @@ -1,164 +1,178 @@ -// 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_WINDOWS_BASIC_CMD_HPP_
-#define BOOST_PROCESS_DETAIL_WINDOWS_BASIC_CMD_HPP_
- -#include <boost/algorithm/string/trim.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <boost/process/shell.hpp>
-#include <boost/process/detail/windows/handler.hpp>
- -#include <vector>
-#include <string>
-#include <iterator>
- - -namespace boost
-{
-namespace process
-{
-namespace detail
-{
-namespace windows
-{
- -inline std::string build_args(const std::string & exe, std::vector<std::string> && data)
-{
- std::string st = exe;
- - //put in quotes if it has spaces
- {
- boost::replace_all(st, "\"", "\\\"");
- - auto it = std::find(st.begin(), st.end(), ' ');
- - if (it != st.end())//contains spaces.
- {
- st.insert(st.begin(), '"');
- st += '"';
- }
- }
- - for (auto & arg : data)
- {
- boost::replace_all(arg, "\"", "\\\"");
- - auto it = std::find(arg.begin(), arg.end(), ' ');//contains space?
- if (it != arg.end())//ok, contains spaces.
- {
- //the first one is put directly onto the output,
- //because then I don't have to copy the whole string
- arg.insert(arg.begin(), '"');
- arg += '"'; //thats the post one.
- }
- - if (!st.empty())//first one does not need a preceeding space
- st += ' ';
- - st += arg;
- }
- return st;
-}
- -inline std::wstring build_args(const std::wstring & exe, std::vector<std::wstring> && data)
-{
- std::wstring st = exe;
- for (auto & arg : data)
- {
- boost::replace_all(arg, L"\"", L"\\\"");
- - auto it = std::find(arg.begin(), arg.end(), ' ');//contains space?
- if (it != arg.end())//ok, contains spaces.
- {
- //the first one is put directly onto the output,
- //because then I don't have to copy the whole string
- arg.insert(arg.begin(), L'"');
- arg += L'"'; //thats the post one.
- }
- - if (!st.empty())//first one does not need a preceeding space
- st += L' ';
- - st += arg;
- }
- return st;
-}
- -template<typename Char>
-struct exe_cmd_init : handler_base_ext
-{
- using value_type = Char;
- using string_type = std::basic_string<value_type>;
- - static const char* c_arg(char) { return "/c";}
- static const wchar_t* c_arg(wchar_t) { return L"/c";}
- - exe_cmd_init(const string_type & exe, bool cmd_only = false)
- : exe(exe), args({}), cmd_only(cmd_only) {};
- exe_cmd_init(string_type && exe, bool cmd_only = false)
- : exe(std::move(exe)), args({}), cmd_only(cmd_only) {};
- - exe_cmd_init(string_type && exe, std::vector<string_type> && args)
- : exe(std::move(exe)), args(build_args(this->exe, std::move(args))), cmd_only(false) {};
- template <class Executor>
- void on_setup(Executor& exec) const
- {
- - if (cmd_only && args.empty())
- exec.cmd_line = exe.c_str();
- else
- {
- exec.exe = exe.c_str();
- exec.cmd_line = args.c_str();
- }
- }
- static exe_cmd_init<Char> exe_args(string_type && exe, std::vector<string_type> && args)
- {
- return exe_cmd_init<Char>(std::move(exe), std::move(args));
- }
- static exe_cmd_init<Char> cmd(string_type&& cmd)
- {
- return exe_cmd_init<Char>(std::move(cmd), true);
- }
- static exe_cmd_init<Char> exe_args_shell(string_type && exe, std::vector<string_type> && args)
- {
- std::vector<string_type> args_ = {c_arg(Char()), std::move(exe)};
- args_.insert(args_.end(), std::make_move_iterator(args.begin()), std::make_move_iterator(args.end()));
- string_type sh = get_shell(Char());
- - return exe_cmd_init<Char>(std::move(sh), std::move(args_));
- }
- - static std:: string get_shell(char) {return shell(). string(codecvt()); }
- static std::wstring get_shell(wchar_t) {return shell().wstring(codecvt());}
- - static exe_cmd_init<Char> cmd_shell(string_type&& cmd)
- {
- std::vector<string_type> args = {c_arg(Char()), std::move(cmd)};
- string_type sh = get_shell(Char());
- - return exe_cmd_init<Char>(
- std::move(sh),
- std::move(args));
- }
-private:
- string_type exe;
- string_type args;
- bool cmd_only;
-};
- -}
- - - -}
-}
-}
- - - -#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ARGS_HPP_ */
+// 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_WINDOWS_BASIC_CMD_HPP_ +#define BOOST_PROCESS_DETAIL_WINDOWS_BASIC_CMD_HPP_ + +#include <boost/algorithm/string/trim.hpp> +#include <boost/algorithm/string/replace.hpp> +#include <boost/process/shell.hpp> +#include <boost/process/detail/windows/handler.hpp> + +#include <vector> +#include <string> +#include <iterator> + + +namespace boost +{ +namespace process +{ +namespace detail +{ +namespace windows +{ + +inline std::string build_args(const std::string & exe, std::vector<std::string> && data) +{ + std::string st = exe; + + //put in quotes if it has spaces + { + boost::replace_all(st, "\"", "\\\""); + + auto it = std::find(st.begin(), st.end(), ' '); + + if (it != st.end())//contains spaces. + { + st.insert(st.begin(), '"'); + st += '"'; + } + } + + for (auto & arg : data) + { + boost::replace_all(arg, "\"", "\\\""); + + auto it = std::find(arg.begin(), arg.end(), ' ');//contains space? + if (it != arg.end())//ok, contains spaces. + { + //the first one is put directly onto the output, + //because then I don't have to copy the whole string + arg.insert(arg.begin(), '"'); + arg += '"'; //thats the post one. + } + + if (!st.empty())//first one does not need a preceeding space + st += ' '; + + st += arg; + } + return st; +} + +inline std::wstring build_args(const std::wstring & exe, std::vector<std::wstring> && data) +{ + std::wstring st = exe; + + //put in quotes if it has spaces + { + boost::replace_all(st, L"\"", L"\\\""); + + auto it = std::find(st.begin(), st.end(), L' '); + + if (it != st.end())//contains spaces. + { + st.insert(st.begin(), L'"'); + st += L'"'; + } + } + + for (auto & arg : data) + { + boost::replace_all(arg, L"\"", L"\\\""); + + auto it = std::find(arg.begin(), arg.end(), L' ');//contains space? + if (it != arg.end())//ok, contains spaces. + { + //the first one is put directly onto the output, + //because then I don't have to copy the whole string + arg.insert(arg.begin(), L'"'); + arg += L'"'; //thats the post one. + } + + if (!st.empty())//first one does not need a preceeding space + st += L' '; + + st += arg; + } + return st; +} + +template<typename Char> +struct exe_cmd_init : handler_base_ext +{ + using value_type = Char; + using string_type = std::basic_string<value_type>; + + static const char* c_arg(char) { return "/c";} + static const wchar_t* c_arg(wchar_t) { return L"/c";} + + exe_cmd_init(const string_type & exe, bool cmd_only = false) + : exe(exe), args({}), cmd_only(cmd_only) {}; + exe_cmd_init(string_type && exe, bool cmd_only = false) + : exe(std::move(exe)), args({}), cmd_only(cmd_only) {}; + + exe_cmd_init(string_type && exe, std::vector<string_type> && args) + : exe(std::move(exe)), args(build_args(this->exe, std::move(args))), cmd_only(false) {}; + template <class Executor> + void on_setup(Executor& exec) const + { + + if (cmd_only && args.empty()) + exec.cmd_line = exe.c_str(); + else + { + exec.exe = exe.c_str(); + exec.cmd_line = args.c_str(); + } + } + static exe_cmd_init<Char> exe_args(string_type && exe, std::vector<string_type> && args) + { + return exe_cmd_init<Char>(std::move(exe), std::move(args)); + } + static exe_cmd_init<Char> cmd(string_type&& cmd) + { + return exe_cmd_init<Char>(std::move(cmd), true); + } + static exe_cmd_init<Char> exe_args_shell(string_type && exe, std::vector<string_type> && args) + { + std::vector<string_type> args_ = {c_arg(Char()), std::move(exe)}; + args_.insert(args_.end(), std::make_move_iterator(args.begin()), std::make_move_iterator(args.end())); + string_type sh = get_shell(Char()); + + return exe_cmd_init<Char>(std::move(sh), std::move(args_)); + } + + static std:: string get_shell(char) {return shell(). string(codecvt()); } + static std::wstring get_shell(wchar_t) {return shell().wstring(codecvt());} + + static exe_cmd_init<Char> cmd_shell(string_type&& cmd) + { + std::vector<string_type> args = {c_arg(Char()), std::move(cmd)}; + string_type sh = get_shell(Char()); + + return exe_cmd_init<Char>( + std::move(sh), + std::move(args)); + } +private: + string_type exe; + string_type args; + bool cmd_only; +}; + +} + + + +} +} +} + + + +#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ARGS_HPP_ */ diff --git a/boost/process/detail/windows/basic_pipe.hpp b/boost/process/detail/windows/basic_pipe.hpp index 2471e60f6d..ca691c078e 100644 --- a/boost/process/detail/windows/basic_pipe.hpp +++ b/boost/process/detail/windows/basic_pipe.hpp @@ -6,14 +6,14 @@ #ifndef BOOST_PROCESS_DETAIL_WINDOWS_PIPE_HPP #define BOOST_PROCESS_DETAIL_WINDOWS_PIPE_HPP -#include <boost/detail/winapi/basic_types.hpp> -#include <boost/detail/winapi/error_codes.hpp> -#include <boost/detail/winapi/pipes.hpp> -#include <boost/detail/winapi/handles.hpp> -#include <boost/detail/winapi/file_management.hpp> -#include <boost/detail/winapi/get_last_error.hpp> -#include <boost/detail/winapi/access_rights.hpp> -#include <boost/detail/winapi/process.hpp> +#include <boost/winapi/basic_types.hpp> +#include <boost/winapi/error_codes.hpp> +#include <boost/winapi/pipes.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/file_management.hpp> +#include <boost/winapi/get_last_error.hpp> +#include <boost/winapi/access_rights.hpp> +#include <boost/winapi/process.hpp> #include <boost/process/detail/windows/compare_handles.hpp> #include <system_error> #include <string> @@ -24,33 +24,33 @@ namespace boost { namespace process { namespace detail { namespace windows { template<class CharT, class Traits = std::char_traits<CharT>> class basic_pipe { - ::boost::detail::winapi::HANDLE_ _source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - ::boost::detail::winapi::HANDLE_ _sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::HANDLE_ _source = ::boost::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::HANDLE_ _sink = ::boost::winapi::INVALID_HANDLE_VALUE_; public: typedef CharT char_type ; typedef Traits traits_type; typedef typename Traits::int_type int_type ; typedef typename Traits::pos_type pos_type ; typedef typename Traits::off_type off_type ; - typedef ::boost::detail::winapi::HANDLE_ native_handle_type; + typedef ::boost::winapi::HANDLE_ native_handle_type; - explicit basic_pipe(::boost::detail::winapi::HANDLE_ source, ::boost::detail::winapi::HANDLE_ sink) + explicit basic_pipe(::boost::winapi::HANDLE_ source, ::boost::winapi::HANDLE_ sink) : _source(source), _sink(sink) {} inline explicit basic_pipe(const std::string & name); inline basic_pipe(const basic_pipe& p); basic_pipe(basic_pipe&& lhs) : _source(lhs._source), _sink(lhs._sink) { - lhs._source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - lhs._sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + lhs._source = ::boost::winapi::INVALID_HANDLE_VALUE_; + lhs._sink = ::boost::winapi::INVALID_HANDLE_VALUE_; } inline basic_pipe& operator=(const basic_pipe& p); inline basic_pipe& operator=(basic_pipe&& lhs); ~basic_pipe() { - if (_sink != ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - ::boost::detail::winapi::CloseHandle(_sink); - if (_source != ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - ::boost::detail::winapi::CloseHandle(_source); + if (_sink != ::boost::winapi::INVALID_HANDLE_VALUE_) + ::boost::winapi::CloseHandle(_sink); + if (_source != ::boost::winapi::INVALID_HANDLE_VALUE_) + ::boost::winapi::CloseHandle(_source); } native_handle_type native_source() const {return _source;} native_handle_type native_sink () const {return _sink;} @@ -60,21 +60,21 @@ public: basic_pipe() { - if (!::boost::detail::winapi::CreatePipe(&_source, &_sink, nullptr, 0)) + if (!::boost::winapi::CreatePipe(&_source, &_sink, nullptr, 0)) throw_last_error("CreatePipe() failed"); } int_type write(const char_type * data, int_type count) { - ::boost::detail::winapi::DWORD_ write_len; - if (!::boost::detail::winapi::WriteFile( + ::boost::winapi::DWORD_ write_len; + if (!::boost::winapi::WriteFile( _sink, data, count * sizeof(char_type), &write_len, nullptr )) { auto ec = ::boost::process::detail::get_last_error(); - if ((ec.value() == ::boost::detail::winapi::ERROR_BROKEN_PIPE_) || - (ec.value() == ::boost::detail::winapi::ERROR_NO_DATA_)) + if ((ec.value() == ::boost::winapi::ERROR_BROKEN_PIPE_) || + (ec.value() == ::boost::winapi::ERROR_NO_DATA_)) return 0; else throw process_error(ec, "WriteFile failed"); @@ -83,14 +83,14 @@ public: } int_type read(char_type * data, int_type count) { - ::boost::detail::winapi::DWORD_ read_len; - if (!::boost::detail::winapi::ReadFile( + ::boost::winapi::DWORD_ read_len; + if (!::boost::winapi::ReadFile( _source, data, count * sizeof(char_type), &read_len, nullptr )) { auto ec = ::boost::process::detail::get_last_error(); - if ((ec.value() == ::boost::detail::winapi::ERROR_BROKEN_PIPE_) || - (ec.value() == ::boost::detail::winapi::ERROR_NO_DATA_)) + if ((ec.value() == ::boost::winapi::ERROR_BROKEN_PIPE_) || + (ec.value() == ::boost::winapi::ERROR_NO_DATA_)) return 0; else throw process_error(ec, "ReadFile failed"); @@ -100,38 +100,38 @@ public: bool is_open() { - return (_source != ::boost::detail::winapi::INVALID_HANDLE_VALUE_) || - (_sink != ::boost::detail::winapi::INVALID_HANDLE_VALUE_); + return (_source != ::boost::winapi::INVALID_HANDLE_VALUE_) || + (_sink != ::boost::winapi::INVALID_HANDLE_VALUE_); } void close() { - ::boost::detail::winapi::CloseHandle(_source); - ::boost::detail::winapi::CloseHandle(_sink); - _source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - _sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::CloseHandle(_source); + ::boost::winapi::CloseHandle(_sink); + _source = ::boost::winapi::INVALID_HANDLE_VALUE_; + _sink = ::boost::winapi::INVALID_HANDLE_VALUE_; } }; template<class Char, class Traits> basic_pipe<Char, Traits>::basic_pipe(const basic_pipe & p) { - auto proc = ::boost::detail::winapi::GetCurrentProcess(); + auto proc = ::boost::winapi::GetCurrentProcess(); - if (p._source == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - _source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + if (p._source == ::boost::winapi::INVALID_HANDLE_VALUE_) + _source = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, p._source, proc, &_source, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); - if (p._sink == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - _sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + if (p._sink == ::boost::winapi::INVALID_HANDLE_VALUE_) + _sink = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, p._sink, proc, &_sink, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); } @@ -143,23 +143,23 @@ basic_pipe<Char, Traits>::basic_pipe(const std::string & name) static constexpr int FILE_FLAG_OVERLAPPED_ = 0x40000000; //temporary //static constexpr int FILE_ATTRIBUTE_NORMAL_ = 0x00000080; //temporary - ::boost::detail::winapi::HANDLE_ source = ::boost::detail::winapi::create_named_pipe( + ::boost::winapi::HANDLE_ source = ::boost::winapi::create_named_pipe( name.c_str(), - ::boost::detail::winapi::PIPE_ACCESS_INBOUND_ + ::boost::winapi::PIPE_ACCESS_INBOUND_ | FILE_FLAG_OVERLAPPED_, //write flag 0, 1, 8192, 8192, 0, nullptr); - if (source == boost::detail::winapi::INVALID_HANDLE_VALUE_) + if (source == boost::winapi::INVALID_HANDLE_VALUE_) ::boost::process::detail::throw_last_error("create_named_pipe() failed"); - ::boost::detail::winapi::HANDLE_ sink = boost::detail::winapi::create_file( + ::boost::winapi::HANDLE_ sink = boost::winapi::create_file( name.c_str(), - ::boost::detail::winapi::GENERIC_WRITE_, 0, nullptr, + ::boost::winapi::GENERIC_WRITE_, 0, nullptr, OPEN_EXISTING_, FILE_FLAG_OVERLAPPED_, //to allow read nullptr); - if (sink == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) + if (sink == ::boost::winapi::INVALID_HANDLE_VALUE_) ::boost::process::detail::throw_last_error("create_file() failed"); _source = source; @@ -169,22 +169,22 @@ basic_pipe<Char, Traits>::basic_pipe(const std::string & name) template<class Char, class Traits> basic_pipe<Char, Traits>& basic_pipe<Char, Traits>::operator=(const basic_pipe & p) { - auto proc = ::boost::detail::winapi::GetCurrentProcess(); + auto proc = ::boost::winapi::GetCurrentProcess(); - if (p._source == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - _source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + if (p._source == ::boost::winapi::INVALID_HANDLE_VALUE_) + _source = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, p._source, proc, &_source, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); - if (p._sink == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - _sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - else if (!::boost::detail::winapi::DuplicateHandle( + if (p._sink == ::boost::winapi::INVALID_HANDLE_VALUE_) + _sink = ::boost::winapi::INVALID_HANDLE_VALUE_; + else if (!::boost::winapi::DuplicateHandle( proc, p._sink, proc, &_sink, 0, - static_cast<::boost::detail::winapi::BOOL_>(true), - ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_)) + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) throw_last_error("Duplicate Pipe Failed"); return *this; @@ -193,16 +193,16 @@ basic_pipe<Char, Traits>& basic_pipe<Char, Traits>::operator=(const basic_pipe & template<class Char, class Traits> basic_pipe<Char, Traits>& basic_pipe<Char, Traits>::operator=(basic_pipe && lhs) { - if (_source != ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - ::boost::detail::winapi::CloseHandle(_source); + if (_source != ::boost::winapi::INVALID_HANDLE_VALUE_) + ::boost::winapi::CloseHandle(_source); - if (_sink != ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - ::boost::detail::winapi::CloseHandle(_sink); + if (_sink != ::boost::winapi::INVALID_HANDLE_VALUE_) + ::boost::winapi::CloseHandle(_sink); _source = lhs._source; _sink = lhs._sink; - lhs._source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - lhs._sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + lhs._source = ::boost::winapi::INVALID_HANDLE_VALUE_; + lhs._sink = ::boost::winapi::INVALID_HANDLE_VALUE_; return *this; } diff --git a/boost/process/detail/windows/child_handle.hpp b/boost/process/detail/windows/child_handle.hpp index 4e809be9fc..afdeb7ab4b 100644 --- a/boost/process/detail/windows/child_handle.hpp +++ b/boost/process/detail/windows/child_handle.hpp @@ -11,9 +11,9 @@ #define BOOST_PROCESS_WINDOWS_CHILD_HPP #include <boost/move/move.hpp> -#include <boost/detail/winapi/handles.hpp> -#include <boost/detail/winapi/process.hpp> -#include <boost/detail/winapi/jobs.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/process.hpp> +#include <boost/winapi/jobs.hpp> namespace boost { namespace process { namespace detail { namespace windows { @@ -21,18 +21,18 @@ typedef int pid_t; struct child_handle { - ::boost::detail::winapi::PROCESS_INFORMATION_ proc_info{nullptr, nullptr, 0,0}; + ::boost::winapi::PROCESS_INFORMATION_ proc_info{nullptr, nullptr, 0,0}; - explicit child_handle(const ::boost::detail::winapi::PROCESS_INFORMATION_ &pi) : + explicit child_handle(const ::boost::winapi::PROCESS_INFORMATION_ &pi) : proc_info(pi) {} explicit child_handle(pid_t pid) : proc_info{nullptr, nullptr, 0,0} { - auto h = ::boost::detail::winapi::OpenProcess( - ::boost::detail::winapi::PROCESS_ALL_ACCESS_, - static_cast<::boost::detail::winapi::BOOL_>(0), + auto h = ::boost::winapi::OpenProcess( + ::boost::winapi::PROCESS_ALL_ACCESS_, + static_cast<::boost::winapi::BOOL_>(0), pid); if (h == nullptr) @@ -44,23 +44,23 @@ struct child_handle child_handle() = default; ~child_handle() { - ::boost::detail::winapi::CloseHandle(proc_info.hProcess); - ::boost::detail::winapi::CloseHandle(proc_info.hThread); + ::boost::winapi::CloseHandle(proc_info.hProcess); + ::boost::winapi::CloseHandle(proc_info.hThread); } child_handle(const child_handle & c) = delete; child_handle(child_handle && c) : proc_info(c.proc_info) { - c.proc_info.hProcess = ::boost::detail::winapi::invalid_handle_value; - c.proc_info.hThread = ::boost::detail::winapi::invalid_handle_value; + c.proc_info.hProcess = ::boost::winapi::invalid_handle_value; + c.proc_info.hThread = ::boost::winapi::invalid_handle_value; } child_handle &operator=(const child_handle & c) = delete; child_handle &operator=(child_handle && c) { - ::boost::detail::winapi::CloseHandle(proc_info.hProcess); - ::boost::detail::winapi::CloseHandle(proc_info.hThread); + ::boost::winapi::CloseHandle(proc_info.hProcess); + ::boost::winapi::CloseHandle(proc_info.hThread); proc_info = c.proc_info; - c.proc_info.hProcess = ::boost::detail::winapi::invalid_handle_value; - c.proc_info.hThread = ::boost::detail::winapi::invalid_handle_value; + c.proc_info.hProcess = ::boost::winapi::invalid_handle_value; + c.proc_info.hThread = ::boost::winapi::invalid_handle_value; return *this; } @@ -69,25 +69,25 @@ struct child_handle return static_cast<int>(proc_info.dwProcessId); } - typedef ::boost::detail::winapi::HANDLE_ process_handle_t; + typedef ::boost::winapi::HANDLE_ process_handle_t; process_handle_t process_handle() const { return proc_info.hProcess; } bool valid() const { return (proc_info.hProcess != nullptr) && - (proc_info.hProcess != ::boost::detail::winapi::INVALID_HANDLE_VALUE_); + (proc_info.hProcess != ::boost::winapi::INVALID_HANDLE_VALUE_); } bool in_group() const { - ::boost::detail::winapi::BOOL_ value; - if (!::boost::detail::winapi::IsProcessInJob(proc_info.hProcess, nullptr, &value)) + ::boost::winapi::BOOL_ value; + if (!::boost::winapi::IsProcessInJob(proc_info.hProcess, nullptr, &value)) throw_last_error("IsProcessinJob Failed"); return value!=0; } bool in_group(std::error_code &ec) const noexcept { - ::boost::detail::winapi::BOOL_ value; - if (!::boost::detail::winapi::IsProcessInJob(proc_info.hProcess, nullptr, &value)) + ::boost::winapi::BOOL_ value; + if (!::boost::winapi::IsProcessInJob(proc_info.hProcess, nullptr, &value)) ec = get_last_error(); return value!=0; } diff --git a/boost/process/detail/windows/close_in.hpp b/boost/process/detail/windows/close_in.hpp index 5100564b4c..63ff772f77 100644 --- a/boost/process/detail/windows/close_in.hpp +++ b/boost/process/detail/windows/close_in.hpp @@ -10,8 +10,8 @@ #ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_IN_HPP #define BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_IN_HPP -#include <boost/detail/winapi/process.hpp> -#include <boost/detail/winapi/handles.hpp> +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> #include <boost/process/detail/handler_base.hpp> namespace boost { namespace process { namespace detail { namespace windows { @@ -21,8 +21,8 @@ struct close_in : public ::boost::process::detail::handler_base template <class WindowsExecutor> void on_setup(WindowsExecutor &e) const { - e.startup_info.hStdInput = boost::detail::winapi::INVALID_HANDLE_VALUE_; - e.startup_info.dwFlags |= boost::detail::winapi::STARTF_USESTDHANDLES_; + e.startup_info.hStdInput = boost::winapi::INVALID_HANDLE_VALUE_; + e.startup_info.dwFlags |= boost::winapi::STARTF_USESTDHANDLES_; } }; diff --git a/boost/process/detail/windows/close_out.hpp b/boost/process/detail/windows/close_out.hpp index dc3de412fc..bec4b0195c 100644 --- a/boost/process/detail/windows/close_out.hpp +++ b/boost/process/detail/windows/close_out.hpp @@ -10,8 +10,8 @@ #ifndef BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_OUT_HPP #define BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_OUT_HPP -#include <boost/detail/winapi/process.hpp> -#include <boost/detail/winapi/handles.hpp> +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> #include <boost/process/detail/handler_base.hpp> namespace boost { namespace process { namespace detail { namespace windows { @@ -27,25 +27,25 @@ template<> template<typename WindowsExecutor> void close_out<1,-1>::on_setup(WindowsExecutor &e) const { - e.startup_info.hStdOutput = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_; + e.startup_info.hStdOutput = ::boost::winapi::INVALID_HANDLE_VALUE_; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; } template<> template<typename WindowsExecutor> void close_out<2,-1>::on_setup(WindowsExecutor &e) const { - e.startup_info.hStdError = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_; + e.startup_info.hStdError = ::boost::winapi::INVALID_HANDLE_VALUE_; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; } template<> template<typename WindowsExecutor> void close_out<1,2>::on_setup(WindowsExecutor &e) const { - e.startup_info.hStdOutput = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - e.startup_info.hStdError = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; - e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_; + e.startup_info.hStdOutput = ::boost::winapi::INVALID_HANDLE_VALUE_; + e.startup_info.hStdError = ::boost::winapi::INVALID_HANDLE_VALUE_; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; } }}}} diff --git a/boost/process/detail/windows/cmd.hpp b/boost/process/detail/windows/cmd.hpp index c76c08a546..2298debf31 100644 --- a/boost/process/detail/windows/cmd.hpp +++ b/boost/process/detail/windows/cmd.hpp @@ -1,49 +1,49 @@ -// 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)
+// 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_WINDOWS_CMD_HPP_
-#define BOOST_PROCESS_WINDOWS_CMD_HPP_
+#ifndef BOOST_PROCESS_WINDOWS_CMD_HPP_ +#define BOOST_PROCESS_WINDOWS_CMD_HPP_ -#include <string>
+#include <string> -namespace boost
-{
-namespace process
-{
-namespace detail
-{
-namespace windows
-{
+namespace boost +{ +namespace process +{ +namespace detail +{ +namespace windows +{ -template<typename CharType>
-struct cmd_setter_ : ::boost::process::detail::handler_base
-{
- typedef CharType value_type;
- typedef std::basic_string<value_type> string_type;
+template<typename CharType> +struct cmd_setter_ : ::boost::process::detail::handler_base +{ + typedef CharType value_type; + typedef std::basic_string<value_type> string_type; - cmd_setter_(string_type && cmd_line) : _cmd_line(std::move(cmd_line)) {}
- cmd_setter_(const string_type & cmd_line) : _cmd_line(cmd_line) {}
- template <class Executor>
- void on_setup(Executor& exec)
- {
- exec.cmd_line = _cmd_line.c_str();
- }
- const string_type & str() const {return _cmd_line;}
+ cmd_setter_(string_type && cmd_line) : _cmd_line(std::move(cmd_line)) {} + cmd_setter_(const string_type & cmd_line) : _cmd_line(cmd_line) {} + template <class Executor> + void on_setup(Executor& exec) + { + exec.cmd_line = _cmd_line.c_str(); + } + const string_type & str() const {return _cmd_line;} -private:
- string_type _cmd_line;
-};
+private: + string_type _cmd_line; +}; -}
+} -}
-}
-}
+} +} +} -#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ARGS_HPP_ */
+#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ARGS_HPP_ */ diff --git a/boost/process/detail/windows/compare_handles.hpp b/boost/process/detail/windows/compare_handles.hpp index 1eafd43209..03361492ac 100644 --- a/boost/process/detail/windows/compare_handles.hpp +++ b/boost/process/detail/windows/compare_handles.hpp @@ -6,28 +6,28 @@ #ifndef BOOST_PROCESS_DETAIL_WINDOWS_COMPARE_HANDLES_HPP_ #define BOOST_PROCESS_DETAIL_WINDOWS_COMPARE_HANDLES_HPP_ -#include <boost/detail/winapi/handles.hpp> -#include <boost/detail/winapi/file_management.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/file_management.hpp> #include <boost/process/detail/config.hpp> namespace boost { namespace process { namespace detail { namespace windows { -inline bool compare_handles(boost::detail::winapi::HANDLE_ lhs, boost::detail::winapi::HANDLE_ rhs) +inline bool compare_handles(boost::winapi::HANDLE_ lhs, boost::winapi::HANDLE_ rhs) { - if ( (lhs == ::boost::detail::winapi::INVALID_HANDLE_VALUE_) - || (rhs == ::boost::detail::winapi::INVALID_HANDLE_VALUE_)) + if ( (lhs == ::boost::winapi::INVALID_HANDLE_VALUE_) + || (rhs == ::boost::winapi::INVALID_HANDLE_VALUE_)) return false; if (lhs == rhs) return true; - ::boost::detail::winapi::BY_HANDLE_FILE_INFORMATION_ lhs_info{0,{0,0},{0,0},{0,0},0,0,0,0,0,0}; - ::boost::detail::winapi::BY_HANDLE_FILE_INFORMATION_ rhs_info{0,{0,0},{0,0},{0,0},0,0,0,0,0,0}; + ::boost::winapi::BY_HANDLE_FILE_INFORMATION_ lhs_info{0,{0,0},{0,0},{0,0},0,0,0,0,0,0}; + ::boost::winapi::BY_HANDLE_FILE_INFORMATION_ rhs_info{0,{0,0},{0,0},{0,0},0,0,0,0,0,0}; - if (!::boost::detail::winapi::GetFileInformationByHandle(lhs, &lhs_info)) + if (!::boost::winapi::GetFileInformationByHandle(lhs, &lhs_info)) ::boost::process::detail::throw_last_error("GetFileInformationByHandle"); - if (!::boost::detail::winapi::GetFileInformationByHandle(rhs, &rhs_info)) + if (!::boost::winapi::GetFileInformationByHandle(rhs, &rhs_info)) ::boost::process::detail::throw_last_error("GetFileInformationByHandle"); return (lhs_info.nFileIndexHigh == rhs_info.nFileIndexHigh) diff --git a/boost/process/detail/windows/env_init.hpp b/boost/process/detail/windows/env_init.hpp index 036a29809f..4d3279587c 100644 --- a/boost/process/detail/windows/env_init.hpp +++ b/boost/process/detail/windows/env_init.hpp @@ -7,8 +7,8 @@ #ifndef BOOST_PROCESS_DETAIL_WINDOWS_ENV_INIT_HPP_ #define BOOST_PROCESS_DETAIL_WINDOWS_ENV_INIT_HPP_ -#include <boost/detail/winapi/error_codes.hpp> -#include <boost/detail/winapi/process.hpp> +#include <boost/winapi/error_codes.hpp> +#include <boost/winapi/process.hpp> #include <boost/process/detail/config.hpp> @@ -25,10 +25,10 @@ struct env_init : public ::boost::process::detail::handler_base env_init(boost::process::basic_environment<Char> && env) : env(std::move(env)) {}; env_init(const boost::process::basic_environment<Char> & env) : env(env) {}; - constexpr static ::boost::detail::winapi::DWORD_ creation_flag(char) {return 0u;} - constexpr static ::boost::detail::winapi::DWORD_ creation_flag(wchar_t) + constexpr static ::boost::winapi::DWORD_ creation_flag(char) {return 0u;} + constexpr static ::boost::winapi::DWORD_ creation_flag(wchar_t) { - return ::boost::detail::winapi::CREATE_UNICODE_ENVIRONMENT_; + return ::boost::winapi::CREATE_UNICODE_ENVIRONMENT_; } template <class WindowsExecutor> @@ -37,7 +37,7 @@ struct env_init : public ::boost::process::detail::handler_base auto e = env.native_handle(); if (*e == null_char<char>()) { - exec.set_error(std::error_code(::boost::detail::winapi::ERROR_BAD_ENVIRONMENT_, std::system_category()), + exec.set_error(std::error_code(::boost::winapi::ERROR_BAD_ENVIRONMENT_, std::system_category()), "Empty Environment"); } diff --git a/boost/process/detail/windows/environment.hpp b/boost/process/detail/windows/environment.hpp index b73da1bd42..13aa587da8 100644 --- a/boost/process/detail/windows/environment.hpp +++ b/boost/process/detail/windows/environment.hpp @@ -1,356 +1,354 @@ -// 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_WINDOWS_ENV_STORAGE_HPP_
-#define BOOST_PROCESS_DETAIL_WINDOWS_ENV_STORAGE_HPP_
- -#include <string>
-#include <vector>
-#include <unordered_map>
-#include <boost/detail/winapi/error_codes.hpp>
-#include <boost/detail/winapi/environment.hpp>
-#include <boost/process/detail/config.hpp>
-#include <boost/detail/winapi/get_current_process.hpp>
-#include <boost/detail/winapi/get_current_process_id.hpp>
-#include <algorithm>
-#include <boost/process/locale.hpp>
- -namespace boost { namespace process { namespace detail { namespace windows {
- -template<typename Char>
-class native_environment_impl
-{
- static void _deleter(Char* p) {boost::detail::winapi::free_environment_strings(p);};
- std::unique_ptr<Char[], void(*)(Char*)> _buf{boost::detail::winapi::get_environment_strings<Char>(), &native_environment_impl::_deleter};
- static inline std::vector<Char*> _load_var(Char* p);
- std::vector<Char*> _env_arr{_load_var(_buf.get())};
-public:
- using char_type = Char;
- using pointer_type = const char_type*;
- using string_type = std::basic_string<char_type>;
- using native_handle_type = pointer_type;
- void reload()
- {
- _buf.reset(boost::detail::winapi::get_environment_strings<Char>());
- _env_arr = _load_var(_buf.get());
- _env_impl = &*_env_arr.begin();
- }
- - string_type get(const pointer_type id);
- void set(const pointer_type id, const pointer_type value);
- void reset(const pointer_type id);
- - string_type get(const string_type & id) {return get(id.c_str());}
- void set(const string_type & id, const string_type & value) {set(id.c_str(), value.c_str()); }
- void reset(const string_type & id) {reset(id.c_str());}
- - native_environment_impl() = default;
- native_environment_impl(const native_environment_impl& ) = delete;
- native_environment_impl(native_environment_impl && ) = default;
- native_environment_impl & operator=(const native_environment_impl& ) = delete;
- native_environment_impl & operator=(native_environment_impl && ) = default;
- Char ** _env_impl = &*_env_arr.begin();
- - native_handle_type native_handle() const {return _buf.get();}
-};
- -template<typename Char>
-inline auto native_environment_impl<Char>::get(const pointer_type id) -> string_type
-{
- Char buf[4096];
- auto size = boost::detail::winapi::get_environment_variable(id, buf, sizeof(buf));
- if (size == 0) //failed
- {
- auto err = ::boost::detail::winapi::GetLastError();
- if (err == ::boost::detail::winapi::ERROR_ENVVAR_NOT_FOUND_)//well, then we consider that an empty value
- return "";
- else
- throw process_error(std::error_code(err, std::system_category()),
- "GetEnvironmentVariable() failed");
- }
- - if (size == sizeof(buf)) //the return size gives the size without the null, so I know this went wrong
- {
- /*limit defined here https://msdn.microsoft.com/en-us/library/windows/desktop/ms683188(v=vs.85).aspx
- * but I used 32768 so it is a multiple of 4096.
- */
- constexpr static std::size_t max_size = 32768;
- //Handle variables longer then buf.
- std::size_t buf_size = sizeof(buf);
- while (buf_size <= max_size)
- {
- std::vector<Char> buf(buf_size);
- auto size = boost::detail::winapi::get_environment_variable(id, buf.data(), buf.size());
- - if (size == buf_size) //buffer to small
- buf_size *= 2;
- else if (size == 0)
- ::boost::process::detail::throw_last_error("GetEnvironmentVariable() failed");
- else
- return std::basic_string<Char>(
- buf.data(), buf.data()+ size + 1);
- - }
- - }
- return std::basic_string<Char>(buf, buf+size+1);
-}
- -template<typename Char>
-inline void native_environment_impl<Char>::set(const pointer_type id, const pointer_type value)
-{
- boost::detail::winapi::set_environment_variable(id, value);
-}
- -template<typename Char>
-inline void native_environment_impl<Char>::reset(const pointer_type id)
-{
- boost::detail::winapi::set_environment_variable(id, nullptr);
-}
- -template<typename Char>
-std::vector<Char*> native_environment_impl<Char>::_load_var(Char* p)
-{
- std::vector<Char*> ret;
- if (*p != null_char<Char>())
- {
- ret.push_back(p);
- while ((*p != null_char<Char>()) || (*(p+1) != null_char<Char>()))
- {
- if (*p==null_char<Char>())
- {
- p++;
- ret.push_back(p);
- }
- else
- p++;
- }
- }
- p++;
- ret.push_back(nullptr);
- - return ret;
-}
- - -template<typename Char>
-struct basic_environment_impl
-{
- std::vector<Char> _data = {null_char<Char>()};
- static std::vector<Char*> _load_var(Char* p);
- std::vector<Char*> _env_arr{_load_var(_data.data())};
-public:
- using char_type = Char;
- using pointer_type = const char_type*;
- using string_type = std::basic_string<char_type>;
- using native_handle_type = pointer_type;
- - std::size_t size() const { return _data.size();}
- - void reload()
- {
- _env_arr = _load_var(_data.data());
- _env_impl = _env_arr.data();
- }
- - string_type get(const pointer_type id) {return get(string_type(id));}
- void set(const pointer_type id, const pointer_type value) {set(string_type(id), value);}
- void reset(const pointer_type id) {reset(string_type(id));}
- - string_type get(const string_type & id);
- void set(const string_type & id, const string_type & value);
- void reset(const string_type & id);
- - inline basic_environment_impl(const native_environment_impl<Char> & nei);
- basic_environment_impl() = default;
- basic_environment_impl(const basic_environment_impl& rhs)
- : _data(rhs._data)
- {
- }
- basic_environment_impl(basic_environment_impl && rhs)
- : _data(std::move(rhs._data)),
- _env_arr(std::move(rhs._env_arr)),
- _env_impl(_env_arr.data())
- {
- }
- basic_environment_impl &operator=(basic_environment_impl && rhs)
- {
- _data = std::move(rhs._data);
- //reload();
- _env_arr = std::move(rhs._env_arr);
- _env_impl = _env_arr.data();
- - return *this;
- }
- basic_environment_impl & operator=(const basic_environment_impl& rhs)
- {
- _data = rhs._data;
- reload();
- return *this;
- }
- - template<typename CharR>
- explicit inline basic_environment_impl(
- const basic_environment_impl<CharR>& rhs,
- const ::boost::process::codecvt_type & cv = ::boost::process::codecvt())
- : _data(::boost::process::detail::convert(rhs._data, cv))
- {
- }
- - template<typename CharR>
- basic_environment_impl & operator=(const basic_environment_impl<CharR>& rhs)
- {
- _data = ::boost::process::detail::convert(rhs._data);
- _env_arr = _load_var(&*_data.begin());
- _env_impl = &*_env_arr.begin();
- return *this;
- }
- - Char ** _env_impl = &*_env_arr.begin();
- - native_handle_type native_handle() const {return &*_data.begin();}
-};
- - -template<typename Char>
-basic_environment_impl<Char>::basic_environment_impl(const native_environment_impl<Char> & nei)
-{
- auto beg = nei.native_handle();
- auto p = beg;
- while ((*p != null_char<Char>()) || (*(p+1) != null_char<Char>()))
- p++;
- p++; //pointing to the second nullchar
- p++; //to get the pointer behing the second nullchar, so it's end.
- - this->_data.assign(beg, p);
- this->reload();
-}
- - -template<typename Char>
-inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_type
-{
- - if (std::equal(id.begin(), id.end(), _data.begin()) && (_data[id.size()] == equal_sign<Char>()))
- return string_type(_data.data()); //null-char is handled by the string.
- - std::vector<Char> seq = {'\0'}; //using a vector, because strings might cause problems with nullchars
- seq.insert(seq.end(), id.begin(), id.end());
- seq.push_back('=');
- - auto itr = std::search(_data.begin(), _data.end(), seq.begin(), seq.end());
- - if (itr == _data.end()) //not found
- return "";
- - itr += seq.size(); //advance to the value behind the '='; the std::string will take care of finding the null-char.
- - return string_type(&*itr);
-}
- -template<typename Char>
-inline void basic_environment_impl<Char>::set(const string_type &id, const string_type &value)
-{
- reset(id);
+// 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_WINDOWS_ENV_STORAGE_HPP_ +#define BOOST_PROCESS_DETAIL_WINDOWS_ENV_STORAGE_HPP_ + +#include <string> +#include <vector> +#include <unordered_map> +#include <boost/winapi/error_codes.hpp> +#include <boost/winapi/environment.hpp> +#include <boost/winapi/get_current_process.hpp> +#include <boost/winapi/get_current_process_id.hpp> +#include <boost/process/detail/config.hpp> +#include <algorithm> +#include <boost/process/locale.hpp> + +namespace boost { namespace process { namespace detail { namespace windows { + +template<typename Char> +class native_environment_impl +{ + static void _deleter(Char* p) {boost::winapi::free_environment_strings(p);}; + std::unique_ptr<Char[], void(*)(Char*)> _buf{boost::winapi::get_environment_strings<Char>(), &native_environment_impl::_deleter}; + static inline std::vector<Char*> _load_var(Char* p); + std::vector<Char*> _env_arr{_load_var(_buf.get())}; +public: + using char_type = Char; + using pointer_type = const char_type*; + using string_type = std::basic_string<char_type>; + using native_handle_type = pointer_type; + void reload() + { + _buf.reset(boost::winapi::get_environment_strings<Char>()); + _env_arr = _load_var(_buf.get()); + _env_impl = &*_env_arr.begin(); + } + + string_type get(const pointer_type id); + void set(const pointer_type id, const pointer_type value); + void reset(const pointer_type id); + + string_type get(const string_type & id) {return get(id.c_str());} + void set(const string_type & id, const string_type & value) {set(id.c_str(), value.c_str()); } + void reset(const string_type & id) {reset(id.c_str());} + + native_environment_impl() = default; + native_environment_impl(const native_environment_impl& ) = delete; + native_environment_impl(native_environment_impl && ) = default; + native_environment_impl & operator=(const native_environment_impl& ) = delete; + native_environment_impl & operator=(native_environment_impl && ) = default; + Char ** _env_impl = &*_env_arr.begin(); + + native_handle_type native_handle() const {return _buf.get();} +}; + +template<typename Char> +inline auto native_environment_impl<Char>::get(const pointer_type id) -> string_type +{ + Char buf[4096]; + auto size = boost::winapi::get_environment_variable(id, buf, sizeof(buf)); + if (size == 0) //failed + { + auto err = ::boost::winapi::GetLastError(); + if (err == ::boost::winapi::ERROR_ENVVAR_NOT_FOUND_)//well, then we consider that an empty value + return ""; + else + throw process_error(std::error_code(err, std::system_category()), + "GetEnvironmentVariable() failed"); + } + + if (size == sizeof(buf)) //the return size gives the size without the null, so I know this went wrong + { + /*limit defined here https://msdn.microsoft.com/en-us/library/windows/desktop/ms683188(v=vs.85).aspx + * but I used 32768 so it is a multiple of 4096. + */ + constexpr static std::size_t max_size = 32768; + //Handle variables longer then buf. + std::size_t buf_size = sizeof(buf); + while (buf_size <= max_size) + { + std::vector<Char> buf(buf_size); + auto size = boost::winapi::get_environment_variable(id, buf.data(), buf.size()); + + if (size == buf_size) //buffer to small + buf_size *= 2; + else if (size == 0) + ::boost::process::detail::throw_last_error("GetEnvironmentVariable() failed"); + else + return std::basic_string<Char>( + buf.data(), buf.data()+ size + 1); + + } + + } + return std::basic_string<Char>(buf, buf+size+1); +} + +template<typename Char> +inline void native_environment_impl<Char>::set(const pointer_type id, const pointer_type value) +{ + boost::winapi::set_environment_variable(id, value); +} + +template<typename Char> +inline void native_environment_impl<Char>::reset(const pointer_type id) +{ + boost::winapi::set_environment_variable(id, nullptr); +} + +template<typename Char> +std::vector<Char*> native_environment_impl<Char>::_load_var(Char* p) +{ + std::vector<Char*> ret; + if (*p != null_char<Char>()) + { + ret.push_back(p); + while ((*p != null_char<Char>()) || (*(p+1) != null_char<Char>())) + { + if (*p==null_char<Char>()) + { + p++; + ret.push_back(p); + } + else + p++; + } + } + p++; + ret.push_back(nullptr); + + return ret; +} + + +template<typename Char> +struct basic_environment_impl +{ + std::vector<Char> _data = {null_char<Char>()}; + static std::vector<Char*> _load_var(Char* p); + std::vector<Char*> _env_arr{_load_var(_data.data())}; +public: + using char_type = Char; + using pointer_type = const char_type*; + using string_type = std::basic_string<char_type>; + using native_handle_type = pointer_type; + + std::size_t size() const { return _data.size();} + + void reload() + { + _env_arr = _load_var(_data.data()); + _env_impl = _env_arr.data(); + } + + string_type get(const pointer_type id) {return get(string_type(id));} + void set(const pointer_type id, const pointer_type value) {set(string_type(id), value);} + void reset(const pointer_type id) {reset(string_type(id));} + + string_type get(const string_type & id); + void set(const string_type & id, const string_type & value); + void reset(const string_type & id); + + inline basic_environment_impl(const native_environment_impl<Char> & nei); + basic_environment_impl() = default; + basic_environment_impl(const basic_environment_impl& rhs) + : _data(rhs._data) + { + } + basic_environment_impl(basic_environment_impl && rhs) + : _data(std::move(rhs._data)), + _env_arr(std::move(rhs._env_arr)), + _env_impl(_env_arr.data()) + { + } + basic_environment_impl &operator=(basic_environment_impl && rhs) + { + _data = std::move(rhs._data); + //reload(); + _env_arr = std::move(rhs._env_arr); + _env_impl = _env_arr.data(); + + return *this; + } + basic_environment_impl & operator=(const basic_environment_impl& rhs) + { + _data = rhs._data; + reload(); + return *this; + } + + template<typename CharR> + explicit inline basic_environment_impl( + const basic_environment_impl<CharR>& rhs, + const ::boost::process::codecvt_type & cv = ::boost::process::codecvt()) + : _data(::boost::process::detail::convert(rhs._data, cv)) + { + } + + template<typename CharR> + basic_environment_impl & operator=(const basic_environment_impl<CharR>& rhs) + { + _data = ::boost::process::detail::convert(rhs._data); + _env_arr = _load_var(&*_data.begin()); + _env_impl = &*_env_arr.begin(); + return *this; + } + + Char ** _env_impl = &*_env_arr.begin(); + + native_handle_type native_handle() const {return &*_data.begin();} +}; + + +template<typename Char> +basic_environment_impl<Char>::basic_environment_impl(const native_environment_impl<Char> & nei) +{ + auto beg = nei.native_handle(); + auto p = beg; + while ((*p != null_char<Char>()) || (*(p+1) != null_char<Char>())) + p++; + p++; //pointing to the second nullchar + p++; //to get the pointer behing the second nullchar, so it's end. + + this->_data.assign(beg, p); + this->reload(); +} + + +template<typename Char> +inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_type +{ + + if (std::equal(id.begin(), id.end(), _data.begin()) && (_data[id.size()] == equal_sign<Char>())) + return string_type(_data.data()); //null-char is handled by the string. + + std::vector<Char> seq = {'\0'}; //using a vector, because strings might cause problems with nullchars + seq.insert(seq.end(), id.begin(), id.end()); + seq.push_back('='); + + auto itr = std::search(_data.begin(), _data.end(), seq.begin(), seq.end()); + + if (itr == _data.end()) //not found + return ""; + + itr += seq.size(); //advance to the value behind the '='; the std::string will take care of finding the null-char. + + return string_type(&*itr); +} + +template<typename Char> +inline void basic_environment_impl<Char>::set(const string_type &id, const string_type &value) +{ + reset(id); - std::vector<Char> insertion;
+ std::vector<Char> insertion; - insertion.insert(insertion.end(), id.begin(), id.end());
- insertion.push_back('=');
- insertion.insert(insertion.end(), value.begin(), value.end());
- insertion.push_back('\0');
+ insertion.insert(insertion.end(), id.begin(), id.end()); + insertion.push_back('='); + insertion.insert(insertion.end(), value.begin(), value.end()); + insertion.push_back('\0'); - _data.insert(_data.end() -1, insertion.begin(), insertion.end());
+ _data.insert(_data.end() -1, insertion.begin(), insertion.end()); - reload();
-}
+ reload(); +} -template<typename Char>
-inline void basic_environment_impl<Char>::reset(const string_type &id)
-{
- //ok, we need to check the size of data first
- if (id.size() >= _data.size()) //ok, so it's impossible id is in there.
- return;
+template<typename Char> +inline void basic_environment_impl<Char>::reset(const string_type &id) +{ + //ok, we need to check the size of data first + if (id.size() >= _data.size()) //ok, so it's impossible id is in there. + return; - //check if it's the first one, spares us the search.
- if (std::equal(id.begin(), id.end(), _data.begin()) && (_data[id.size()] == equal_sign<Char>()))
- {
- auto beg = _data.begin();
- auto end = beg;
+ //check if it's the first one, spares us the search. + if (std::equal(id.begin(), id.end(), _data.begin()) && (_data[id.size()] == equal_sign<Char>())) + { + auto beg = _data.begin(); + auto end = beg; - while (*end != '\0')
- end++;
+ while (*end != '\0') + end++; - end++; //to point behind the last null-char
+ end++; //to point behind the last null-char - _data.erase(beg, end); //and remove the thingy
+ _data.erase(beg, end); //and remove the thingy - }
+ } - std::vector<Char> seq = {'\0'}; //using a vector, because strings might cause problems with nullchars
- seq.insert(seq.end(), id.begin(), id.end());
- seq.push_back('=');
+ std::vector<Char> seq = {'\0'}; //using a vector, because strings might cause problems with nullchars + seq.insert(seq.end(), id.begin(), id.end()); + seq.push_back('='); - auto itr = std::search(_data.begin(), _data.end(), seq.begin(), seq.end());
+ auto itr = std::search(_data.begin(), _data.end(), seq.begin(), seq.end()); - if (itr == _data.end())
- return;//nothing to return if it's empty anyway...
+ if (itr == _data.end()) + return;//nothing to return if it's empty anyway... - auto end = itr;
+ auto end = itr; - while (*end != '\0')
- end++;
+ while (*++end != '\0'); - end ++; //to point behind the last null-char
- _data.erase(itr, end);//and remove it
- reload();
+ _data.erase(itr, end);//and remove it + reload(); -}
+} -template<typename Char>
-std::vector<Char*> basic_environment_impl<Char>::_load_var(Char* p)
-{
- std::vector<Char*> ret;
- if (*p != null_char<Char>())
- {
- ret.push_back(p);
- while ((*p != null_char<Char>()) || (*(p+1) != null_char<Char>()))
- {
- if (*p==null_char<Char>())
- {
- p++;
- ret.push_back(p);
- }
- else
- p++;
- }
- }
- p++;
- ret.push_back(nullptr);
- return ret;
-}
+template<typename Char> +std::vector<Char*> basic_environment_impl<Char>::_load_var(Char* p) +{ + std::vector<Char*> ret; + if (*p != null_char<Char>()) + { + ret.push_back(p); + while ((*p != null_char<Char>()) || (*(p+1) != null_char<Char>())) + { + if (*p==null_char<Char>()) + { + p++; + ret.push_back(p); + } + else + p++; + } + } + p++; + ret.push_back(nullptr); + return ret; +} -template<typename T> constexpr T env_seperator();
-template<> constexpr char env_seperator() {return ';'; }
-template<> constexpr wchar_t env_seperator() {return L';'; }
+template<typename T> constexpr T env_seperator(); +template<> constexpr char env_seperator() {return ';'; } +template<> constexpr wchar_t env_seperator() {return L';'; } -inline int get_id() {return boost::detail::winapi::GetCurrentProcessId();}
-inline void* native_handle() {return boost::detail::winapi::GetCurrentProcess(); }
+inline int get_id() {return boost::winapi::GetCurrentProcessId();} +inline void* native_handle() {return boost::winapi::GetCurrentProcess(); } -typedef void* native_handle_t;
+typedef void* native_handle_t; -}
+} -}
-}
-}
+} +} +} -#endif /* BOOST_PROCESS_DETAIL_WINDOWS_ENV_STORAGE_HPP_ */
+#endif /* BOOST_PROCESS_DETAIL_WINDOWS_ENV_STORAGE_HPP_ */ diff --git a/boost/process/detail/windows/executor.hpp b/boost/process/detail/windows/executor.hpp index 30b1e46369..bc52cbb5fe 100644 --- a/boost/process/detail/windows/executor.hpp +++ b/boost/process/detail/windows/executor.hpp @@ -16,8 +16,8 @@ #include <boost/process/detail/traits.hpp> #include <boost/process/error.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp> -#include <boost/detail/winapi/handles.hpp> -#include <boost/detail/winapi/process.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/process.hpp> #include <boost/none.hpp> #include <system_error> #include <memory> @@ -33,13 +33,13 @@ template<typename CharType> struct startup_info; template<> struct startup_info<char> { - typedef ::boost::detail::winapi::STARTUPINFOA_ type; + typedef ::boost::winapi::STARTUPINFOA_ type; }; #endif template<> struct startup_info<wchar_t> { - typedef ::boost::detail::winapi::STARTUPINFOW_ type; + typedef ::boost::winapi::STARTUPINFOW_ type; }; #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6 @@ -49,13 +49,13 @@ template<typename CharType> struct startup_info_ex; #if !defined( BOOST_NO_ANSI_APIS ) template<> struct startup_info_ex<char> { - typedef ::boost::detail::winapi::STARTUPINFOEXA_ type; + typedef ::boost::winapi::STARTUPINFOEXA_ type; }; #endif template<> struct startup_info_ex<wchar_t> { - typedef ::boost::detail::winapi::STARTUPINFOEXW_ type; + typedef ::boost::winapi::STARTUPINFOEXW_ type; }; @@ -66,7 +66,7 @@ template<> struct startup_info_ex<wchar_t> template<typename CharT> struct startup_info_impl { - ::boost::detail::winapi::DWORD_ creation_flags = 0; + ::boost::winapi::DWORD_ creation_flags = 0; typedef typename startup_info_ex<CharT>::type startup_info_ex_t; typedef typename startup_info<CharT>::type startup_info_t; @@ -74,9 +74,9 @@ struct startup_info_impl startup_info_ex_t startup_info_ex {startup_info_t {sizeof(startup_info_t), nullptr, nullptr, nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, - ::boost::detail::winapi::invalid_handle_value, - ::boost::detail::winapi::invalid_handle_value, - ::boost::detail::winapi::invalid_handle_value}, + ::boost::winapi::invalid_handle_value, + ::boost::winapi::invalid_handle_value, + ::boost::winapi::invalid_handle_value}, nullptr }; startup_info_t & startup_info = startup_info_ex.StartupInfo; @@ -84,7 +84,7 @@ struct startup_info_impl void set_startup_info_ex() { startup_info.cb = sizeof(startup_info_ex_t); - creation_flags = ::boost::detail::winapi::EXTENDED_STARTUPINFO_PRESENT_; + creation_flags = ::boost::winapi::EXTENDED_STARTUPINFO_PRESENT_; } }; @@ -96,13 +96,13 @@ struct startup_info_impl { typedef typename startup_info<CharT>::type startup_info_t; - ::boost::detail::winapi::DWORD_ creation_flags = 0; + ::boost::winapi::DWORD_ creation_flags = 0; startup_info_t startup_info {sizeof(startup_info_t), nullptr, nullptr, nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr, - ::boost::detail::winapi::invalid_handle_value, - ::boost::detail::winapi::invalid_handle_value, - ::boost::detail::winapi::invalid_handle_value}; + ::boost::winapi::invalid_handle_value, + ::boost::winapi::invalid_handle_value, + ::boost::winapi::invalid_handle_value}; }; #endif @@ -186,7 +186,7 @@ public: } //NOTE: The non-cast cmd-line string can only be modified by the wchar_t variant which is currently disabled. - int err_code = ::boost::detail::winapi::create_process( + int err_code = ::boost::winapi::create_process( exe, // LPCSTR_ lpApplicationName, const_cast<Char*>(cmd_line), // LPSTR_ lpCommandLine, proc_attrs, // LPSECURITY_ATTRIBUTES_ lpProcessAttributes, @@ -232,9 +232,9 @@ public: const std::error_code& error() const {return _ec;} - ::boost::detail::winapi::LPSECURITY_ATTRIBUTES_ proc_attrs = nullptr; - ::boost::detail::winapi::LPSECURITY_ATTRIBUTES_ thread_attrs = nullptr; - ::boost::detail::winapi::BOOL_ inherit_handles = false; + ::boost::winapi::LPSECURITY_ATTRIBUTES_ proc_attrs = nullptr; + ::boost::winapi::LPSECURITY_ATTRIBUTES_ thread_attrs = nullptr; + ::boost::winapi::BOOL_ inherit_handles = false; const Char * work_dir = nullptr; const Char * cmd_line = nullptr; const Char * exe = nullptr; @@ -242,7 +242,7 @@ public: Sequence & seq; - ::boost::detail::winapi::PROCESS_INFORMATION_ proc_info{nullptr, nullptr, 0,0}; + ::boost::winapi::PROCESS_INFORMATION_ proc_info{nullptr, nullptr, 0,0}; }; diff --git a/boost/process/detail/windows/file_descriptor.hpp b/boost/process/detail/windows/file_descriptor.hpp index 337e634781..80e4c8ae8f 100644 --- a/boost/process/detail/windows/file_descriptor.hpp +++ b/boost/process/detail/windows/file_descriptor.hpp @@ -1,104 +1,104 @@ -// 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_WINDOWS_FILE_DESCRIPTOR_HPP_
-#define BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_
- -#include <boost/detail/winapi/basic_types.hpp>
-#include <boost/detail/winapi/handles.hpp>
-#include <boost/detail/winapi/file_management.hpp>
-#include <string>
-#include <boost/filesystem/path.hpp>
- -namespace boost { namespace process { namespace detail { namespace windows {
- -struct file_descriptor
-{
- enum mode_t
- {
- read = 1,
- write = 2,
- read_write = 3
- };
- static ::boost::detail::winapi::DWORD_ desired_access(mode_t mode)
- {
- switch(mode)
- {
- case read:
- return ::boost::detail::winapi::GENERIC_READ_;
- case write:
- return ::boost::detail::winapi::GENERIC_WRITE_;
- case read_write:
- return ::boost::detail::winapi::GENERIC_READ_
- | ::boost::detail::winapi::GENERIC_WRITE_;
- default:
- return 0u;
- }
- }
- - file_descriptor() = default;
- file_descriptor(const boost::filesystem::path& p, mode_t mode = read_write)
- : file_descriptor(p.native(), mode)
- {
- }
- - file_descriptor(const std::string & path , mode_t mode = read_write)
- : file_descriptor(path.c_str(), mode) {}
- file_descriptor(const std::wstring & path, mode_t mode = read_write)
- : file_descriptor(path.c_str(), mode) {}
- - file_descriptor(const char* path, mode_t mode = read_write)
- : _handle(
- ::boost::detail::winapi::create_file(
- path,
- desired_access(mode),
- ::boost::detail::winapi::FILE_SHARE_READ_ |
- ::boost::detail::winapi::FILE_SHARE_WRITE_,
- nullptr,
- ::boost::detail::winapi::OPEN_ALWAYS_,
- - ::boost::detail::winapi::FILE_ATTRIBUTE_NORMAL_,
- nullptr
- ))
- {
- - }
- file_descriptor(const wchar_t * path, mode_t mode = read_write)
- : _handle(
- ::boost::detail::winapi::create_file(
- path,
- desired_access(mode),
- ::boost::detail::winapi::FILE_SHARE_READ_ |
- ::boost::detail::winapi::FILE_SHARE_WRITE_,
- nullptr,
- ::boost::detail::winapi::OPEN_ALWAYS_,
- - ::boost::detail::winapi::FILE_ATTRIBUTE_NORMAL_,
- nullptr
- ))
-{
- -}
- file_descriptor(const file_descriptor & ) = delete;
- file_descriptor(file_descriptor && ) = default;
- - file_descriptor& operator=(const file_descriptor & ) = delete;
- file_descriptor& operator=(file_descriptor && ) = default;
- - ~file_descriptor()
- {
- if (_handle != ::boost::detail::winapi::INVALID_HANDLE_VALUE_)
- ::boost::detail::winapi::CloseHandle(_handle);
- }
- - ::boost::detail::winapi::HANDLE_ handle() const { return _handle;}
- -private:
- ::boost::detail::winapi::HANDLE_ _handle = ::boost::detail::winapi::INVALID_HANDLE_VALUE_;
-};
- -}}}}
- -#endif /* BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ */
+// 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_WINDOWS_FILE_DESCRIPTOR_HPP_ +#define BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ + +#include <boost/winapi/basic_types.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/file_management.hpp> +#include <string> +#include <boost/filesystem/path.hpp> + +namespace boost { namespace process { namespace detail { namespace windows { + +struct file_descriptor +{ + enum mode_t + { + read = 1, + write = 2, + read_write = 3 + }; + static ::boost::winapi::DWORD_ desired_access(mode_t mode) + { + switch(mode) + { + case read: + return ::boost::winapi::GENERIC_READ_; + case write: + return ::boost::winapi::GENERIC_WRITE_; + case read_write: + return ::boost::winapi::GENERIC_READ_ + | ::boost::winapi::GENERIC_WRITE_; + default: + return 0u; + } + } + + file_descriptor() = default; + file_descriptor(const boost::filesystem::path& p, mode_t mode = read_write) + : file_descriptor(p.native(), mode) + { + } + + file_descriptor(const std::string & path , mode_t mode = read_write) + : file_descriptor(path.c_str(), mode) {} + file_descriptor(const std::wstring & path, mode_t mode = read_write) + : file_descriptor(path.c_str(), mode) {} + + file_descriptor(const char* path, mode_t mode = read_write) + : _handle( + ::boost::winapi::create_file( + path, + desired_access(mode), + ::boost::winapi::FILE_SHARE_READ_ | + ::boost::winapi::FILE_SHARE_WRITE_, + nullptr, + ::boost::winapi::OPEN_ALWAYS_, + + ::boost::winapi::FILE_ATTRIBUTE_NORMAL_, + nullptr + )) + { + + } + file_descriptor(const wchar_t * path, mode_t mode = read_write) + : _handle( + ::boost::winapi::create_file( + path, + desired_access(mode), + ::boost::winapi::FILE_SHARE_READ_ | + ::boost::winapi::FILE_SHARE_WRITE_, + nullptr, + ::boost::winapi::OPEN_ALWAYS_, + + ::boost::winapi::FILE_ATTRIBUTE_NORMAL_, + nullptr + )) +{ + +} + file_descriptor(const file_descriptor & ) = delete; + file_descriptor(file_descriptor && ) = default; + + file_descriptor& operator=(const file_descriptor & ) = delete; + file_descriptor& operator=(file_descriptor && ) = default; + + ~file_descriptor() + { + if (_handle != ::boost::winapi::INVALID_HANDLE_VALUE_) + ::boost::winapi::CloseHandle(_handle); + } + + ::boost::winapi::HANDLE_ handle() const { return _handle;} + +private: + ::boost::winapi::HANDLE_ _handle = ::boost::winapi::INVALID_HANDLE_VALUE_; +}; + +}}}} + +#endif /* BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ */ diff --git a/boost/process/detail/windows/file_in.hpp b/boost/process/detail/windows/file_in.hpp index b092d278c2..c39235fb3d 100644 --- a/boost/process/detail/windows/file_in.hpp +++ b/boost/process/detail/windows/file_in.hpp @@ -1,44 +1,44 @@ -// 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
-//
-// 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_WINDOWS_FILE_IN_HPP
-#define BOOST_PROCESS_DETAIL_WINDOWS_FILE_IN_HPP
- -#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/handles.hpp>
-#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/windows/file_descriptor.hpp>
-#include <io.h>
- -namespace boost { namespace process { namespace detail { namespace windows {
- -struct file_in : public ::boost::process::detail::handler_base
-{
- file_descriptor file;
- ::boost::detail::winapi::HANDLE_ handle = file.handle();
- - template<typename T>
- file_in(T&& t) : file(std::forward<T>(t), file_descriptor::read) {}
- file_in(FILE * f) : handle(reinterpret_cast<::boost::detail::winapi::HANDLE_>(_get_osfhandle(_fileno(f)))) {}
- - template <class WindowsExecutor>
- void on_setup(WindowsExecutor &e) const
- {
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- e.startup_info.hStdInput = handle;
- e.startup_info.dwFlags |= boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
- }
-};
- -}}}}
- -#endif
+// 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 +// +// 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_WINDOWS_FILE_IN_HPP +#define BOOST_PROCESS_DETAIL_WINDOWS_FILE_IN_HPP + +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/windows/file_descriptor.hpp> +#include <io.h> + +namespace boost { namespace process { namespace detail { namespace windows { + +struct file_in : public ::boost::process::detail::handler_base +{ + file_descriptor file; + ::boost::winapi::HANDLE_ handle = file.handle(); + + template<typename T> + file_in(T&& t) : file(std::forward<T>(t), file_descriptor::read) {} + file_in(FILE * f) : handle(reinterpret_cast<::boost::winapi::HANDLE_>(_get_osfhandle(_fileno(f)))) {} + + template <class WindowsExecutor> + void on_setup(WindowsExecutor &e) const + { + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + e.startup_info.hStdInput = handle; + e.startup_info.dwFlags |= boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; + } +}; + +}}}} + +#endif diff --git a/boost/process/detail/windows/file_out.hpp b/boost/process/detail/windows/file_out.hpp index 2e2cc198cf..db14b3907d 100644 --- a/boost/process/detail/windows/file_out.hpp +++ b/boost/process/detail/windows/file_out.hpp @@ -1,77 +1,77 @@ -// 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
-//
-// 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)
+// 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 +// +// 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_WINDOWS_FILE_OUT_HPP
-#define BOOST_PROCESS_DETAIL_WINDOWS_FILE_OUT_HPP
+#ifndef BOOST_PROCESS_DETAIL_WINDOWS_FILE_OUT_HPP +#define BOOST_PROCESS_DETAIL_WINDOWS_FILE_OUT_HPP -#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/handles.hpp>
-#include <boost/detail/winapi/handle_info.hpp>
-#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/windows/file_descriptor.hpp>
+#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/handle_info.hpp> +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/windows/file_descriptor.hpp> -namespace boost { namespace process { namespace detail { namespace windows {
+namespace boost { namespace process { namespace detail { namespace windows { -template<int p1, int p2>
-struct file_out : public ::boost::process::detail::handler_base
-{
- file_descriptor file;
- ::boost::detail::winapi::HANDLE_ handle = file.handle();
+template<int p1, int p2> +struct file_out : public ::boost::process::detail::handler_base +{ + file_descriptor file; + ::boost::winapi::HANDLE_ handle = file.handle(); - template<typename T>
- file_out(T&& t) : file(std::forward<T>(t), file_descriptor::write) {}
- file_out(FILE * f) : handle(reinterpret_cast<void*>(_get_osfhandle(_fileno(f)))) {}
+ template<typename T> + file_out(T&& t) : file(std::forward<T>(t), file_descriptor::write) {} + file_out(FILE * f) : handle(reinterpret_cast<void*>(_get_osfhandle(_fileno(f)))) {} - template <typename WindowsExecutor>
- inline void on_setup(WindowsExecutor &e) const;
-};
+ template <typename WindowsExecutor> + inline void on_setup(WindowsExecutor &e) const; +}; -template<>
-template<typename WindowsExecutor>
-void file_out<1,-1>::on_setup(WindowsExecutor &e) const
-{
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
+template<> +template<typename WindowsExecutor> +void file_out<1,-1>::on_setup(WindowsExecutor &e) const +{ + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); - e.startup_info.hStdOutput = handle;
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
-}
+ e.startup_info.hStdOutput = handle; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; +} -template<>
-template<typename WindowsExecutor>
-void file_out<2,-1>::on_setup(WindowsExecutor &e) const
-{
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
+template<> +template<typename WindowsExecutor> +void file_out<2,-1>::on_setup(WindowsExecutor &e) const +{ + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); - e.startup_info.hStdError = handle;
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
-}
+ e.startup_info.hStdError = handle; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; +} -template<>
-template<typename WindowsExecutor>
-void file_out<1,2>::on_setup(WindowsExecutor &e) const
-{
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
+template<> +template<typename WindowsExecutor> +void file_out<1,2>::on_setup(WindowsExecutor &e) const +{ + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); - e.startup_info.hStdOutput = handle;
- e.startup_info.hStdError = handle;
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
-}
+ e.startup_info.hStdOutput = handle; + e.startup_info.hStdError = handle; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; +} -}}}}
+}}}} -#endif
+#endif diff --git a/boost/process/detail/windows/group_handle.hpp b/boost/process/detail/windows/group_handle.hpp index e289263cad..5025c0d245 100644 --- a/boost/process/detail/windows/group_handle.hpp +++ b/boost/process/detail/windows/group_handle.hpp @@ -7,14 +7,14 @@ #define BOOST_PROCESS_DETAIL_WINDOWS_GROUP_HPP_ #include <boost/process/detail/windows/handler.hpp> -#include <boost/detail/winapi/jobs.hpp> +#include <boost/winapi/jobs.hpp> #include <boost/process/detail/windows/child_handle.hpp> #include <boost/process/detail/windows/job_workaround.hpp> #include <system_error> namespace boost { namespace process { namespace detail { namespace windows { -inline bool break_away_enabled(::boost::detail::winapi::HANDLE_ h) +inline bool break_away_enabled(::boost::winapi::HANDLE_ h) { workaround::JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ info; @@ -29,7 +29,7 @@ inline bool break_away_enabled(::boost::detail::winapi::HANDLE_ h) return (info.BasicLimitInformation.LimitFlags & workaround::JOB_OBJECT_LIMIT_BREAKAWAY_OK_) != 0; } -inline void enable_break_away(::boost::detail::winapi::HANDLE_ h) +inline void enable_break_away(::boost::winapi::HANDLE_ h) { workaround::JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ info; @@ -54,7 +54,7 @@ inline void enable_break_away(::boost::detail::winapi::HANDLE_ h) throw_last_error("SetInformationJobObject() failed"); } -inline void enable_break_away(::boost::detail::winapi::HANDLE_ h, std::error_code & ec) +inline void enable_break_away(::boost::winapi::HANDLE_ h, std::error_code & ec) { workaround::JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ info; @@ -91,9 +91,9 @@ inline void enable_break_away(::boost::detail::winapi::HANDLE_ h, std::error_cod struct group_handle { - ::boost::detail::winapi::HANDLE_ _job_object; + ::boost::winapi::HANDLE_ _job_object; - typedef ::boost::detail::winapi::HANDLE_ handle_t; + typedef ::boost::winapi::HANDLE_ handle_t; handle_t handle() const { return _job_object; } explicit group_handle(handle_t h) : @@ -103,52 +103,52 @@ struct group_handle } - group_handle() : group_handle(::boost::detail::winapi::CreateJobObjectA(nullptr, nullptr)) + group_handle() : group_handle(::boost::winapi::CreateJobObjectA(nullptr, nullptr)) { } ~group_handle() { - ::boost::detail::winapi::CloseHandle(_job_object); + ::boost::winapi::CloseHandle(_job_object); } group_handle(const group_handle & c) = delete; group_handle(group_handle && c) : _job_object(c._job_object) { - c._job_object = ::boost::detail::winapi::invalid_handle_value; + c._job_object = ::boost::winapi::invalid_handle_value; } group_handle &operator=(const group_handle & c) = delete; group_handle &operator=(group_handle && c) { - ::boost::detail::winapi::CloseHandle(_job_object); + ::boost::winapi::CloseHandle(_job_object); _job_object = c._job_object; - c._job_object = ::boost::detail::winapi::invalid_handle_value; + c._job_object = ::boost::winapi::invalid_handle_value; return *this; } void add(handle_t proc) { - if (!::boost::detail::winapi::AssignProcessToJobObject(_job_object, proc)) + if (!::boost::winapi::AssignProcessToJobObject(_job_object, proc)) throw_last_error(); } void add(handle_t proc, std::error_code & ec) noexcept { - if (!::boost::detail::winapi::AssignProcessToJobObject(_job_object, proc)) + if (!::boost::winapi::AssignProcessToJobObject(_job_object, proc)) ec = get_last_error(); } bool has(handle_t proc) { - ::boost::detail::winapi::BOOL_ is; - if (!::boost::detail::winapi::IsProcessInJob(proc, _job_object, &is)) + ::boost::winapi::BOOL_ is; + if (!::boost::winapi::IsProcessInJob(proc, _job_object, &is)) throw_last_error(); return is!=0; } bool has(handle_t proc, std::error_code & ec) noexcept { - ::boost::detail::winapi::BOOL_ is; - if (!::boost::detail::winapi::IsProcessInJob(proc, _job_object, &is)) + ::boost::winapi::BOOL_ is; + if (!::boost::winapi::IsProcessInJob(proc, _job_object, &is)) ec = get_last_error(); return is!=0; } @@ -162,13 +162,13 @@ struct group_handle inline void terminate(const group_handle &p) { - if (!::boost::detail::winapi::TerminateJobObject(p.handle(), EXIT_FAILURE)) + if (!::boost::winapi::TerminateJobObject(p.handle(), EXIT_FAILURE)) boost::process::detail::throw_last_error("TerminateJobObject() failed"); } inline void terminate(const group_handle &p, std::error_code &ec) noexcept { - if (!::boost::detail::winapi::TerminateJobObject(p.handle(), EXIT_FAILURE)) + if (!::boost::winapi::TerminateJobObject(p.handle(), EXIT_FAILURE)) ec = boost::process::detail::get_last_error(); else ec.clear(); @@ -176,8 +176,8 @@ inline void terminate(const group_handle &p, std::error_code &ec) noexcept inline bool in_group() { - ::boost::detail::winapi::BOOL_ res; - if (!::boost::detail::winapi::IsProcessInJob(boost::detail::winapi::GetCurrentProcess(), nullptr, &res)) + ::boost::winapi::BOOL_ res; + if (!::boost::winapi::IsProcessInJob(boost::winapi::GetCurrentProcess(), nullptr, &res)) throw_last_error("IsProcessInJob failed"); return res!=0; diff --git a/boost/process/detail/windows/group_ref.hpp b/boost/process/detail/windows/group_ref.hpp index 1f62c4dcb0..bbbe4317ba 100644 --- a/boost/process/detail/windows/group_ref.hpp +++ b/boost/process/detail/windows/group_ref.hpp @@ -8,7 +8,7 @@ #include <boost/process/detail/config.hpp> #include <boost/process/detail/windows/group_handle.hpp> -#include <boost/detail/winapi/process.hpp> +#include <boost/winapi/process.hpp> #include <boost/process/detail/windows/handler.hpp> namespace boost { namespace process { @@ -19,7 +19,7 @@ namespace detail { namespace windows { struct group_ref : handler_base_ext { - ::boost::detail::winapi::HANDLE_ handle; + ::boost::winapi::HANDLE_ handle; explicit group_ref(group_handle &g) : handle(g.handle()) @@ -30,14 +30,14 @@ struct group_ref : handler_base_ext { //I can only enable this if the current process supports breakaways. if (in_group() && break_away_enabled(nullptr)) - exec.creation_flags |= boost::detail::winapi::CREATE_BREAKAWAY_FROM_JOB_; + exec.creation_flags |= boost::winapi::CREATE_BREAKAWAY_FROM_JOB_; } template <class Executor> void on_success(Executor& exec) const { - if (!::boost::detail::winapi::AssignProcessToJobObject(handle, exec.proc_info.hProcess)) + if (!::boost::winapi::AssignProcessToJobObject(handle, exec.proc_info.hProcess)) exec.set_error(::boost::process::detail::get_last_error(), "AssignProcessToJobObject() failed."); diff --git a/boost/process/detail/windows/handler.hpp b/boost/process/detail/windows/handler.hpp index f8ef89f016..f151ccc869 100644 --- a/boost/process/detail/windows/handler.hpp +++ b/boost/process/detail/windows/handler.hpp @@ -1,20 +1,20 @@ -// 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)
+// 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_WINDOWS_HANDLER_HPP_
-#define BOOST_PROCESS_DETAIL_WINDOWS_HANDLER_HPP_
+#ifndef BOOST_PROCESS_DETAIL_WINDOWS_HANDLER_HPP_ +#define BOOST_PROCESS_DETAIL_WINDOWS_HANDLER_HPP_ -#include <boost/process/detail/handler_base.hpp>
+#include <boost/process/detail/handler_base.hpp> -namespace boost { namespace process { namespace detail { namespace windows {
+namespace boost { namespace process { namespace detail { namespace windows { -//does not extend anything.
-struct handler_base_ext : handler_base {};
+//does not extend anything. +struct handler_base_ext : handler_base {}; -}}}}
+}}}} -#endif /* BOOST_PROCESS_DETAIL_WINDOWS_HANDLER_HPP_ */
+#endif /* BOOST_PROCESS_DETAIL_WINDOWS_HANDLER_HPP_ */ diff --git a/boost/process/detail/windows/io_service_ref.hpp b/boost/process/detail/windows/io_context_ref.hpp index 6b61c7ca2c..903ef0a09f 100644 --- a/boost/process/detail/windows/io_service_ref.hpp +++ b/boost/process/detail/windows/io_context_ref.hpp @@ -1,160 +1,160 @@ -// 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_WINDOWS_IO_SERVICE_REF_HPP_
-#define BOOST_PROCESS_WINDOWS_IO_SERVICE_REF_HPP_
- -#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/windows/async_handler.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/windows/object_handle.hpp>
-#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/handles.hpp>
- -#include <boost/fusion/algorithm/iteration/for_each.hpp>
-#include <boost/fusion/algorithm/transformation/filter_if.hpp>
-#include <boost/fusion/algorithm/transformation/transform.hpp>
-#include <boost/fusion/view/transform_view.hpp>
-#include <boost/fusion/container/vector/convert.hpp>
- - -#include <functional>
-#include <type_traits>
-#include <memory>
-#include <atomic>
-#include <vector>
- -#include <boost/type_index.hpp>
- -namespace boost { namespace process { namespace detail { namespace windows {
- -template<typename Executor>
-struct on_exit_handler_transformer
-{
- Executor & exec;
- on_exit_handler_transformer(Executor & exec) : exec(exec) {}
- template<typename Sig>
- struct result;
- - template<typename T>
- struct result<on_exit_handler_transformer<Executor>(T&)>
- {
- typedef typename T::on_exit_handler_t type;
- };
- - template<typename T>
- auto operator()(T& t) const -> typename T::on_exit_handler_t
- {
- return t.on_exit_handler(exec);
- }
-};
- -template<typename Executor>
-struct async_handler_collector
-{
- Executor & exec;
- std::vector<std::function<void(int, const std::error_code & ec)>> &handlers;
- - - async_handler_collector(Executor & exec,
- std::vector<std::function<void(int, const std::error_code & ec)>> &handlers)
- : exec(exec), handlers(handlers) {}
- - template<typename T>
- void operator()(T & t) const
- {
- handlers.push_back(t.on_exit_handler(exec));
- }
-};
- -//Also set's up waiting for the exit, so it can close async stuff.
-struct io_service_ref : boost::process::detail::handler_base
-{
- - io_service_ref(boost::asio::io_service & ios)
- : ios(ios)
- {
- }
- boost::asio::io_service &get() {return ios;};
- - template <class Executor>
- void on_success(Executor& exec) const
- {
- auto asyncs = boost::fusion::filter_if<
- is_async_handler<
- typename std::remove_reference< boost::mpl::_ > ::type
- >>(exec.seq);
- - //ok, check if there are actually any.
- if (boost::fusion::empty(asyncs))
- {
- return;
- }
- - ::boost::detail::winapi::PROCESS_INFORMATION_ & proc = exec.proc_info;
- auto this_proc = ::boost::detail::winapi::GetCurrentProcess();
- - auto proc_in = proc.hProcess;;
- ::boost::detail::winapi::HANDLE_ process_handle;
- - if (!::boost::detail::winapi::DuplicateHandle(
- this_proc, proc_in, this_proc, &process_handle, 0,
- static_cast<::boost::detail::winapi::BOOL_>(true),
- ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_))
- - exec.set_error(::boost::process::detail::get_last_error(),
- "Duplicate Pipe Failed");
- - - std::vector<std::function<void(int, const std::error_code & ec)>> funcs;
- funcs.reserve(boost::fusion::size(asyncs));
- boost::fusion::for_each(asyncs, async_handler_collector<Executor>(exec, funcs));
- - wait_handler wh(std::move(funcs), ios, process_handle, exec.exit_status);
- - auto handle_p = wh.handle.get();
- handle_p->async_wait(std::move(wh));
- }
- - - struct wait_handler
- {
- std::vector<std::function<void(int, const std::error_code & ec)>> funcs;
- std::unique_ptr<boost::asio::windows::object_handle> handle;
- std::shared_ptr<std::atomic<int>> exit_status;
- wait_handler(const wait_handler & ) = delete;
- wait_handler(wait_handler && ) = default;
- wait_handler(std::vector<std::function<void(int, const std::error_code & ec)>> && funcs,
- boost::asio::io_service & ios, void * handle,
- const std::shared_ptr<std::atomic<int>> &exit_status)
- : funcs(std::move(funcs)),
- handle(new boost::asio::windows::object_handle(ios, handle)),
- exit_status(exit_status)
- {
- - }
- void operator()(const boost::system::error_code & ec_in)
- {
- std::error_code ec;
- if (ec_in)
- ec = std::error_code(ec_in.value(), std::system_category());
- - ::boost::detail::winapi::DWORD_ code;
- ::boost::detail::winapi::GetExitCodeProcess(handle->native(), &code);
- exit_status->store(code);
- - for (auto & func : funcs)
- func(code, ec);
- }
- - };
- -private:
- boost::asio::io_service &ios;
-};
- -}}}}
- -#endif /* BOOST_PROCESS_WINDOWS_IO_SERVICE_REF_HPP_ */
+// 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_WINDOWS_IO_SERVICE_REF_HPP_ +#define BOOST_PROCESS_WINDOWS_IO_SERVICE_REF_HPP_ + +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/windows/async_handler.hpp> +#include <boost/asio/io_context.hpp> +#include <boost/asio/windows/object_handle.hpp> +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> + +#include <boost/fusion/algorithm/iteration/for_each.hpp> +#include <boost/fusion/algorithm/transformation/filter_if.hpp> +#include <boost/fusion/algorithm/transformation/transform.hpp> +#include <boost/fusion/view/transform_view.hpp> +#include <boost/fusion/container/vector/convert.hpp> + + +#include <functional> +#include <type_traits> +#include <memory> +#include <atomic> +#include <vector> + +#include <boost/type_index.hpp> + +namespace boost { namespace process { namespace detail { namespace windows { + +template<typename Executor> +struct on_exit_handler_transformer +{ + Executor & exec; + on_exit_handler_transformer(Executor & exec) : exec(exec) {} + template<typename Sig> + struct result; + + template<typename T> + struct result<on_exit_handler_transformer<Executor>(T&)> + { + typedef typename T::on_exit_handler_t type; + }; + + template<typename T> + auto operator()(T& t) const -> typename T::on_exit_handler_t + { + return t.on_exit_handler(exec); + } +}; + +template<typename Executor> +struct async_handler_collector +{ + Executor & exec; + std::vector<std::function<void(int, const std::error_code & ec)>> &handlers; + + + async_handler_collector(Executor & exec, + std::vector<std::function<void(int, const std::error_code & ec)>> &handlers) + : exec(exec), handlers(handlers) {} + + template<typename T> + void operator()(T & t) const + { + handlers.push_back(t.on_exit_handler(exec)); + } +}; + +//Also set's up waiting for the exit, so it can close async stuff. +struct io_context_ref : boost::process::detail::handler_base +{ + + io_context_ref(boost::asio::io_context & ios) + : ios(ios) + { + } + boost::asio::io_context &get() {return ios;}; + + template <class Executor> + void on_success(Executor& exec) const + { + auto asyncs = boost::fusion::filter_if< + is_async_handler< + typename std::remove_reference< boost::mpl::_ > ::type + >>(exec.seq); + + //ok, check if there are actually any. + if (boost::fusion::empty(asyncs)) + { + return; + } + + ::boost::winapi::PROCESS_INFORMATION_ & proc = exec.proc_info; + auto this_proc = ::boost::winapi::GetCurrentProcess(); + + auto proc_in = proc.hProcess;; + ::boost::winapi::HANDLE_ process_handle; + + if (!::boost::winapi::DuplicateHandle( + this_proc, proc_in, this_proc, &process_handle, 0, + static_cast<::boost::winapi::BOOL_>(true), + ::boost::winapi::DUPLICATE_SAME_ACCESS_)) + + exec.set_error(::boost::process::detail::get_last_error(), + "Duplicate Pipe Failed"); + + + std::vector<std::function<void(int, const std::error_code & ec)>> funcs; + funcs.reserve(boost::fusion::size(asyncs)); + boost::fusion::for_each(asyncs, async_handler_collector<Executor>(exec, funcs)); + + wait_handler wh(std::move(funcs), ios, process_handle, exec.exit_status); + + auto handle_p = wh.handle.get(); + handle_p->async_wait(std::move(wh)); + } + + + struct wait_handler + { + std::vector<std::function<void(int, const std::error_code & ec)>> funcs; + std::unique_ptr<boost::asio::windows::object_handle> handle; + std::shared_ptr<std::atomic<int>> exit_status; + wait_handler(const wait_handler & ) = delete; + wait_handler(wait_handler && ) = default; + wait_handler(std::vector<std::function<void(int, const std::error_code & ec)>> && funcs, + boost::asio::io_context & ios, void * handle, + const std::shared_ptr<std::atomic<int>> &exit_status) + : funcs(std::move(funcs)), + handle(new boost::asio::windows::object_handle(ios, handle)), + exit_status(exit_status) + { + + } + void operator()(const boost::system::error_code & ec_in) + { + std::error_code ec; + if (ec_in) + ec = std::error_code(ec_in.value(), std::system_category()); + + ::boost::winapi::DWORD_ code; + ::boost::winapi::GetExitCodeProcess(handle->native_handle(), &code); + exit_status->store(code); + + for (auto & func : funcs) + func(code, ec); + } + + }; + +private: + boost::asio::io_context &ios; +}; + +}}}} + +#endif /* BOOST_PROCESS_WINDOWS_IO_SERVICE_REF_HPP_ */ diff --git a/boost/process/detail/windows/is_running.hpp b/boost/process/detail/windows/is_running.hpp index 66cc6837ae..920693d116 100644 --- a/boost/process/detail/windows/is_running.hpp +++ b/boost/process/detail/windows/is_running.hpp @@ -9,20 +9,20 @@ #include <boost/process/detail/config.hpp> #include <system_error> #include <cstdlib> -#include <boost/detail/winapi/process.hpp> +#include <boost/winapi/process.hpp> namespace boost { namespace process { namespace detail { namespace windows { -constexpr static ::boost::detail::winapi::DWORD_ still_active = 259; +constexpr static ::boost::winapi::DWORD_ still_active = 259; struct child_handle; inline bool is_running(const child_handle &p, int & exit_code) { - ::boost::detail::winapi::DWORD_ code; + ::boost::winapi::DWORD_ code; //single value, not needed in the winapi. - if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &code)) + if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &code)) ::boost::process::detail::throw_last_error("GetExitCodeProcess() failed"); if (code == still_active) @@ -36,9 +36,9 @@ inline bool is_running(const child_handle &p, int & exit_code) inline bool is_running(const child_handle &p, int & exit_code, std::error_code &ec) noexcept { - ::boost::detail::winapi::DWORD_ code; + ::boost::winapi::DWORD_ code; //single value, not needed in the winapi. - if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &code)) + if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &code)) ec = ::boost::process::detail::get_last_error(); else ec.clear(); diff --git a/boost/process/detail/windows/job_workaround.hpp b/boost/process/detail/windows/job_workaround.hpp index b915d0c088..16534ce003 100644 --- a/boost/process/detail/windows/job_workaround.hpp +++ b/boost/process/detail/windows/job_workaround.hpp @@ -6,9 +6,9 @@ #ifndef BOOST_PROCESS_DETAIL_WINDOWS_JOB_WORKAROUND_HPP_ #define BOOST_PROCESS_DETAIL_WINDOWS_JOB_WORKAROUND_HPP_ -#include <boost/detail/winapi/config.hpp> -#include <boost/detail/winapi/basic_types.hpp> -#include <boost/detail/winapi/dll.hpp> +#include <boost/winapi/config.hpp> +#include <boost/winapi/basic_types.hpp> +#include <boost/winapi/dll.hpp> namespace boost { namespace process { namespace detail { namespace windows { namespace workaround { @@ -42,35 +42,35 @@ typedef enum _JOBOBJECTINFOCLASS_ { } JOBOBJECTINFOCLASS_; typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION_ { - ::boost::detail::winapi::LARGE_INTEGER_ PerProcessUserTimeLimit; - ::boost::detail::winapi::LARGE_INTEGER_ PerJobUserTimeLimit; - ::boost::detail::winapi::DWORD_ LimitFlags; - ::boost::detail::winapi::SIZE_T_ MinimumWorkingSetSize; - ::boost::detail::winapi::SIZE_T_ MaximumWorkingSetSize; - ::boost::detail::winapi::DWORD_ ActiveProcessLimit; - ::boost::detail::winapi::ULONG_PTR_ Affinity; - ::boost::detail::winapi::DWORD_ PriorityClass; - ::boost::detail::winapi::DWORD_ SchedulingClass; + ::boost::winapi::LARGE_INTEGER_ PerProcessUserTimeLimit; + ::boost::winapi::LARGE_INTEGER_ PerJobUserTimeLimit; + ::boost::winapi::DWORD_ LimitFlags; + ::boost::winapi::SIZE_T_ MinimumWorkingSetSize; + ::boost::winapi::SIZE_T_ MaximumWorkingSetSize; + ::boost::winapi::DWORD_ ActiveProcessLimit; + ::boost::winapi::ULONG_PTR_ Affinity; + ::boost::winapi::DWORD_ PriorityClass; + ::boost::winapi::DWORD_ SchedulingClass; } JOBOBJECT_BASIC_LIMIT_INFORMATION_; typedef struct _IO_COUNTERS_ { - ::boost::detail::winapi::ULONGLONG_ ReadOperationCount; - ::boost::detail::winapi::ULONGLONG_ WriteOperationCount; - ::boost::detail::winapi::ULONGLONG_ OtherOperationCount; - ::boost::detail::winapi::ULONGLONG_ ReadTransferCount; - ::boost::detail::winapi::ULONGLONG_ WriteTransferCount; - ::boost::detail::winapi::ULONGLONG_ OtherTransferCount; + ::boost::winapi::ULONGLONG_ ReadOperationCount; + ::boost::winapi::ULONGLONG_ WriteOperationCount; + ::boost::winapi::ULONGLONG_ OtherOperationCount; + ::boost::winapi::ULONGLONG_ ReadTransferCount; + ::boost::winapi::ULONGLONG_ WriteTransferCount; + ::boost::winapi::ULONGLONG_ OtherTransferCount; } IO_COUNTERS_; typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ { JOBOBJECT_BASIC_LIMIT_INFORMATION_ BasicLimitInformation; IO_COUNTERS_ IoInfo; - ::boost::detail::winapi::SIZE_T_ ProcessMemoryLimit; - ::boost::detail::winapi::SIZE_T_ JobMemoryLimit; - ::boost::detail::winapi::SIZE_T_ PeakProcessMemoryUsed; - ::boost::detail::winapi::SIZE_T_ PeakJobMemoryUsed; + ::boost::winapi::SIZE_T_ ProcessMemoryLimit; + ::boost::winapi::SIZE_T_ JobMemoryLimit; + ::boost::winapi::SIZE_T_ PeakProcessMemoryUsed; + ::boost::winapi::SIZE_T_ PeakJobMemoryUsed; } JOBOBJECT_EXTENDED_LIMIT_INFORMATION_; @@ -82,23 +82,23 @@ typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ { _Out_opt_ LPDWORD lpReturnLength ); */ -typedef ::boost::detail::winapi::BOOL_ ( WINAPI *query_information_job_object_p)( - ::boost::detail::winapi::HANDLE_, +typedef ::boost::winapi::BOOL_ ( WINAPI *query_information_job_object_p)( + ::boost::winapi::HANDLE_, JOBOBJECTINFOCLASS_, void *, - ::boost::detail::winapi::DWORD_, - ::boost::detail::winapi::DWORD_ *); + ::boost::winapi::DWORD_, + ::boost::winapi::DWORD_ *); -inline ::boost::detail::winapi::BOOL_ WINAPI query_information_job_object( - ::boost::detail::winapi::HANDLE_ hJob, +inline ::boost::winapi::BOOL_ WINAPI query_information_job_object( + ::boost::winapi::HANDLE_ hJob, JOBOBJECTINFOCLASS_ JobObjectInfoClass, void * lpJobObjectInfo, - ::boost::detail::winapi::DWORD_ cbJobObjectInfoLength, - ::boost::detail::winapi::DWORD_ *lpReturnLength) + ::boost::winapi::DWORD_ cbJobObjectInfoLength, + ::boost::winapi::DWORD_ *lpReturnLength) { - static ::boost::detail::winapi::HMODULE_ h = ::boost::detail::winapi::get_module_handle("Kernel32.dll"); - static query_information_job_object_p f = reinterpret_cast<query_information_job_object_p>(::boost::detail::winapi::get_proc_address(h, "QueryInformationJobObject")); + static ::boost::winapi::HMODULE_ h = ::boost::winapi::get_module_handle("Kernel32.dll"); + static query_information_job_object_p f = reinterpret_cast<query_information_job_object_p>(::boost::winapi::get_proc_address(h, "QueryInformationJobObject")); return (*f)(hJob, JobObjectInfoClass, lpJobObjectInfo, cbJobObjectInfoLength, lpReturnLength); } @@ -110,27 +110,27 @@ inline ::boost::detail::winapi::BOOL_ WINAPI query_information_job_object( _In_ DWORD cbJobObjectInfoLength );*/ -typedef ::boost::detail::winapi::BOOL_ ( WINAPI *set_information_job_object_p)( - ::boost::detail::winapi::HANDLE_, +typedef ::boost::winapi::BOOL_ ( WINAPI *set_information_job_object_p)( + ::boost::winapi::HANDLE_, JOBOBJECTINFOCLASS_, void *, - ::boost::detail::winapi::DWORD_); + ::boost::winapi::DWORD_); } -inline ::boost::detail::winapi::BOOL_ WINAPI set_information_job_object( - ::boost::detail::winapi::HANDLE_ hJob, +inline ::boost::winapi::BOOL_ WINAPI set_information_job_object( + ::boost::winapi::HANDLE_ hJob, JOBOBJECTINFOCLASS_ JobObjectInfoClass, void * lpJobObjectInfo, - ::boost::detail::winapi::DWORD_ cbJobObjectInfoLength) + ::boost::winapi::DWORD_ cbJobObjectInfoLength) { - static ::boost::detail::winapi::HMODULE_ h = ::boost::detail::winapi::get_module_handle("Kernel32.dll"); - static set_information_job_object_p f = reinterpret_cast<set_information_job_object_p>(::boost::detail::winapi::get_proc_address(h, "SetInformationJobObject")); + static ::boost::winapi::HMODULE_ h = ::boost::winapi::get_module_handle("Kernel32.dll"); + static set_information_job_object_p f = reinterpret_cast<set_information_job_object_p>(::boost::winapi::get_proc_address(h, "SetInformationJobObject")); return (*f)(hJob, JobObjectInfoClass, lpJobObjectInfo, cbJobObjectInfoLength); } -constexpr static ::boost::detail::winapi::DWORD_ JOB_OBJECT_LIMIT_BREAKAWAY_OK_ = 0x00000800; +constexpr static ::boost::winapi::DWORD_ JOB_OBJECT_LIMIT_BREAKAWAY_OK_ = 0x00000800; }}}}} diff --git a/boost/process/detail/windows/locale.hpp b/boost/process/detail/windows/locale.hpp index 34da2a69d3..90b0110dc5 100644 --- a/boost/process/detail/windows/locale.hpp +++ b/boost/process/detail/windows/locale.hpp @@ -1,103 +1,103 @@ -// Copyright (c) 2016 Klemens D. Morgenstern
-// Copyright (c) 2008 Beman Dawes
-//
-// 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_WINDOWS_LOCALE_HPP_
-#define BOOST_PROCESS_DETAIL_WINDOWS_LOCALE_HPP_
- -#include <locale>
-#include <boost/core/ignore_unused.hpp>
-#include <boost/detail/winapi/file_management.hpp>
-#include <boost/detail/winapi/character_code_conversion.hpp>
- -namespace boost
-{
-namespace process
-{
-namespace detail
-{
-namespace windows
-{
- -//copied from boost.filesystem
-class windows_file_codecvt
- : public std::codecvt< wchar_t, char, std::mbstate_t >
- {
- public:
- explicit windows_file_codecvt(std::size_t refs = 0)
- : std::codecvt<wchar_t, char, std::mbstate_t>(refs) {}
- protected:
- - bool do_always_noconv() const noexcept override { return false; }
- - // seems safest to assume variable number of characters since we don't
- // actually know what codepage is active
- int do_encoding() const noexcept override { return 0; }
- - std::codecvt_base::result do_in(std::mbstate_t& state,
- const char* from, const char* from_end, const char*& from_next,
- wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const override
- {
- boost::ignore_unused(state);
- ::boost::detail::winapi::UINT_ codepage = AreFileApisANSI() ?
- ::boost::detail::winapi::CP_ACP_ :
- ::boost::detail::winapi::CP_OEMCP_;
- - int count;
- if ((count = ::boost::detail::winapi::MultiByteToWideChar(codepage,
- ::boost::detail::winapi::MB_PRECOMPOSED_, from,
- static_cast<int>(from_end - from), to, static_cast<int>(to_end - to))) == 0)
- {
- return error; // conversion failed
- }
- - from_next = from_end;
- to_next = to + count;
- *to_next = L'\0';
- return ok;
- }
- - std::codecvt_base::result do_out(std::mbstate_t & state,
- const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next,
- char* to, char* to_end, char*& to_next) const override
- {
- boost::ignore_unused(state);
- auto codepage = ::boost::detail::winapi::AreFileApisANSI() ?
- ::boost::detail::winapi::CP_ACP_ :
- ::boost::detail::winapi::CP_OEMCP_;
- - int count;
- if ((count = ::boost::detail::winapi::WideCharToMultiByte(codepage,
- ::boost::detail::winapi::WC_NO_BEST_FIT_CHARS_, from,
- static_cast<int>(from_end - from), to, static_cast<int>(to_end - to), 0, 0)) == 0)
- {
- return error; // conversion failed
- }
- - from_next = from_end;
- to_next = to + count;
- *to_next = '\0';
- return ok;
- }
- - std::codecvt_base::result do_unshift(std::mbstate_t&,
- char* /*from*/, char* /*to*/, char* & /*next*/) const override { return ok; }
- - int do_length(std::mbstate_t&,
- const char* /*from*/, const char* /*from_end*/, std::size_t /*max*/) const override { return 0; }
- - int do_max_length() const noexcept override { return 0; }
- };
- - - -}
-}
-}
-}
- - - -#endif /* BOOST_PROCESS_LOCALE_HPP_ */
+// Copyright (c) 2016 Klemens D. Morgenstern +// Copyright (c) 2008 Beman Dawes +// +// 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_WINDOWS_LOCALE_HPP_ +#define BOOST_PROCESS_DETAIL_WINDOWS_LOCALE_HPP_ + +#include <locale> +#include <boost/core/ignore_unused.hpp> +#include <boost/winapi/file_management.hpp> +#include <boost/winapi/character_code_conversion.hpp> + +namespace boost +{ +namespace process +{ +namespace detail +{ +namespace windows +{ + +//copied from boost.filesystem +class windows_file_codecvt + : public std::codecvt< wchar_t, char, std::mbstate_t > + { + public: + explicit windows_file_codecvt(std::size_t refs = 0) + : std::codecvt<wchar_t, char, std::mbstate_t>(refs) {} + protected: + + bool do_always_noconv() const noexcept override { return false; } + + // seems safest to assume variable number of characters since we don't + // actually know what codepage is active + int do_encoding() const noexcept override { return 0; } + + std::codecvt_base::result do_in(std::mbstate_t& state, + const char* from, const char* from_end, const char*& from_next, + wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const override + { + boost::ignore_unused(state); + ::boost::winapi::UINT_ codepage = AreFileApisANSI() ? + ::boost::winapi::CP_ACP_ : + ::boost::winapi::CP_OEMCP_; + + int count; + if ((count = ::boost::winapi::MultiByteToWideChar(codepage, + ::boost::winapi::MB_PRECOMPOSED_, from, + static_cast<int>(from_end - from), to, static_cast<int>(to_end - to))) == 0) + { + return error; // conversion failed + } + + from_next = from_end; + to_next = to + count; + *to_next = L'\0'; + return ok; + } + + std::codecvt_base::result do_out(std::mbstate_t & state, + const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, + char* to, char* to_end, char*& to_next) const override + { + boost::ignore_unused(state); + auto codepage = ::boost::winapi::AreFileApisANSI() ? + ::boost::winapi::CP_ACP_ : + ::boost::winapi::CP_OEMCP_; + + int count; + if ((count = ::boost::winapi::WideCharToMultiByte(codepage, + ::boost::winapi::WC_NO_BEST_FIT_CHARS_, from, + static_cast<int>(from_end - from), to, static_cast<int>(to_end - to), 0, 0)) == 0) + { + return error; // conversion failed + } + + from_next = from_end; + to_next = to + count; + *to_next = '\0'; + return ok; + } + + std::codecvt_base::result do_unshift(std::mbstate_t&, + char* /*from*/, char* /*to*/, char* & /*next*/) const override { return ok; } + + int do_length(std::mbstate_t&, + const char* /*from*/, const char* /*from_end*/, std::size_t /*max*/) const override { return 0; } + + int do_max_length() const noexcept override { return 0; } + }; + + + +} +} +} +} + + + +#endif /* BOOST_PROCESS_LOCALE_HPP_ */ diff --git a/boost/process/detail/windows/null_in.hpp b/boost/process/detail/windows/null_in.hpp index f5c0ae6bf7..5fd9ffb9e2 100644 --- a/boost/process/detail/windows/null_in.hpp +++ b/boost/process/detail/windows/null_in.hpp @@ -1,41 +1,41 @@ -// 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
-//
-// 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_WINDOWS_INITIALIZERS_NULL_IN_HPP
-#define BOOST_PROCESS_WINDOWS_INITIALIZERS_NULL_IN_HPP
- -#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/handles.hpp>
-#include <boost/detail/winapi/handle_info.hpp>
-#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/windows/file_descriptor.hpp>
- -namespace boost { namespace process { namespace detail { namespace windows {
- -struct null_in : public ::boost::process::detail::handler_base
-{
- file_descriptor source{"NUL", file_descriptor::read};
- -public:
- template <class WindowsExecutor>
- void on_setup(WindowsExecutor &e) const
- {
- boost::detail::winapi::SetHandleInformation(source.handle(),
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - e.startup_info.hStdInput = source.handle();
- e.startup_info.dwFlags |= boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
- }
-};
- -}}}}
- -#endif
+// 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 +// +// 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_WINDOWS_INITIALIZERS_NULL_IN_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_NULL_IN_HPP + +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/handle_info.hpp> +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/windows/file_descriptor.hpp> + +namespace boost { namespace process { namespace detail { namespace windows { + +struct null_in : public ::boost::process::detail::handler_base +{ + file_descriptor source{"NUL", file_descriptor::read}; + +public: + template <class WindowsExecutor> + void on_setup(WindowsExecutor &e) const + { + boost::winapi::SetHandleInformation(source.handle(), + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + e.startup_info.hStdInput = source.handle(); + e.startup_info.dwFlags |= boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; + } +}; + +}}}} + +#endif diff --git a/boost/process/detail/windows/null_out.hpp b/boost/process/detail/windows/null_out.hpp index 1bc19586c1..0323deab78 100644 --- a/boost/process/detail/windows/null_out.hpp +++ b/boost/process/detail/windows/null_out.hpp @@ -1,75 +1,75 @@ -// 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
-//
-// 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_WINDOWS_INITIALIZERS_NULL_OUT_HPP
-#define BOOST_PROCESS_WINDOWS_INITIALIZERS_NULL_OUT_HPP
- -#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/handles.hpp>
-#include <boost/detail/winapi/handle_info.hpp>
-#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/windows/file_descriptor.hpp>
- -namespace boost { namespace process { namespace detail { namespace windows {
- -template<int p1, int p2>
-struct null_out : public ::boost::process::detail::handler_base
-{
- file_descriptor sink {"NUL", file_descriptor::write}; //works because it gets destroyed AFTER launch.
- - template <typename WindowsExecutor>
- void on_setup(WindowsExecutor &e) const;
-};
- -template<>
-template<typename WindowsExecutor>
-void null_out<1,-1>::on_setup(WindowsExecutor &e) const
-{
- boost::detail::winapi::SetHandleInformation(sink.handle(),
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - e.startup_info.hStdOutput = sink.handle();
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
- -}
- -template<>
-template<typename WindowsExecutor>
-void null_out<2,-1>::on_setup(WindowsExecutor &e) const
-{
- boost::detail::winapi::SetHandleInformation(sink.handle(),
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - e.startup_info.hStdError = sink.handle();
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
- -}
- -template<>
-template<typename WindowsExecutor>
-void null_out<1,2>::on_setup(WindowsExecutor &e) const
-{
- boost::detail::winapi::SetHandleInformation(sink.handle(),
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - e.startup_info.hStdOutput = sink.handle();
- e.startup_info.hStdError = sink.handle();
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
- -}
- -}}}}
- -#endif
+// 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 +// +// 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_WINDOWS_INITIALIZERS_NULL_OUT_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_NULL_OUT_HPP + +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/winapi/handle_info.hpp> +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/windows/file_descriptor.hpp> + +namespace boost { namespace process { namespace detail { namespace windows { + +template<int p1, int p2> +struct null_out : public ::boost::process::detail::handler_base +{ + file_descriptor sink {"NUL", file_descriptor::write}; //works because it gets destroyed AFTER launch. + + template <typename WindowsExecutor> + void on_setup(WindowsExecutor &e) const; +}; + +template<> +template<typename WindowsExecutor> +void null_out<1,-1>::on_setup(WindowsExecutor &e) const +{ + boost::winapi::SetHandleInformation(sink.handle(), + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + e.startup_info.hStdOutput = sink.handle(); + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; + +} + +template<> +template<typename WindowsExecutor> +void null_out<2,-1>::on_setup(WindowsExecutor &e) const +{ + boost::winapi::SetHandleInformation(sink.handle(), + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + e.startup_info.hStdError = sink.handle(); + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; + +} + +template<> +template<typename WindowsExecutor> +void null_out<1,2>::on_setup(WindowsExecutor &e) const +{ + boost::winapi::SetHandleInformation(sink.handle(), + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + e.startup_info.hStdOutput = sink.handle(); + e.startup_info.hStdError = sink.handle(); + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; + +} + +}}}} + +#endif diff --git a/boost/process/detail/windows/on_exit.hpp b/boost/process/detail/windows/on_exit.hpp index 751f6a5f85..92517cb83c 100644 --- a/boost/process/detail/windows/on_exit.hpp +++ b/boost/process/detail/windows/on_exit.hpp @@ -1,40 +1,39 @@ -// 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_WINDOWS_ON_EXIT_HPP_
-#define BOOST_PROCESS_WINDOWS_ON_EXIT_HPP_
- -#include <boost/process/detail/config.hpp>
-#include <boost/process/detail/handler_base.hpp>
-#include <boost/process/detail/windows/async_handler.hpp>
-#include <boost/detail/winapi/process.hpp>
-#include <system_error>
-#include <functional>
- -namespace boost { namespace process { namespace detail { namespace windows {
- -struct on_exit_ : boost::process::detail::windows::async_handler
-{
- std::function<void(int, const std::error_code&)> handler;
- on_exit_(const std::function<void(int, const std::error_code&)> & handler) : handler(handler)
- {
- - }
- - template<typename Executor>
- std::function<void(int, const std::error_code&)> on_exit_handler(Executor&)
- {
- auto handler = this->handler;
- return [handler](int exit_code, const std::error_code & ec)
- {
- handler(static_cast<int>(exit_code), ec);
- };
- - }
-};
- - -}}}}
-#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ON_EXIT_HPP_ */
+// 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_WINDOWS_ON_EXIT_HPP_ +#define BOOST_PROCESS_WINDOWS_ON_EXIT_HPP_ + +#include <boost/process/detail/config.hpp> +#include <boost/process/detail/handler_base.hpp> +#include <boost/process/detail/windows/async_handler.hpp> +#include <system_error> +#include <functional> + +namespace boost { namespace process { namespace detail { namespace windows { + +struct on_exit_ : boost::process::detail::windows::async_handler +{ + std::function<void(int, const std::error_code&)> handler; + on_exit_(const std::function<void(int, const std::error_code&)> & handler) : handler(handler) + { + + } + + template<typename Executor> + std::function<void(int, const std::error_code&)> on_exit_handler(Executor&) + { + auto handler = this->handler; + return [handler](int exit_code, const std::error_code & ec) + { + handler(static_cast<int>(exit_code), ec); + }; + + } +}; + + +}}}} +#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ON_EXIT_HPP_ */ diff --git a/boost/process/detail/windows/pipe_in.hpp b/boost/process/detail/windows/pipe_in.hpp index cd8c186e15..3cc1a10b90 100644 --- a/boost/process/detail/windows/pipe_in.hpp +++ b/boost/process/detail/windows/pipe_in.hpp @@ -1,89 +1,89 @@ -// 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
-//
-// 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_WINDOWS_INITIALIZERS_PIPE_IN_HPP
-#define BOOST_PROCESS_WINDOWS_INITIALIZERS_PIPE_IN_HPP
- -#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/handles.hpp>
-#include <boost/process/detail/handler_base.hpp>
- -namespace boost { namespace process { namespace detail { namespace windows {
- -struct pipe_in : public ::boost::process::detail::handler_base
-{
- ::boost::detail::winapi::HANDLE_ handle;
- - pipe_in(::boost::detail::winapi::HANDLE_ handle) : handle(handle) {}
- - template<typename T> //async_pipe
- pipe_in(T & p) : handle(p.native_source())
- {
- p.assign_source(::boost::detail::winapi::INVALID_HANDLE_VALUE_);
- }
- - template <class WindowsExecutor>
- void on_setup(WindowsExecutor &e) const
- {
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - e.startup_info.hStdInput = handle;
- e.startup_info.dwFlags |= boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
- }
- template<typename WindowsExecutor>
- void on_error(WindowsExecutor &, const std::error_code &) const
- {
- ::boost::detail::winapi::CloseHandle(handle);
- }
- - template<typename WindowsExecutor>
- void on_success(WindowsExecutor &) const
- {
- ::boost::detail::winapi::CloseHandle(handle);
- }
-};
- -class async_pipe;
- -struct async_pipe_in : public pipe_in
-{
- async_pipe &pipe;
- - template<typename AsyncPipe>
- async_pipe_in(AsyncPipe & p) : pipe_in(p.native_source()), pipe(p)
- {
- }
- - template<typename Pipe, typename Executor>
- static void close(Pipe & pipe, Executor &)
- {
- boost::system::error_code ec;
- std::move(pipe).source().close(ec);
- }
- - template<typename Executor>
- void on_error(Executor & exec, const std::error_code &)
- {
- close(pipe, exec);
- }
- - template<typename Executor>
- void on_success(Executor &exec)
- {
- close(pipe, exec);
- }
-};
- - -}}}}
- -#endif
+// 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 +// +// 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_WINDOWS_INITIALIZERS_PIPE_IN_HPP +#define BOOST_PROCESS_WINDOWS_INITIALIZERS_PIPE_IN_HPP + +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/process/detail/handler_base.hpp> + +namespace boost { namespace process { namespace detail { namespace windows { + +struct pipe_in : public ::boost::process::detail::handler_base +{ + ::boost::winapi::HANDLE_ handle; + + pipe_in(::boost::winapi::HANDLE_ handle) : handle(handle) {} + + template<typename T> //async_pipe + pipe_in(T & p) : handle(p.native_source()) + { + p.assign_source(::boost::winapi::INVALID_HANDLE_VALUE_); + } + + template <class WindowsExecutor> + void on_setup(WindowsExecutor &e) const + { + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + e.startup_info.hStdInput = handle; + e.startup_info.dwFlags |= boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; + } + template<typename WindowsExecutor> + void on_error(WindowsExecutor &, const std::error_code &) const + { + ::boost::winapi::CloseHandle(handle); + } + + template<typename WindowsExecutor> + void on_success(WindowsExecutor &) const + { + ::boost::winapi::CloseHandle(handle); + } +}; + +class async_pipe; + +struct async_pipe_in : public pipe_in +{ + async_pipe &pipe; + + template<typename AsyncPipe> + async_pipe_in(AsyncPipe & p) : pipe_in(p.native_source()), pipe(p) + { + } + + template<typename Pipe, typename Executor> + static void close(Pipe & pipe, Executor &) + { + boost::system::error_code ec; + std::move(pipe).source().close(ec); + } + + template<typename Executor> + void on_error(Executor & exec, const std::error_code &) + { + close(pipe, exec); + } + + template<typename Executor> + void on_success(Executor &exec) + { + close(pipe, exec); + } +}; + + +}}}} + +#endif diff --git a/boost/process/detail/windows/pipe_out.hpp b/boost/process/detail/windows/pipe_out.hpp index c32f0a604e..4cefa2fc28 100644 --- a/boost/process/detail/windows/pipe_out.hpp +++ b/boost/process/detail/windows/pipe_out.hpp @@ -1,122 +1,122 @@ -// 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_WINDOWS_PIPE_OUT_HPP
-#define BOOST_PROCESS_WINDOWS_PIPE_OUT_HPP
- -#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/handles.hpp>
-#include <boost/process/detail/handler_base.hpp>
- -namespace boost { namespace process { namespace detail { namespace windows {
- - - -template<int p1, int p2>
-struct pipe_out : public ::boost::process::detail::handler_base
-{
- ::boost::detail::winapi::HANDLE_ handle;
- - pipe_out(::boost::detail::winapi::HANDLE_ handle) : handle(handle) {}
- template<typename T>
- pipe_out(T & p) : handle(p.native_sink())
- {
- p.assign_sink(::boost::detail::winapi::INVALID_HANDLE_VALUE_);
- }
- - template<typename WindowsExecutor>
- void on_setup(WindowsExecutor &e) const;
- - template<typename WindowsExecutor>
- void on_error(WindowsExecutor &, const std::error_code &) const
- {
- ::boost::detail::winapi::CloseHandle(handle);
- }
- - template<typename WindowsExecutor>
- void on_success(WindowsExecutor &) const
- {
- ::boost::detail::winapi::CloseHandle(handle);
- }
-};
- -template<>
-template<typename WindowsExecutor>
-void pipe_out<1,-1>::on_setup(WindowsExecutor &e) const
-{
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - e.startup_info.hStdOutput = handle;
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
-}
- -template<>
-template<typename WindowsExecutor>
-void pipe_out<2,-1>::on_setup(WindowsExecutor &e) const
-{
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - - e.startup_info.hStdError = handle;
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
-}
- -template<>
-template<typename WindowsExecutor>
-void pipe_out<1,2>::on_setup(WindowsExecutor &e) const
-{
- boost::detail::winapi::SetHandleInformation(handle,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_,
- boost::detail::winapi::HANDLE_FLAG_INHERIT_);
- - e.startup_info.hStdOutput = handle;
- e.startup_info.hStdError = handle;
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESTDHANDLES_;
- e.inherit_handles = true;
-}
- -template<int p1, int p2>
-struct async_pipe_out : public pipe_out<p1, p2>
-{
- async_pipe &pipe;
- template<typename AsyncPipe>
- async_pipe_out(AsyncPipe & p) : pipe_out<p1, p2>(p.native_sink()), pipe(p)
- {
- }
- - template<typename Pipe, typename Executor>
- static void close(Pipe & pipe, Executor &)
- {
- boost::system::error_code ec;
- std::move(pipe).sink().close(ec);
- }
- - template<typename Executor>
- void on_error(Executor & exec, const std::error_code &)
- {
- close(pipe, exec);
- }
- - template<typename Executor>
- void on_success(Executor &exec)
- {
- close(pipe, exec);
- }
-};
- -}}}}
- -#endif
+// 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_WINDOWS_PIPE_OUT_HPP +#define BOOST_PROCESS_WINDOWS_PIPE_OUT_HPP + +#include <boost/winapi/process.hpp> +#include <boost/winapi/handles.hpp> +#include <boost/process/detail/handler_base.hpp> + +namespace boost { namespace process { namespace detail { namespace windows { + + + +template<int p1, int p2> +struct pipe_out : public ::boost::process::detail::handler_base +{ + ::boost::winapi::HANDLE_ handle; + + pipe_out(::boost::winapi::HANDLE_ handle) : handle(handle) {} + template<typename T> + pipe_out(T & p) : handle(p.native_sink()) + { + p.assign_sink(::boost::winapi::INVALID_HANDLE_VALUE_); + } + + template<typename WindowsExecutor> + void on_setup(WindowsExecutor &e) const; + + template<typename WindowsExecutor> + void on_error(WindowsExecutor &, const std::error_code &) const + { + ::boost::winapi::CloseHandle(handle); + } + + template<typename WindowsExecutor> + void on_success(WindowsExecutor &) const + { + ::boost::winapi::CloseHandle(handle); + } +}; + +template<> +template<typename WindowsExecutor> +void pipe_out<1,-1>::on_setup(WindowsExecutor &e) const +{ + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + e.startup_info.hStdOutput = handle; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; +} + +template<> +template<typename WindowsExecutor> +void pipe_out<2,-1>::on_setup(WindowsExecutor &e) const +{ + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + + e.startup_info.hStdError = handle; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; +} + +template<> +template<typename WindowsExecutor> +void pipe_out<1,2>::on_setup(WindowsExecutor &e) const +{ + boost::winapi::SetHandleInformation(handle, + boost::winapi::HANDLE_FLAG_INHERIT_, + boost::winapi::HANDLE_FLAG_INHERIT_); + + e.startup_info.hStdOutput = handle; + e.startup_info.hStdError = handle; + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESTDHANDLES_; + e.inherit_handles = true; +} + +template<int p1, int p2> +struct async_pipe_out : public pipe_out<p1, p2> +{ + async_pipe &pipe; + template<typename AsyncPipe> + async_pipe_out(AsyncPipe & p) : pipe_out<p1, p2>(p.native_sink()), pipe(p) + { + } + + template<typename Pipe, typename Executor> + static void close(Pipe & pipe, Executor &) + { + boost::system::error_code ec; + std::move(pipe).sink().close(ec); + } + + template<typename Executor> + void on_error(Executor & exec, const std::error_code &) + { + close(pipe, exec); + } + + template<typename Executor> + void on_success(Executor &exec) + { + close(pipe, exec); + } +}; + +}}}} + +#endif diff --git a/boost/process/detail/windows/search_path.hpp b/boost/process/detail/windows/search_path.hpp index 53fb966784..7c589a720c 100644 --- a/boost/process/detail/windows/search_path.hpp +++ b/boost/process/detail/windows/search_path.hpp @@ -19,9 +19,8 @@ #include <array> #include <atomic> #include <cstdlib> -#include <boost/detail/winapi/shell.hpp> - - +#include <boost/winapi/shell.hpp> +#include <boost/process/environment.hpp> namespace boost { namespace process { namespace detail { namespace windows { @@ -29,20 +28,46 @@ inline boost::filesystem::path search_path( const boost::filesystem::path &filename, const std::vector<boost::filesystem::path> &path) { + const ::boost::process::wnative_environment ne{}; + typedef typename ::boost::process::wnative_environment::const_entry_type value_type; + const auto id = L"PATHEXT"; + + auto itr = std::find_if(ne.cbegin(), ne.cend(), + [&](const value_type & e) + {return id == ::boost::to_upper_copy(e.get_name(), ::boost::process::detail::process_locale());}); + + auto extensions_in = itr->to_vector(); + + std::vector<std::wstring> extensions((extensions_in.size() * 2) + 1); + + auto it_ex = extensions.begin(); + it_ex++; + it_ex = std::transform(extensions_in.begin(), extensions_in.end(), it_ex, + [](const std::wstring & ws){return boost::to_lower_copy(ws, ::boost::process::detail::process_locale());}); + + std::transform(extensions_in.begin(), extensions_in.end(), it_ex, + [](const std::wstring & ws){return boost::to_upper_copy(ws, ::boost::process::detail::process_locale());}); + + + std::copy(std::make_move_iterator(extensions_in.begin()), std::make_move_iterator(extensions_in.end()), extensions.begin() + 1); + + + for (auto & ext : extensions) + boost::to_lower(ext); + for (const boost::filesystem::path & pp : path) { - auto full = pp / filename; - std::array<std::string, 4> extensions {{ "", ".exe", ".com", ".bat" }}; + auto p = pp / filename; for (boost::filesystem::path ext : extensions) { - auto p = full; - p += ext; + boost::filesystem::path pp = p; + pp += ext; boost::system::error_code ec; - bool file = boost::filesystem::is_regular_file(p, ec); + bool file = boost::filesystem::is_regular_file(pp, ec); if (!ec && file && - ::boost::detail::winapi::sh_get_file_info(p.string().c_str(), 0, 0, 0, ::boost::detail::winapi::SHGFI_EXETYPE_)) + ::boost::winapi::sh_get_file_info(pp.native().c_str(), 0, 0, 0, ::boost::winapi::SHGFI_EXETYPE_)) { - return p; + return pp; } } } diff --git a/boost/process/detail/windows/shell_path.hpp b/boost/process/detail/windows/shell_path.hpp index 7cce445292..263a410541 100644 --- a/boost/process/detail/windows/shell_path.hpp +++ b/boost/process/detail/windows/shell_path.hpp @@ -13,15 +13,15 @@ #include <boost/process/detail/config.hpp> #include <system_error> #include <boost/filesystem/path.hpp> -#include <boost/detail/winapi/basic_types.hpp> -#include <boost/detail/winapi/get_system_directory.hpp> +#include <boost/winapi/basic_types.hpp> +#include <boost/winapi/get_system_directory.hpp> namespace boost { namespace process { namespace detail { namespace windows { inline boost::filesystem::path shell_path() { - ::boost::detail::winapi::WCHAR_ sysdir[260]; - unsigned int size = ::boost::detail::winapi::get_system_directory(sysdir, sizeof(sysdir)); + ::boost::winapi::WCHAR_ sysdir[260]; + unsigned int size = ::boost::winapi::get_system_directory(sysdir, sizeof(sysdir)); if (!size) throw_last_error("GetSystemDirectory() failed"); @@ -32,12 +32,12 @@ inline boost::filesystem::path shell_path() inline boost::filesystem::path shell_path(std::error_code &ec) noexcept { - ::boost::detail::winapi::WCHAR_ sysdir[260]; - unsigned int size = ::boost::detail::winapi::get_system_directory(sysdir, sizeof(sysdir)); + ::boost::winapi::WCHAR_ sysdir[260]; + unsigned int size = ::boost::winapi::get_system_directory(sysdir, sizeof(sysdir)); boost::filesystem::path p; if (!size) ec = std::error_code( - ::boost::detail::winapi::GetLastError(), + ::boost::winapi::GetLastError(), std::system_category()); else { diff --git a/boost/process/detail/windows/show_window.hpp b/boost/process/detail/windows/show_window.hpp index ed42ebc56e..3cd2b44902 100644 --- a/boost/process/detail/windows/show_window.hpp +++ b/boost/process/detail/windows/show_window.hpp @@ -1,39 +1,39 @@ -// 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)
+// 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_WINDOWS_SHOW_WINDOW_HPP
-#define BOOST_PROCESS_WINDOWS_SHOW_WINDOW_HPP
+#ifndef BOOST_PROCESS_WINDOWS_SHOW_WINDOW_HPP +#define BOOST_PROCESS_WINDOWS_SHOW_WINDOW_HPP -#include <boost/detail/winapi/process.hpp>
-#include <boost/detail/winapi/show_window.hpp>
-#include <boost/process/detail/handler_base.hpp>
+#include <boost/winapi/process.hpp> +#include <boost/winapi/show_window.hpp> +#include <boost/process/detail/handler_base.hpp> -namespace boost { namespace process { namespace detail { namespace windows {
+namespace boost { namespace process { namespace detail { namespace windows { -template<::boost::detail::winapi::WORD_ Flags>
-struct show_window : ::boost::process::detail::handler_base
-{
- template <class WindowsExecutor>
- void on_setup(WindowsExecutor &e) const
- {
- e.startup_info.dwFlags |= ::boost::detail::winapi::STARTF_USESHOWWINDOW_;
- e.startup_info.wShowWindow |= Flags;
- }
-};
+template<::boost::winapi::WORD_ Flags> +struct show_window : ::boost::process::detail::handler_base +{ + template <class WindowsExecutor> + void on_setup(WindowsExecutor &e) const + { + e.startup_info.dwFlags |= ::boost::winapi::STARTF_USESHOWWINDOW_; + e.startup_info.wShowWindow |= Flags; + } +}; -}}}}
+}}}} -#endif
+#endif diff --git a/boost/process/detail/windows/start_dir.hpp b/boost/process/detail/windows/start_dir.hpp index 06629ed1f8..a52ecb8ff7 100644 --- a/boost/process/detail/windows/start_dir.hpp +++ b/boost/process/detail/windows/start_dir.hpp @@ -1,36 +1,36 @@ -// 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
-//
-// 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_WINDOWS_START_DIR_HPP
-#define BOOST_PROCESS_DETAIL_WINDOWS_START_DIR_HPP
- -#include <string>
-#include <boost/process/detail/windows/handler.hpp>
- -namespace boost { namespace process { namespace detail { namespace windows {
- -template<typename Char>
-struct start_dir_init : handler_base_ext
-{
- start_dir_init(const std::basic_string<Char> &s) : s_(s) {}
- - template <class Executor>
- void on_setup(Executor& exec) const
- {
- exec.work_dir = s_.c_str();
- }
- - const std::basic_string<Char> &str() const {return s_;}
-private:
- std::basic_string<Char> s_;
-};
- -}}}}
- -#endif
+// 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 +// +// 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_WINDOWS_START_DIR_HPP +#define BOOST_PROCESS_DETAIL_WINDOWS_START_DIR_HPP + +#include <string> +#include <boost/process/detail/windows/handler.hpp> + +namespace boost { namespace process { namespace detail { namespace windows { + +template<typename Char> +struct start_dir_init : handler_base_ext +{ + start_dir_init(const std::basic_string<Char> &s) : s_(s) {} + + template <class Executor> + void on_setup(Executor& exec) const + { + exec.work_dir = s_.c_str(); + } + + const std::basic_string<Char> &str() const {return s_;} +private: + std::basic_string<Char> s_; +}; + +}}}} + +#endif diff --git a/boost/process/detail/windows/terminate.hpp b/boost/process/detail/windows/terminate.hpp index a10b074078..ba66e4085c 100644 --- a/boost/process/detail/windows/terminate.hpp +++ b/boost/process/detail/windows/terminate.hpp @@ -13,8 +13,8 @@ #include <boost/process/detail/config.hpp> #include <system_error> #include <cstdlib> -#include <boost/detail/winapi/process.hpp> -#include <boost/detail/winapi/get_last_error.hpp> +#include <boost/winapi/process.hpp> +#include <boost/winapi/get_last_error.hpp> namespace boost { namespace process { namespace detail { namespace windows { @@ -22,22 +22,22 @@ struct child_handle; inline void terminate(child_handle &p) { - if (!::boost::detail::winapi::TerminateProcess(p.process_handle(), EXIT_FAILURE)) + if (!::boost::winapi::TerminateProcess(p.process_handle(), EXIT_FAILURE)) boost::process::detail::throw_last_error("TerminateProcess() failed"); - ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess); - p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::CloseHandle(p.proc_info.hProcess); + p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; } inline void terminate(child_handle &p, std::error_code &ec) noexcept { - if (!::boost::detail::winapi::TerminateProcess(p.process_handle(), EXIT_FAILURE)) + if (!::boost::winapi::TerminateProcess(p.process_handle(), EXIT_FAILURE)) ec = boost::process::detail::get_last_error(); else { ec.clear(); - ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess); - p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::CloseHandle(p.proc_info.hProcess); + p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; } } diff --git a/boost/process/detail/windows/wait_for_exit.hpp b/boost/process/detail/windows/wait_for_exit.hpp index decdb51172..4219d9725a 100644 --- a/boost/process/detail/windows/wait_for_exit.hpp +++ b/boost/process/detail/windows/wait_for_exit.hpp @@ -13,8 +13,8 @@ #include <boost/process/detail/config.hpp> #include <system_error> -#include <boost/detail/winapi/synchronization.hpp> -#include <boost/detail/winapi/process.hpp> +#include <boost/winapi/synchronization.hpp> +#include <boost/winapi/process.hpp> #include <boost/process/detail/windows/child_handle.hpp> #include <chrono> @@ -22,37 +22,37 @@ namespace boost { namespace process { namespace detail { namespace windows { inline void wait(child_handle &p, int & exit_code) { - if (::boost::detail::winapi::WaitForSingleObject(p.process_handle(), - ::boost::detail::winapi::infinite) == ::boost::detail::winapi::wait_failed) + if (::boost::winapi::WaitForSingleObject(p.process_handle(), + ::boost::winapi::infinite) == ::boost::winapi::wait_failed) throw_last_error("WaitForSingleObject() failed"); - ::boost::detail::winapi::DWORD_ _exit_code; - if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) + ::boost::winapi::DWORD_ _exit_code; + if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) throw_last_error("GetExitCodeProcess() failed"); - ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess); - p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::CloseHandle(p.proc_info.hProcess); + p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; exit_code = static_cast<int>(_exit_code); } inline void wait(child_handle &p, int & exit_code, std::error_code &ec) noexcept { - ::boost::detail::winapi::DWORD_ _exit_code = 1; + ::boost::winapi::DWORD_ _exit_code = 1; - if (::boost::detail::winapi::WaitForSingleObject(p.process_handle(), - ::boost::detail::winapi::infinite) == ::boost::detail::winapi::wait_failed) + if (::boost::winapi::WaitForSingleObject(p.process_handle(), + ::boost::winapi::infinite) == ::boost::winapi::wait_failed) ec = std::error_code( - ::boost::detail::winapi::GetLastError(), + ::boost::winapi::GetLastError(), std::system_category()); - else if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) + else if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) ec = std::error_code( - ::boost::detail::winapi::GetLastError(), + ::boost::winapi::GetLastError(), std::system_category()); else ec.clear(); - ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess); - p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::CloseHandle(p.proc_info.hProcess); + p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; exit_code = static_cast<int>(_exit_code); } @@ -66,21 +66,21 @@ inline bool wait_for( std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(rel_time); - ::boost::detail::winapi::DWORD_ wait_code; - wait_code = ::boost::detail::winapi::WaitForSingleObject(p.process_handle(), - static_cast<::boost::detail::winapi::DWORD_>(ms.count())); - if (wait_code == ::boost::detail::winapi::wait_failed) + ::boost::winapi::DWORD_ wait_code; + wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(), + static_cast<::boost::winapi::DWORD_>(ms.count())); + if (wait_code == ::boost::winapi::wait_failed) throw_last_error("WaitForSingleObject() failed"); - else if (wait_code == ::boost::detail::winapi::wait_timeout) + else if (wait_code == ::boost::winapi::wait_timeout) return false; // - ::boost::detail::winapi::DWORD_ _exit_code; - if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) + ::boost::winapi::DWORD_ _exit_code; + if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) throw_last_error("GetExitCodeProcess() failed"); exit_code = static_cast<int>(_exit_code); - ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess); - p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::CloseHandle(p.proc_info.hProcess); + p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; return true; } @@ -96,21 +96,21 @@ inline bool wait_for( std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(rel_time); - ::boost::detail::winapi::DWORD_ wait_code; - wait_code = ::boost::detail::winapi::WaitForSingleObject(p.process_handle(), - static_cast<::boost::detail::winapi::DWORD_>(ms.count())); - if (wait_code == ::boost::detail::winapi::wait_failed) + ::boost::winapi::DWORD_ wait_code; + wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(), + static_cast<::boost::winapi::DWORD_>(ms.count())); + if (wait_code == ::boost::winapi::wait_failed) ec = std::error_code( - ::boost::detail::winapi::GetLastError(), + ::boost::winapi::GetLastError(), std::system_category()); - else if (wait_code == ::boost::detail::winapi::wait_timeout) + else if (wait_code == ::boost::winapi::wait_timeout) return false; // - ::boost::detail::winapi::DWORD_ _exit_code = 1; - if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) + ::boost::winapi::DWORD_ _exit_code = 1; + if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) { ec = std::error_code( - ::boost::detail::winapi::GetLastError(), + ::boost::winapi::GetLastError(), std::system_category()); return false; } @@ -118,8 +118,8 @@ inline bool wait_for( ec.clear(); exit_code = static_cast<int>(_exit_code); - ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess); - p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::CloseHandle(p.proc_info.hProcess); + p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; return true; ; } @@ -134,22 +134,22 @@ inline bool wait_until( std::chrono::duration_cast<std::chrono::milliseconds>( timeout_time - std::chrono::system_clock::now()); - ::boost::detail::winapi::DWORD_ wait_code; - wait_code = ::boost::detail::winapi::WaitForSingleObject(p.process_handle(), - static_cast<::boost::detail::winapi::DWORD_>(ms.count())); + ::boost::winapi::DWORD_ wait_code; + wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(), + static_cast<::boost::winapi::DWORD_>(ms.count())); - if (wait_code == ::boost::detail::winapi::wait_failed) + if (wait_code == ::boost::winapi::wait_failed) throw_last_error("WaitForSingleObject() failed"); - else if (wait_code == ::boost::detail::winapi::wait_timeout) + else if (wait_code == ::boost::winapi::wait_timeout) return false; - ::boost::detail::winapi::DWORD_ _exit_code; - if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) + ::boost::winapi::DWORD_ _exit_code; + if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) throw_last_error("GetExitCodeProcess() failed"); exit_code = static_cast<int>(_exit_code); - ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess); - p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + ::boost::winapi::CloseHandle(p.proc_info.hProcess); + p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; return true; } @@ -165,24 +165,28 @@ inline bool wait_until( std::chrono::duration_cast<std::chrono::milliseconds>( timeout_time - std::chrono::system_clock::now()); - ::boost::detail::winapi::DWORD_ _exit_code = 1; + ::boost::winapi::DWORD_ wait_code; + wait_code = ::boost::winapi::WaitForSingleObject(p.process_handle(), + static_cast<::boost::winapi::DWORD_>(ms.count())); - if (::boost::detail::winapi::WaitForSingleObject(p.process_handle(), - static_cast<::boost::detail::winapi::DWORD_>(ms.count())) - == ::boost::detail::winapi::wait_failed) + if (wait_code == ::boost::winapi::wait_failed) ec = std::error_code( - ::boost::detail::winapi::GetLastError(), + ::boost::winapi::GetLastError(), std::system_category()); - else if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) + else if (wait_code == ::boost::winapi::wait_timeout) + return false; + + ::boost::winapi::DWORD_ _exit_code; + if (!::boost::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code)) ec = std::error_code( - ::boost::detail::winapi::GetLastError(), + ::boost::winapi::GetLastError(), std::system_category()); else ec.clear(); - exit_code = static_cast<int>(exit_code); - ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess); - p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_; + exit_code = static_cast<int>(_exit_code); + ::boost::winapi::CloseHandle(p.proc_info.hProcess); + p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_; return true; ; } diff --git a/boost/process/detail/windows/wait_group.hpp b/boost/process/detail/windows/wait_group.hpp index 449985f2fc..e0b18b1268 100644 --- a/boost/process/detail/windows/wait_group.hpp +++ b/boost/process/detail/windows/wait_group.hpp @@ -7,8 +7,8 @@ #define BOOST_PROCESS_DETAIL_WINDOWS_WAIT_GROUP_HPP_ #include <boost/process/detail/config.hpp> -#include <boost/detail/winapi/jobs.hpp> -#include <boost/detail/winapi/wait.hpp> +#include <boost/winapi/jobs.hpp> +#include <boost/winapi/wait.hpp> namespace boost { namespace process { namespace detail { namespace windows { @@ -17,16 +17,16 @@ struct group_handle; inline void wait(const group_handle &p) { - if (::boost::detail::winapi::WaitForSingleObject(p.handle(), - ::boost::detail::winapi::infinite) == ::boost::detail::winapi::wait_failed) + if (::boost::winapi::WaitForSingleObject(p.handle(), + ::boost::winapi::infinite) == ::boost::winapi::wait_failed) throw_last_error("WaitForSingleObject() failed"); } inline void wait(const group_handle &p, std::error_code &ec) { - if (::boost::detail::winapi::WaitForSingleObject(p.handle(), - ::boost::detail::winapi::infinite) == ::boost::detail::winapi::wait_failed) + if (::boost::winapi::WaitForSingleObject(p.handle(), + ::boost::winapi::infinite) == ::boost::winapi::wait_failed) ec = get_last_error(); } @@ -39,11 +39,11 @@ inline bool wait_for( std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(rel_time); - ::boost::detail::winapi::DWORD_ wait_code; - wait_code = ::boost::detail::winapi::WaitForSingleObject(p.handle(), ms.count()); - if (wait_code == ::boost::detail::winapi::wait_failed) + ::boost::winapi::DWORD_ wait_code; + wait_code = ::boost::winapi::WaitForSingleObject(p.handle(), ms.count()); + if (wait_code == ::boost::winapi::wait_failed) throw_last_error("WaitForSingleObject() failed"); - else if (wait_code == ::boost::detail::winapi::wait_timeout) + else if (wait_code == ::boost::winapi::wait_timeout) return false; // return true; @@ -60,12 +60,12 @@ inline bool wait_for( std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(rel_time); - ::boost::detail::winapi::DWORD_ wait_code; - wait_code = ::boost::detail::winapi::WaitForSingleObject(p.handle(), ms.count()); - if (wait_code == ::boost::detail::winapi::wait_failed) + ::boost::winapi::DWORD_ wait_code; + wait_code = ::boost::winapi::WaitForSingleObject(p.handle(), ms.count()); + if (wait_code == ::boost::winapi::wait_failed) ec = get_last_error(); - else if (wait_code == ::boost::detail::winapi::wait_timeout) + else if (wait_code == ::boost::winapi::wait_timeout) return false; // return true; @@ -80,13 +80,13 @@ inline bool wait_until( std::chrono::duration_cast<std::chrono::milliseconds>( timeout_time - std::chrono::system_clock::now()); - ::boost::detail::winapi::DWORD_ wait_code; - wait_code = ::boost::detail::winapi::WaitForSingleObject(p.handle(), ms.count()); + ::boost::winapi::DWORD_ wait_code; + wait_code = ::boost::winapi::WaitForSingleObject(p.handle(), ms.count()); - if (wait_code == ::boost::detail::winapi::wait_failed) + if (wait_code == ::boost::winapi::wait_failed) throw_last_error("WaitForSingleObject() failed"); - else if (wait_code == ::boost::detail::winapi::wait_timeout) + else if (wait_code == ::boost::winapi::wait_timeout) return false; // return true; @@ -103,13 +103,13 @@ inline bool wait_until( std::chrono::duration_cast<std::chrono::milliseconds>( timeout_time - std::chrono::system_clock::now()); - ::boost::detail::winapi::DWORD_ wait_code; - wait_code = ::boost::detail::winapi::WaitForSingleObject(p.handle(), ms.count()); + ::boost::winapi::DWORD_ wait_code; + wait_code = ::boost::winapi::WaitForSingleObject(p.handle(), ms.count()); - if (wait_code == ::boost::detail::winapi::wait_failed) + if (wait_code == ::boost::winapi::wait_failed) ec = get_last_error(); - else if (wait_code == ::boost::detail::winapi::wait_timeout) + else if (wait_code == ::boost::winapi::wait_timeout) return false; // return true; diff --git a/boost/process/env.hpp b/boost/process/env.hpp index 4362b0fe86..1080283129 100644 --- a/boost/process/env.hpp +++ b/boost/process/env.hpp @@ -1,502 +1,502 @@ -// 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_ENV_HPP_
-#define BOOST_PROCESS_DETAIL_ENV_HPP_
- -#include <boost/process/environment.hpp>
-#include <boost/none.hpp>
- -#if defined(BOOST_POSIX_API)
-#include <boost/process/detail/posix/env_init.hpp>
-#elif defined(BOOST_WINDOWS_API)
-#include <boost/process/detail/windows/env_init.hpp>
-#endif
- -/** \file boost/process/env.hpp
- *
- * This header which provides the `env` property. It allows the modification of the
- * environment the child process will run in, in a functional style.
- *
- * \xmlonly
-<programlisting>
-namespace boost {
- namespace process {
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::env">env</globalname>;
- }
-}
-</programlisting>
- * \endxmlonly
- *
- * For additional information see the platform documentations:
- *
- * - [windows](https://msdn.microsoft.com/en-US/library/windows/desktop/ms682653.aspx)
- * - [posix](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html)
- *
- */
- - -namespace boost {
- -namespace process { namespace detail {
- - -template<typename Char>
-std::size_t make_env_string_size(const std::basic_string<Char> & ch)
-{
- return ch.size() + 1;
-}
- -template<typename Char>
-std::size_t make_env_string_size(const Char * ch)
-{
- std::size_t sz = 0;
- while (ch[sz] != null_char<Char>())
- sz++;
- - sz++;
- return sz;
-}
- -template<typename Char, typename Container>
-inline std::basic_string<Char> make_env_string(const Container & value)
-{
- std::size_t sz = 0;
- for (auto & v : value)
- sz += make_env_string_size(v);
- - std::basic_string<Char> s;
- s.reserve(sz); //+1 for ;, end doesn't have one.
- - for (auto & val : value)
- (s += val) += api::env_seperator<Char>();
- - s.resize(s.size() -1); //remove last ';'
- return s;
-}
- - -template<typename Char>
-struct env_set
-{
- using string_type = std::basic_string<Char>;
- string_type key;
- string_type value;
-};
- -template<typename Char>
-struct env_append
-{
- using string_type = std::basic_string<Char>;
- string_type key;
- string_type value;
-};
- - - -template<typename Char>
-struct env_reset
-{
- using string_type = std::basic_string<Char>;
- string_type key;
-};
- - -template<> struct is_wchar_t<env_set<wchar_t>> : std::true_type {};
-template<> struct is_wchar_t<env_append<wchar_t>> : std::true_type {};
-template<> struct is_wchar_t<env_reset<wchar_t>> : std::true_type {};
-template<> struct is_wchar_t<basic_environment<wchar_t>> : std::true_type {};
- - -template<>
-struct char_converter<char, env_set<wchar_t>>
-{
- static env_set<char> conv(const env_set<wchar_t> & in)
- {
- return {::boost::process::detail::convert(in.key),
- ::boost::process::detail::convert(in.value)};
- }
-};
- -template<>
-struct char_converter<wchar_t, env_set<char>>
-{
- static env_set<wchar_t> conv(const env_set<char> & in)
- {
- return {::boost::process::detail::convert(in.key),
- ::boost::process::detail::convert(in.value)};
- }
-};
- -template<>
-struct char_converter<char, env_append<wchar_t>>
-{
- static env_append<char> conv(const env_append<wchar_t> & in)
- {
- return {::boost::process::detail::convert(in.key),
- ::boost::process::detail::convert(in.value)};
- }
-};
- -template<>
-struct char_converter<wchar_t, env_append<char>>
-{
- static env_append<wchar_t> conv(const env_append<char> & in)
- {
- return {::boost::process::detail::convert(in.key),
- ::boost::process::detail::convert(in.value)};
- }
-};
- -template<>
-struct char_converter<char, env_reset<wchar_t>>
-{
- static env_reset<char> conv(const env_reset<wchar_t> & in)
- {
- return {::boost::process::detail::convert(in.key)};
- }
-};
- -template<>
-struct char_converter<wchar_t, env_reset<char>>
-{
- static env_reset<wchar_t> conv(const env_reset<char> & in)
- {
- return {::boost::process::detail::convert(in.key)};
- }
-};
- - -template<typename Char>
-struct env_init
-{
- basic_environment<Char> env;
-};
- -template<>
-struct char_converter<char, env_init<wchar_t>>
-{
- static env_init<char> conv(const env_init<wchar_t> & in)
- {
- return {basic_environment<char>(in.env)};
- }
-};
- -template<>
-struct char_converter<wchar_t, env_init<char>>
-{
- static env_init<wchar_t> conv(const env_init<char> & in)
- {
- return {basic_environment<wchar_t>(in.env)};
- }
-};
- -template<>
-struct char_converter<char, basic_environment<wchar_t>>
-{
- static basic_environment<char> conv(const basic_environment<wchar_t> & in)
- {
- return { basic_environment<char>(in) };
- }
-};
- -template<>
-struct char_converter<wchar_t, basic_environment<char>>
-{
- static basic_environment<wchar_t> conv(const basic_environment<char> & in)
- {
- return { basic_environment<wchar_t>(in) };
- }
-};
- -template<typename Char>
-struct env_proxy
-{
- using string_type = std::basic_string<Char>;
- string_type key;
- - - env_set<Char> operator=(const string_type & value)
- {
- return {std::move(key), value};
- }
- env_set<Char> operator=(const std::vector<string_type> & value)
- {
- return {std::move(key), make_env_string<Char>(value)};
- }
- env_set<Char> operator=(const std::initializer_list<const Char*> & value)
- {
- return {std::move(key), make_env_string<Char>(value)};
- }
- - env_append<Char> operator+=(const string_type & value)
- {
- return {std::move(key), value};
- }
- env_append<Char> operator+=(const std::vector<string_type> & value)
- {
- return {std::move(key), make_env_string<Char>(value)};
- }
- env_append<Char> operator+=(const std::initializer_list<const Char*> & value)
- {
- return {std::move(key), make_env_string<Char>(value)};
- }
- env_reset<Char> operator=(boost::none_t)
- {
- return {std::move(key)};
- }
-};
- -struct env_
-{
- constexpr env_() {};
- - template<typename Char>
- env_set<Char> operator()(const std::basic_string<Char> & key,
- const std::basic_string<Char> & value) const
- {
- return {key, value};
- }
- template<typename Char>
- env_set<Char> operator()(const std::basic_string<Char> & key,
- const std::vector<std::basic_string<Char>> & value) const
- {
- return {key, make_env_string<Char>(value)};
- }
- template<typename Char>
- env_set<Char> operator()(const std::basic_string<Char> & key,
- const std::initializer_list<Char*> & value) const
- {
- return {key, make_env_string<Char>(value)};
- }
- template<typename Char>
- env_reset<Char> operator()(const std::basic_string<Char> & key, boost::none_t)
- {
- return {key};
- }
- template<typename Char>
- env_proxy<Char> operator[](const std::basic_string<Char> & key) const
- {
- return {key};
- }
- template<typename Char>
- env_proxy<Char> operator[](const Char* key) const
- {
- return {key};
- }
- template<typename Char>
- env_init<Char> operator()(const basic_environment<Char> & env) const
- {
- return {env};
- }
- template<typename Char>
- env_init<Char> operator= (const basic_environment<Char> & env) const
- {
- return {env};
- }
-};
- -template<typename Char>
-struct env_builder
-{
- basic_environment<Char> env;
- env_builder() : env{basic_native_environment<Char>()} {}
-
- void operator()(const basic_environment<Char> & e)
- {
- env = e;
- }
- - void operator()(env_init<Char> & ei)
- {
- env = std::move(ei.env);
- }
- void operator()(env_set<Char> & es)
- {
- env[es.key] = es.value;
- }
- void operator()(env_reset<Char> & es)
- {
- env.erase(es.key);
- }
- template<typename T>
- void operator()(env_append<T> & es)
- {
- env[es.key] += es.value;
- }
- - typedef api::env_init<Char> result_type;
- api::env_init<Char> get_initializer()
- {
- return api::env_init<Char>(std::move(env));
- }
-};
- -template<>
-struct initializer_builder<env_tag<char>>
-{
- typedef env_builder<char> type;
-};
- -template<>
-struct initializer_builder<env_tag<wchar_t>>
-{
- typedef env_builder<wchar_t> type;
-};
- -}
- -/**
- -The `env` property provides a functional way to modify the environment used by
-the child process. If none is passed the environment is inherited from the father
-process. Appending means that the environment will be interpreted as a ';' or ':'
-seperated list as used in `PATH`.
- -On both `posix` and `windows` the environment variables can be lists of strings,
-seperated by ';'. This is typically used for the `PATH` variable.
- -By default the environment will be inherited from the launching process,
-which is also true if environment are modified with this initializer.
- -\section env_details Details
- -\subsection env_operations Operations
- -\subsubsection env_set_var Setting variables
+// 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_ENV_HPP_ +#define BOOST_PROCESS_DETAIL_ENV_HPP_ + +#include <boost/process/environment.hpp> +#include <boost/none.hpp> + +#if defined(BOOST_POSIX_API) +#include <boost/process/detail/posix/env_init.hpp> +#elif defined(BOOST_WINDOWS_API) +#include <boost/process/detail/windows/env_init.hpp> +#endif + +/** \file boost/process/env.hpp + * + * This header which provides the `env` property. It allows the modification of the + * environment the child process will run in, in a functional style. + * + * \xmlonly +<programlisting> +namespace boost { + namespace process { + <emphasis>unspecified</emphasis> <globalname alt="boost::process::env">env</globalname>; + } +} +</programlisting> + * \endxmlonly + * + * For additional information see the platform documentations: + * + * - [windows](https://msdn.microsoft.com/en-US/library/windows/desktop/ms682653.aspx) + * - [posix](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html) + * + */ + + +namespace boost { + +namespace process { namespace detail { + + +template<typename Char> +std::size_t make_env_string_size(const std::basic_string<Char> & ch) +{ + return ch.size() + 1; +} + +template<typename Char> +std::size_t make_env_string_size(const Char * ch) +{ + std::size_t sz = 0; + while (ch[sz] != null_char<Char>()) + sz++; + + sz++; + return sz; +} + +template<typename Char, typename Container> +inline std::basic_string<Char> make_env_string(const Container & value) +{ + std::size_t sz = 0; + for (auto & v : value) + sz += make_env_string_size(v); + + std::basic_string<Char> s; + s.reserve(sz); //+1 for ;, end doesn't have one. + + for (auto & val : value) + (s += val) += api::env_seperator<Char>(); + + s.resize(s.size() -1); //remove last ';' + return s; +} + + +template<typename Char> +struct env_set +{ + using string_type = std::basic_string<Char>; + string_type key; + string_type value; +}; + +template<typename Char> +struct env_append +{ + using string_type = std::basic_string<Char>; + string_type key; + string_type value; +}; + + + +template<typename Char> +struct env_reset +{ + using string_type = std::basic_string<Char>; + string_type key; +}; + + +template<> struct is_wchar_t<env_set<wchar_t>> : std::true_type {}; +template<> struct is_wchar_t<env_append<wchar_t>> : std::true_type {}; +template<> struct is_wchar_t<env_reset<wchar_t>> : std::true_type {}; +template<> struct is_wchar_t<basic_environment<wchar_t>> : std::true_type {}; + + +template<> +struct char_converter<char, env_set<wchar_t>> +{ + static env_set<char> conv(const env_set<wchar_t> & in) + { + return {::boost::process::detail::convert(in.key), + ::boost::process::detail::convert(in.value)}; + } +}; + +template<> +struct char_converter<wchar_t, env_set<char>> +{ + static env_set<wchar_t> conv(const env_set<char> & in) + { + return {::boost::process::detail::convert(in.key), + ::boost::process::detail::convert(in.value)}; + } +}; + +template<> +struct char_converter<char, env_append<wchar_t>> +{ + static env_append<char> conv(const env_append<wchar_t> & in) + { + return {::boost::process::detail::convert(in.key), + ::boost::process::detail::convert(in.value)}; + } +}; + +template<> +struct char_converter<wchar_t, env_append<char>> +{ + static env_append<wchar_t> conv(const env_append<char> & in) + { + return {::boost::process::detail::convert(in.key), + ::boost::process::detail::convert(in.value)}; + } +}; + +template<> +struct char_converter<char, env_reset<wchar_t>> +{ + static env_reset<char> conv(const env_reset<wchar_t> & in) + { + return {::boost::process::detail::convert(in.key)}; + } +}; + +template<> +struct char_converter<wchar_t, env_reset<char>> +{ + static env_reset<wchar_t> conv(const env_reset<char> & in) + { + return {::boost::process::detail::convert(in.key)}; + } +}; + + +template<typename Char> +struct env_init +{ + basic_environment<Char> env; +}; + +template<> +struct char_converter<char, env_init<wchar_t>> +{ + static env_init<char> conv(const env_init<wchar_t> & in) + { + return {basic_environment<char>(in.env)}; + } +}; + +template<> +struct char_converter<wchar_t, env_init<char>> +{ + static env_init<wchar_t> conv(const env_init<char> & in) + { + return {basic_environment<wchar_t>(in.env)}; + } +}; + +template<> +struct char_converter<char, basic_environment<wchar_t>> +{ + static basic_environment<char> conv(const basic_environment<wchar_t> & in) + { + return { basic_environment<char>(in) }; + } +}; + +template<> +struct char_converter<wchar_t, basic_environment<char>> +{ + static basic_environment<wchar_t> conv(const basic_environment<char> & in) + { + return { basic_environment<wchar_t>(in) }; + } +}; + +template<typename Char> +struct env_proxy +{ + using string_type = std::basic_string<Char>; + string_type key; + + + env_set<Char> operator=(const string_type & value) + { + return {std::move(key), value}; + } + env_set<Char> operator=(const std::vector<string_type> & value) + { + return {std::move(key), make_env_string<Char>(value)}; + } + env_set<Char> operator=(const std::initializer_list<const Char*> & value) + { + return {std::move(key), make_env_string<Char>(value)}; + } + + env_append<Char> operator+=(const string_type & value) + { + return {std::move(key), value}; + } + env_append<Char> operator+=(const std::vector<string_type> & value) + { + return {std::move(key), make_env_string<Char>(value)}; + } + env_append<Char> operator+=(const std::initializer_list<const Char*> & value) + { + return {std::move(key), make_env_string<Char>(value)}; + } + env_reset<Char> operator=(boost::none_t) + { + return {std::move(key)}; + } +}; + +struct env_ +{ + constexpr env_() {}; + + template<typename Char> + env_set<Char> operator()(const std::basic_string<Char> & key, + const std::basic_string<Char> & value) const + { + return {key, value}; + } + template<typename Char> + env_set<Char> operator()(const std::basic_string<Char> & key, + const std::vector<std::basic_string<Char>> & value) const + { + return {key, make_env_string<Char>(value)}; + } + template<typename Char> + env_set<Char> operator()(const std::basic_string<Char> & key, + const std::initializer_list<Char*> & value) const + { + return {key, make_env_string<Char>(value)}; + } + template<typename Char> + env_reset<Char> operator()(const std::basic_string<Char> & key, boost::none_t) + { + return {key}; + } + template<typename Char> + env_proxy<Char> operator[](const std::basic_string<Char> & key) const + { + return {key}; + } + template<typename Char> + env_proxy<Char> operator[](const Char* key) const + { + return {key}; + } + template<typename Char> + env_init<Char> operator()(const basic_environment<Char> & env) const + { + return {env}; + } + template<typename Char> + env_init<Char> operator= (const basic_environment<Char> & env) const + { + return {env}; + } +}; + +template<typename Char> +struct env_builder +{ + basic_environment<Char> env; + env_builder() : env{basic_native_environment<Char>()} {} + + void operator()(const basic_environment<Char> & e) + { + env = e; + } + + void operator()(env_init<Char> & ei) + { + env = std::move(ei.env); + } + void operator()(env_set<Char> & es) + { + env[es.key] = es.value; + } + void operator()(env_reset<Char> & es) + { + env.erase(es.key); + } + template<typename T> + void operator()(env_append<T> & es) + { + env[es.key] += es.value; + } + + typedef api::env_init<Char> result_type; + api::env_init<Char> get_initializer() + { + return api::env_init<Char>(std::move(env)); + } +}; + +template<> +struct initializer_builder<env_tag<char>> +{ + typedef env_builder<char> type; +}; + +template<> +struct initializer_builder<env_tag<wchar_t>> +{ + typedef env_builder<wchar_t> type; +}; + +} + +/** + +The `env` property provides a functional way to modify the environment used by +the child process. If none is passed the environment is inherited from the father +process. Appending means that the environment will be interpreted as a ';' or ':' +separated list as used in `PATH`. + +On both `posix` and `windows` the environment variables can be lists of strings, +separated by ';'. This is typically used for the `PATH` variable. + +By default the environment will be inherited from the launching process, +which is also true if environment are modified with this initializer. + +\section env_details Details + +\subsection env_operations Operations -To set a variable `id` the value `value` the following syntax can be used.
+\subsubsection env_set_var Setting variables -\code{.cpp}
-env[id] = value;
-env(id, value);
-\endcode
+To set a variable `id` the value `value` the following syntax can be used. -`std::initializer_list` is among the allowed types, so the following syntax is also possible.
+\code{.cpp} +env[id] = value; +env(id, value); +\endcode -\code{.cpp}
-env[id] = {value1, value2};
-env(id, {value1, value2});
-\endcode
+`std::initializer_list` is among the allowed types, so the following syntax is also possible. -\note Creates the variable if it does not exist.
+\code{.cpp} +env[id] = {value1, value2}; +env(id, {value1, value2}); +\endcode -The following lists contain possible value types, with `char_type` being either `char` or `wchar_t`
-for both `id` and `value`.
+\note Creates the variable if it does not exist. -\paragraph id id
+The following lists contain possible value types, with `char_type` being either `char` or `wchar_t` +for both `id` and `value`. - - `std::basic_string<char_type>`
- - `const char_type *`
+\paragraph id id -\paragraph env_set_var_value value
+ - `std::basic_string<char_type>` + - `const char_type *` - - `std::basic_string<char_type>`
- - `const char_type * `
- - `std::initializer_list<const char_type *>`
- - `std::vector<std::basic_string<char_type>>`
+\paragraph env_set_var_value value + - `std::basic_string<char_type>` + - `const char_type * ` + - `std::initializer_list<const char_type *>` + - `std::vector<std::basic_string<char_type>>` -\note Using `std::vector` or `std::initializer_list`
-\subsubsection env_append_var Append variables
+\note Using `std::vector` or `std::initializer_list` -Appending means, that a variable will be interpreted as a
-To append a variable `id` the value `value` the following syntax can be used:
+\subsubsection env_append_var Append variables -\code{.cpp}
-env[id] += value;
-\endcode
+Appending means, that a variable will be interpreted as a +To append a variable `id` the value `value` the following syntax can be used: -`std::initializer_list` is among the allowed types, so the following syntax is also possible.
+\code{.cpp} +env[id] += value; +\endcode -\code{.cpp}
-env[id] += {value1, value2};
-\endcode
+`std::initializer_list` is among the allowed types, so the following syntax is also possible. -\note Creates the variable if it does not exist.
+\code{.cpp} +env[id] += {value1, value2}; +\endcode -The following lists contain possible value types, with `char_type` being either `char` or `wchar_t`
-for both `id` and `value`.
+\note Creates the variable if it does not exist. -\paragraph env_append_var_id id
+The following lists contain possible value types, with `char_type` being either `char` or `wchar_t` +for both `id` and `value`. - - `std::basic_string<char_type>`
- - `const char_type *`
+\paragraph env_append_var_id id -\paragraph env_append_var_value value
+ - `std::basic_string<char_type>` + - `const char_type *` - - `std::basic_string<char_type>`
- - `const char_type *`
- - `std::initializer_list<const char_type *>`
- - `std::vector<std::basic_string<char_type>>`
+\paragraph env_append_var_value value + - `std::basic_string<char_type>` + - `const char_type *` + - `std::initializer_list<const char_type *>` + - `std::vector<std::basic_string<char_type>>` -\subsubsection env_reset Reset variables
-Reseting signle variables can be done in the following way:
+\subsubsection env_reset Reset variables -\code{.cpp}
-env[id] = boost::none;
-env(id, boost::none);
-\endcode
+Reseting signle variables can be done in the following way: -\note This does not set the value empty, but removes it from the list.
+\code{.cpp} +env[id] = boost::none; +env(id, boost::none); +\endcode -The following lists contain possible value types, with `char_type` being either `char` or `wchar_t`:
+\note This does not set the value empty, but removes it from the list. -\paragraph env_reset_var_id id
+The following lists contain possible value types, with `char_type` being either `char` or `wchar_t`: - - `std::basic_string<char_type>`
- - `const char_type *`
+\paragraph env_reset_var_id id -\subsubsection env_init Initialize the environment
+ - `std::basic_string<char_type>` + - `const char_type *` -The whole environment can be initialized from an object of type
-\xmlonly <classname>boost::process::environment</classname> \endxmlonly
+\subsubsection env_init Initialize the environment -\code{.cpp}
-env=env;
-env(env);
-\endcode
+The whole environment can be initialized from an object of type +\xmlonly <classname>boost::process::environment</classname> \endxmlonly -\note The passed `environment` can also be default-constructed to get an empty environment.
+\code{.cpp} +env=env; +env(env); +\endcode -\paragraph env_init_var_id id
+\note The passed `environment` can also be default-constructed to get an empty environment. - - `std::basic_string<char_type>`
- - `const char_type *`
+\paragraph env_init_var_id id -\paragraph env_init_var_value value
+ - `std::basic_string<char_type>` + - `const char_type *` - - `boost::process::basic_environment<char_type>`
+\paragraph env_init_var_value value -\subsection env_example Example
+ - `boost::process::basic_environment<char_type>` -\code{.cpp}
-spawn("b2", env["PATH"]+="F:/boost", env["SOME_VAR"]=boost::none, env["NEW_VAR"]="VALUE");
-\endcode
+\subsection env_example Example -If the overload style should be done by passing an instance of
-\xmlonly <classname>boost::process::environment</classname> \endxmlonly
-the above example would look like this.
+\code{.cpp} +spawn("b2", env["PATH"]+="F:/boost", env["SOME_VAR"]=boost::none, env["NEW_VAR"]="VALUE"); +\endcode -\code{.cpp}
-environment e = this_process::environment();
-e["PATH"] += "F:/boost";
-e.erase("SOME_VAR");
-e["NEW_VAR"] = "VALUE";
-spawn("b2", e);
-\endcode
+If the overload style should be done by passing an instance of +\xmlonly <classname>boost::process::environment</classname> \endxmlonly +the above example would look like this. -\warning Passing an empty environment will cause undefined behaviour.
+\code{.cpp} +environment e = this_process::environment(); +e["PATH"] += "F:/boost"; +e.erase("SOME_VAR"); +e["NEW_VAR"] = "VALUE"; +spawn("b2", e); +\endcode - */
-constexpr boost::process::detail::env_ env{};
+\warning Passing an empty environment will cause undefined behaviour. + */ +constexpr boost::process::detail::env_ env{}; -}}
-#endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENV_HPP_ */
+}} + +#endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENV_HPP_ */ diff --git a/boost/process/environment.hpp b/boost/process/environment.hpp index 1684798b87..d8b70fefb8 100644 --- a/boost/process/environment.hpp +++ b/boost/process/environment.hpp @@ -472,17 +472,17 @@ public: ///Assign a string to the value void assign(const string_type &value); - ///Assign a set of strings to the entry; they will be seperated by ';' or ':'. + ///Assign a set of strings to the entry; they will be separated by ';' or ':'. void assign(const std::vector<string_type> &value); - ///Append a string to the end of the entry, it will seperated by ';' or ':'. + ///Append a string to the end of the entry, it will separated by ';' or ':'. void append(const string_type &value); ///Reset the value void clear(); ///Assign a string to the entry. entry &operator=(const string_type & value); - ///Assign a set of strings to the entry; they will be seperated by ';' or ':'. + ///Assign a set of strings to the entry; they will be separated by ';' or ':'. entry &operator=(const std::vector<string_type> & value); - ///Append a string to the end of the entry, it will seperated by ';' or ':'. + ///Append a string to the end of the entry, it will separated by ';' or ':'. entry &operator+=(const string_type & value); }; @@ -592,17 +592,17 @@ public: ///Assign a string to the value void assign(const string_type &value); - ///Assign a set of strings to the entry; they will be seperated by ';' or ':'. + ///Assign a set of strings to the entry; they will be separated by ';' or ':'. void assign(const std::vector<string_type> &value); - ///Append a string to the end of the entry, it will seperated by ';' or ':'. + ///Append a string to the end of the entry, it will separated by ';' or ':'. void append(const string_type &value); ///Reset the value void clear(); ///Assign a string to the entry. entry &operator=(const string_type & value); - ///Assign a set of strings to the entry; they will be seperated by ';' or ':'. + ///Assign a set of strings to the entry; they will be separated by ';' or ':'. entry &operator=(const std::vector<string_type> & value); - ///Append a string to the end of the entry, it will seperated by ';' or ':'. + ///Append a string to the end of the entry, it will separated by ';' or ':'. entry &operator+=(const string_type & value); }; diff --git a/boost/process/exe.hpp b/boost/process/exe.hpp index 04a63bc754..3c0303a9e1 100644 --- a/boost/process/exe.hpp +++ b/boost/process/exe.hpp @@ -1,79 +1,79 @@ -// 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)
+// 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_EXE_HPP
-#define BOOST_PROCESS_EXE_HPP
+#ifndef BOOST_PROCESS_EXE_HPP +#define BOOST_PROCESS_EXE_HPP -#include <boost/process/detail/basic_cmd.hpp>
+#include <boost/process/detail/basic_cmd.hpp> -/** \file boost/process/exe.hpp
- *
- * Header which provides the exe property.
-\xmlonly
-<programlisting>
-namespace boost {
- namespace process {
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::exe">exe</globalname>;
- }
-}
-</programlisting>
-\endxmlonly
- */
-namespace boost { namespace process { namespace detail {
+/** \file boost/process/exe.hpp + * + * Header which provides the exe property. +\xmlonly +<programlisting> +namespace boost { + namespace process { + <emphasis>unspecified</emphasis> <globalname alt="boost::process::exe">exe</globalname>; + } +} +</programlisting> +\endxmlonly + */ +namespace boost { namespace process { namespace detail { -struct exe_
-{
- template<typename Char>
- inline exe_setter_<Char> operator()(const Char *s) const
- {
- return exe_setter_<Char>(s);
- }
- template<typename Char>
- inline exe_setter_<Char> operator= (const Char *s) const
- {
- return exe_setter_<Char>(s);
- }
+struct exe_ +{ + template<typename Char> + inline exe_setter_<Char> operator()(const Char *s) const + { + return exe_setter_<Char>(s); + } + template<typename Char> + inline exe_setter_<Char> operator= (const Char *s) const + { + return exe_setter_<Char>(s); + } - template<typename Char>
- inline exe_setter_<Char> operator()(const std::basic_string<Char> &s) const
- {
- return exe_setter_<Char>(s);
- }
- template<typename Char>
- inline exe_setter_<Char> operator= (const std::basic_string<Char> &s) const
- {
- return exe_setter_<Char>(s);
- }
-};
+ template<typename Char> + inline exe_setter_<Char> operator()(const std::basic_string<Char> &s) const + { + return exe_setter_<Char>(s); + } + template<typename Char> + inline exe_setter_<Char> operator= (const std::basic_string<Char> &s) const + { + return exe_setter_<Char>(s); + } +}; -}
+} -/** The exe property allows to explicitly set the executable.
+/** The exe property allows to explicitly set the executable. -The overload form applies when to the first, when several strings are passed to a launching
-function.
+The overload form applies when to the first, when several strings are passed to a launching +function. -The following expressions are valid, with `value` being either a C-String or
-a `std::basic_string` with `char` or `wchar_t` or a `boost::filesystem::path`.
+The following expressions are valid, with `value` being either a C-String or +a `std::basic_string` with `char` or `wchar_t` or a `boost::filesystem::path`. -\code{.cpp}
-exe="value";
-exe(value);
-\endcode
+\code{.cpp} +exe="value"; +exe(value); +\endcode -The property can only be used for assignments.
+The property can only be used for assignments. - */
-constexpr boost::process::detail::exe_ exe{};
+ */ +constexpr boost::process::detail::exe_ exe{}; -}}
+}} -#endif
+#endif diff --git a/boost/process/extend.hpp b/boost/process/extend.hpp index 7496f30f16..219b522730 100644 --- a/boost/process/extend.hpp +++ b/boost/process/extend.hpp @@ -33,7 +33,7 @@ namespace boost { namespace process { namespace detail { template<typename Tuple> -inline asio::io_service& get_io_service(const Tuple & tup); +inline asio::io_context& get_io_context(const Tuple & tup); } @@ -57,9 +57,9 @@ struct windows_executor; #endif using ::boost::process::detail::handler; -using ::boost::process::detail::api::require_io_service; +using ::boost::process::detail::api::require_io_context; using ::boost::process::detail::api::async_handler; -using ::boost::process::detail::get_io_service; +using ::boost::process::detail::get_io_context; using ::boost::process::detail::get_last_error; using ::boost::process::detail::throw_last_error; @@ -91,13 +91,13 @@ inline void throw_last_error(const std::string & msg); inline void throw_last_error(); -/** This function gets the io_service from the initializer sequence. +/** This function gets the io_context from the initializer sequence. * - * \attention Yields a compile-time error if no `io_service` is provided. + * \attention Yields a compile-time error if no `io_context` is provided. * \param seq The Sequence of the initializer. */ template<typename Sequence> -inline asio::io_service& get_io_service(const Sequence & seq); +inline asio::io_context& get_io_context(const Sequence & seq); /** This class is the base for every initializer, to be used for extensions. * @@ -149,14 +149,14 @@ struct handler }; -/** Inheriting the class will tell the launching process that an `io_service` is - * needed. This should always be used when \ref get_io_service is used. +/** Inheriting the class will tell the launching process that an `io_context` is + * needed. This should always be used when \ref get_io_context is used. * */ -struct require_io_service {}; +struct require_io_context {}; /** Inheriting this class will tell the launching function, that an event handler * shall be invoked when the process exits. This automatically does also inherit - * \ref require_io_service. + * \ref require_io_context. * * You must add the following function to your implementation: * @@ -179,7 +179,7 @@ std::function<void(int, const std::error_code&)> on_exit_handler(Executor & exec * * \warning Cannot be used with \ref boost::process::spawn */ -struct async_handler : handler, require_io_service +struct async_handler : handler, require_io_context { }; @@ -241,7 +241,7 @@ struct posix_executor char **env = ::environ; ///The pid of the process - it will be -1 before invoking [fork](http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html), and after forking either 0 for the new process or a positive value if in the current process. */ pid_t pid = -1; - ///This shared-pointer holds the exit code. It's done this way, so it can be shared between an `asio::io_service` and \ref child. + ///This shared-pointer holds the exit code. It's done this way, so it can be shared between an `asio::io_context` and \ref child. std::shared_ptr<std::atomic<int>> exit_status = std::make_shared<std::atomic<int>>(still_active); ///This function returns a const reference to the error state of the executor. @@ -302,7 +302,7 @@ struct windows_executor ::boost::detail::winapi::PROCESS_INFORMATION_ proc_info{nullptr, nullptr, 0,0}; - ///This shared-pointer holds the exit code. It's done this way, so it can be shared between an `asio::io_service` and \ref child. + ///This shared-pointer holds the exit code. It's done this way, so it can be shared between an `asio::io_context` and \ref child. std::shared_ptr<std::atomic<int>> exit_status = std::make_shared<std::atomic<int>>(still_active); ///This function returns a const reference to the error state of the executor. diff --git a/boost/process/io.hpp b/boost/process/io.hpp index 85a143ca31..5dd541a2a5 100644 --- a/boost/process/io.hpp +++ b/boost/process/io.hpp @@ -1,551 +1,551 @@ -// 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_IO_HPP_
-#define BOOST_PROCESS_IO_HPP_
- -#include <iosfwd>
-#include <cstdio>
-#include <functional>
-#include <utility>
-#include <boost/process/detail/config.hpp>
-#include <boost/process/pipe.hpp>
- -#include <future>
- -#if defined(BOOST_POSIX_API)
-#include <boost/process/detail/posix/asio_fwd.hpp>
-#include <boost/process/detail/posix/close_in.hpp>
-#include <boost/process/detail/posix/close_out.hpp>
-#include <boost/process/detail/posix/null_in.hpp>
-#include <boost/process/detail/posix/null_out.hpp>
-#include <boost/process/detail/posix/file_in.hpp>
-#include <boost/process/detail/posix/file_out.hpp>
-#include <boost/process/detail/posix/pipe_in.hpp>
-#include <boost/process/detail/posix/pipe_out.hpp>
-#elif defined(BOOST_WINDOWS_API)
-#include <boost/process/detail/windows/asio_fwd.hpp>
-#include <boost/process/detail/windows/close_in.hpp>
-#include <boost/process/detail/windows/close_out.hpp>
-#include <boost/process/detail/windows/null_in.hpp>
-#include <boost/process/detail/windows/null_out.hpp>
-#include <boost/process/detail/windows/file_in.hpp>
-#include <boost/process/detail/windows/file_out.hpp>
-#include <boost/process/detail/windows/pipe_in.hpp>
-#include <boost/process/detail/windows/pipe_out.hpp>
-#endif
- -/** \file boost/process/io.hpp
- *
- * Header which provides the io properties. It provides the following properties:
- *
-\xmlonly
-<programlisting>
-namespace boost {
- namespace process {
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::close">close</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::null">null</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::std_in">std_in</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::std_out">std_out</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::std_err">std_err</globalname>;
- }
-}
-</programlisting>
-\endxmlonly
- -\par File I/O
- -The library allows full redirection of streams to files as shown below.
- -\code{.cpp}
-boost::filesystem::path log = "my_log_file.txt";
-boost::filesystem::path input = "input.txt";
-boost::filesystem::path output = "output.txt";
-system("my_prog", std_out>output, std_in<input, std_err>log);
-\endcode
- -\par Synchronous Pipe I/O
- -Another way is to communicate through pipes.
- -\code{.cpp}
-pstream str;
-child c("my_prog", std_out > str);
- -int i;
-str >> i;
-\endcode
- -Note that the pipe may also be used between several processes, like this:
- -\code{.cpp}
-pipe p;
-child c1("nm", "a.out", std_out>p);
-child c2("c++filt", std_in<p);
-\endcode
- -\par Asynchronous I/O
- -Utilizing `boost.asio` asynchronous I/O is provided.
- -\code
-boost::asio::io_service ios;
-std::future<std::string> output;
-system("ls", std_out > output, ios);
- -auto res = fut.get();
-\endcode
- -\note `boost/process/asnyc.hpp` must also be included for this to work.
- -\par Closing
- -Stream can be closed, so nothing can be read or written.
- -\code{.cpp}
-system("foo", std_in.close());
-\endcode
- -\par Null
- -Streams can be redirected to null, which means, that written date will be
-discarded and read data will only contain `EOF`.
- -\code{.cpp}
-system("b2", std_out > null);
-\endcode
- - *
- */
- -namespace boost { namespace process { namespace detail {
- - -template<typename T> using is_streambuf = typename std::is_same<T, boost::asio::streambuf>::type;
-template<typename T> using is_const_buffer =
- std::integral_constant<bool,
- std::is_same< boost::asio::const_buffer, T>::value |
- std::is_base_of<boost::asio::const_buffer, T>::value
- >;
-template<typename T> using is_mutable_buffer =
- std::integral_constant<bool,
- std::is_same< boost::asio::mutable_buffer, T>::value |
- std::is_base_of<boost::asio::mutable_buffer, T>::value
- >;
- - -struct null_t {constexpr null_t() {}};
-struct close_t;
- -template<class>
-struct std_in_
-{
- constexpr std_in_() {}
- - api::close_in close() const {return api::close_in(); }
- api::close_in operator=(const close_t &) const {return api::close_in();}
- api::close_in operator<(const close_t &) const {return api::close_in();}
- - api::null_in null() const {return api::null_in();}
- api::null_in operator=(const null_t &) const {return api::null_in();}
- api::null_in operator<(const null_t &) const {return api::null_in();}
- - api::file_in operator=(const boost::filesystem::path &p) const {return p;}
- api::file_in operator=(const std::string & p) const {return p;}
- api::file_in operator=(const std::wstring &p) const {return p;}
- api::file_in operator=(const char * p) const {return p;}
- api::file_in operator=(const wchar_t * p) const {return p;}
- - api::file_in operator<(const boost::filesystem::path &p) const {return p;}
- api::file_in operator<(const std::string &p) const {return p;}
- api::file_in operator<(const std::wstring &p) const {return p;}
- api::file_in operator<(const char*p) const {return p;}
- api::file_in operator<(const wchar_t * p) const {return p;}
- - api::file_in operator=(FILE * f) const {return f;}
- api::file_in operator<(FILE * f) const {return f;}
+// 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_IO_HPP_ +#define BOOST_PROCESS_IO_HPP_ + +#include <iosfwd> +#include <cstdio> +#include <functional> +#include <utility> +#include <boost/process/detail/config.hpp> +#include <boost/process/pipe.hpp> + +#include <future> + +#if defined(BOOST_POSIX_API) +#include <boost/process/detail/posix/asio_fwd.hpp> +#include <boost/process/detail/posix/close_in.hpp> +#include <boost/process/detail/posix/close_out.hpp> +#include <boost/process/detail/posix/null_in.hpp> +#include <boost/process/detail/posix/null_out.hpp> +#include <boost/process/detail/posix/file_in.hpp> +#include <boost/process/detail/posix/file_out.hpp> +#include <boost/process/detail/posix/pipe_in.hpp> +#include <boost/process/detail/posix/pipe_out.hpp> +#elif defined(BOOST_WINDOWS_API) +#include <boost/process/detail/windows/asio_fwd.hpp> +#include <boost/process/detail/windows/close_in.hpp> +#include <boost/process/detail/windows/close_out.hpp> +#include <boost/process/detail/windows/null_in.hpp> +#include <boost/process/detail/windows/null_out.hpp> +#include <boost/process/detail/windows/file_in.hpp> +#include <boost/process/detail/windows/file_out.hpp> +#include <boost/process/detail/windows/pipe_in.hpp> +#include <boost/process/detail/windows/pipe_out.hpp> +#endif + +/** \file boost/process/io.hpp + * + * Header which provides the io properties. It provides the following properties: + * +\xmlonly +<programlisting> +namespace boost { + namespace process { + <emphasis>unspecified</emphasis> <globalname alt="boost::process::close">close</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::null">null</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::std_in">std_in</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::std_out">std_out</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::std_err">std_err</globalname>; + } +} +</programlisting> +\endxmlonly + +\par File I/O + +The library allows full redirection of streams to files as shown below. + +\code{.cpp} +boost::filesystem::path log = "my_log_file.txt"; +boost::filesystem::path input = "input.txt"; +boost::filesystem::path output = "output.txt"; +system("my_prog", std_out>output, std_in<input, std_err>log); +\endcode + +\par Synchronous Pipe I/O + +Another way is to communicate through pipes. + +\code{.cpp} +pstream str; +child c("my_prog", std_out > str); + +int i; +str >> i; +\endcode + +Note that the pipe may also be used between several processes, like this: + +\code{.cpp} +pipe p; +child c1("nm", "a.out", std_out>p); +child c2("c++filt", std_in<p); +\endcode + +\par Asynchronous I/O + +Utilizing `boost.asio` asynchronous I/O is provided. + +\code +boost::asio::io_context ios; +std::future<std::string> output; +system("ls", std_out > output, ios); + +auto res = fut.get(); +\endcode + +\note `boost/process/async.hpp` must also be included for this to work. + +\par Closing + +Stream can be closed, so nothing can be read or written. + +\code{.cpp} +system("foo", std_in.close()); +\endcode + +\par Null + +Streams can be redirected to null, which means, that written date will be +discarded and read data will only contain `EOF`. + +\code{.cpp} +system("b2", std_out > null); +\endcode + + * + */ + +namespace boost { namespace process { namespace detail { + + +template<typename T> using is_streambuf = typename std::is_same<T, boost::asio::streambuf>::type; +template<typename T> using is_const_buffer = + std::integral_constant<bool, + std::is_same< boost::asio::const_buffer, T>::value | + std::is_base_of<boost::asio::const_buffer, T>::value + >; +template<typename T> using is_mutable_buffer = + std::integral_constant<bool, + std::is_same< boost::asio::mutable_buffer, T>::value | + std::is_base_of<boost::asio::mutable_buffer, T>::value + >; + + +struct null_t {constexpr null_t() {}}; +struct close_t; + +template<class> +struct std_in_ +{ + constexpr std_in_() {} + + api::close_in close() const {return api::close_in(); } + api::close_in operator=(const close_t &) const {return api::close_in();} + api::close_in operator<(const close_t &) const {return api::close_in();} + + api::null_in null() const {return api::null_in();} + api::null_in operator=(const null_t &) const {return api::null_in();} + api::null_in operator<(const null_t &) const {return api::null_in();} + + api::file_in operator=(const boost::filesystem::path &p) const {return p;} + api::file_in operator=(const std::string & p) const {return p;} + api::file_in operator=(const std::wstring &p) const {return p;} + api::file_in operator=(const char * p) const {return p;} + api::file_in operator=(const wchar_t * p) const {return p;} + + api::file_in operator<(const boost::filesystem::path &p) const {return p;} + api::file_in operator<(const std::string &p) const {return p;} + api::file_in operator<(const std::wstring &p) const {return p;} + api::file_in operator<(const char*p) const {return p;} + api::file_in operator<(const wchar_t * p) const {return p;} + + api::file_in operator=(FILE * f) const {return f;} + api::file_in operator<(FILE * f) const {return f;} - template<typename Char, typename Traits> api::pipe_in operator=(basic_pipe<Char, Traits> & p) const {return p;}
- template<typename Char, typename Traits> api::pipe_in operator<(basic_pipe<Char, Traits> & p) const {return p;}
- template<typename Char, typename Traits> api::pipe_in operator=(basic_opstream<Char, Traits> & p) const {return p.pipe();}
- template<typename Char, typename Traits> api::pipe_in operator<(basic_opstream<Char, Traits> & p) const {return p.pipe();}
- template<typename Char, typename Traits> api::pipe_in operator=(basic_pstream <Char, Traits> & p) const {return p.pipe();}
- template<typename Char, typename Traits> api::pipe_in operator<(basic_pstream <Char, Traits> & p) const {return p.pipe();}
- - api::async_pipe_in operator=(async_pipe & p) const {return p;}
- api::async_pipe_in operator<(async_pipe & p) const {return p;}
- - template<typename T, typename = typename std::enable_if<
- is_const_buffer<T>::value || is_mutable_buffer<T>::value
- >::type>
- api::async_in_buffer<const T> operator=(const T & buf) const {return buf;}
- template<typename T, typename = typename std::enable_if<is_streambuf<T>::value>::type >
- api::async_in_buffer<T> operator=(T & buf) const {return buf;}
+ template<typename Char, typename Traits> api::pipe_in operator=(basic_pipe<Char, Traits> & p) const {return p;} + template<typename Char, typename Traits> api::pipe_in operator<(basic_pipe<Char, Traits> & p) const {return p;} + template<typename Char, typename Traits> api::pipe_in operator=(basic_opstream<Char, Traits> & p) const {return p.pipe();} + template<typename Char, typename Traits> api::pipe_in operator<(basic_opstream<Char, Traits> & p) const {return p.pipe();} + template<typename Char, typename Traits> api::pipe_in operator=(basic_pstream <Char, Traits> & p) const {return p.pipe();} + template<typename Char, typename Traits> api::pipe_in operator<(basic_pstream <Char, Traits> & p) const {return p.pipe();} + + api::async_pipe_in operator=(async_pipe & p) const {return p;} + api::async_pipe_in operator<(async_pipe & p) const {return p;} + + template<typename T, typename = typename std::enable_if< + is_const_buffer<T>::value || is_mutable_buffer<T>::value + >::type> + api::async_in_buffer<const T> operator=(const T & buf) const {return buf;} + template<typename T, typename = typename std::enable_if<is_streambuf<T>::value>::type > + api::async_in_buffer<T> operator=(T & buf) const {return buf;} - template<typename T, typename = typename std::enable_if<
- is_const_buffer<T>::value || is_mutable_buffer<T>::value
- >::type>
- api::async_in_buffer<const T> operator<(const T & buf) const {return buf;}
- template<typename T, typename = typename std::enable_if<is_streambuf<T>::value>::type >
- api::async_in_buffer<T> operator<(T & buf) const {return buf;}
- -};
+ template<typename T, typename = typename std::enable_if< + is_const_buffer<T>::value || is_mutable_buffer<T>::value + >::type> + api::async_in_buffer<const T> operator<(const T & buf) const {return buf;} + template<typename T, typename = typename std::enable_if<is_streambuf<T>::value>::type > + api::async_in_buffer<T> operator<(T & buf) const {return buf;} + +}; -//-1 == empty.
-//1 == stdout
-//2 == stderr
-template<int p1, int p2 = -1>
-struct std_out_
-{
- constexpr std_out_() {}
+//-1 == empty. +//1 == stdout +//2 == stderr +template<int p1, int p2 = -1> +struct std_out_ +{ + constexpr std_out_() {} - api::close_out<p1,p2> close() const {return api::close_out<p1,p2>(); }
- api::close_out<p1,p2> operator=(const close_t &) const {return api::close_out<p1,p2>();}
- api::close_out<p1,p2> operator>(const close_t &) const {return api::close_out<p1,p2>();}
- - api::null_out<p1,p2> null() const {return api::null_out<p1,p2>();}
- api::null_out<p1,p2> operator=(const null_t &) const {return api::null_out<p1,p2>();}
- api::null_out<p1,p2> operator>(const null_t &) const {return api::null_out<p1,p2>();}
- - api::file_out<p1,p2> operator=(const boost::filesystem::path &p) const {return api::file_out<p1,p2>(p);}
- api::file_out<p1,p2> operator=(const std::string &p) const {return api::file_out<p1,p2>(p);}
- api::file_out<p1,p2> operator=(const std::wstring &p) const {return api::file_out<p1,p2>(p);}
- api::file_out<p1,p2> operator=(const char * p) const {return api::file_out<p1,p2>(p);}
- api::file_out<p1,p2> operator=(const wchar_t * p) const {return api::file_out<p1,p2>(p);}
- - api::file_out<p1,p2> operator>(const boost::filesystem::path &p) const {return api::file_out<p1,p2>(p);}
- api::file_out<p1,p2> operator>(const std::string &p) const {return api::file_out<p1,p2>(p);}
- api::file_out<p1,p2> operator>(const std::wstring &p) const {return api::file_out<p1,p2>(p);}
- api::file_out<p1,p2> operator>(const char * p) const {return api::file_out<p1,p2>(p);}
- api::file_out<p1,p2> operator>(const wchar_t * p) const {return api::file_out<p1,p2>(p);}
- - api::file_out<p1,p2> operator=(FILE * f) const {return f;}
- api::file_out<p1,p2> operator>(FILE * f) const {return f;}
- - template<typename Char, typename Traits> api::pipe_out<p1,p2> operator=(basic_pipe<Char, Traits> & p) const {return p;}
- template<typename Char, typename Traits> api::pipe_out<p1,p2> operator>(basic_pipe<Char, Traits> & p) const {return p;}
- template<typename Char, typename Traits> api::pipe_out<p1,p2> operator=(basic_ipstream<Char, Traits> & p) const {return p.pipe();}
- template<typename Char, typename Traits> api::pipe_out<p1,p2> operator>(basic_ipstream<Char, Traits> & p) const {return p.pipe();}
- template<typename Char, typename Traits> api::pipe_out<p1,p2> operator=(basic_pstream <Char, Traits> & p) const {return p.pipe();}
- template<typename Char, typename Traits> api::pipe_out<p1,p2> operator>(basic_pstream <Char, Traits> & p) const {return p.pipe();}
- - api::async_pipe_out<p1, p2> operator=(async_pipe & p) const {return p;}
- api::async_pipe_out<p1, p2> operator>(async_pipe & p) const {return p;}
+ api::close_out<p1,p2> close() const {return api::close_out<p1,p2>(); } + api::close_out<p1,p2> operator=(const close_t &) const {return api::close_out<p1,p2>();} + api::close_out<p1,p2> operator>(const close_t &) const {return api::close_out<p1,p2>();} + + api::null_out<p1,p2> null() const {return api::null_out<p1,p2>();} + api::null_out<p1,p2> operator=(const null_t &) const {return api::null_out<p1,p2>();} + api::null_out<p1,p2> operator>(const null_t &) const {return api::null_out<p1,p2>();} + + api::file_out<p1,p2> operator=(const boost::filesystem::path &p) const {return api::file_out<p1,p2>(p);} + api::file_out<p1,p2> operator=(const std::string &p) const {return api::file_out<p1,p2>(p);} + api::file_out<p1,p2> operator=(const std::wstring &p) const {return api::file_out<p1,p2>(p);} + api::file_out<p1,p2> operator=(const char * p) const {return api::file_out<p1,p2>(p);} + api::file_out<p1,p2> operator=(const wchar_t * p) const {return api::file_out<p1,p2>(p);} + + api::file_out<p1,p2> operator>(const boost::filesystem::path &p) const {return api::file_out<p1,p2>(p);} + api::file_out<p1,p2> operator>(const std::string &p) const {return api::file_out<p1,p2>(p);} + api::file_out<p1,p2> operator>(const std::wstring &p) const {return api::file_out<p1,p2>(p);} + api::file_out<p1,p2> operator>(const char * p) const {return api::file_out<p1,p2>(p);} + api::file_out<p1,p2> operator>(const wchar_t * p) const {return api::file_out<p1,p2>(p);} + + api::file_out<p1,p2> operator=(FILE * f) const {return f;} + api::file_out<p1,p2> operator>(FILE * f) const {return f;} + + template<typename Char, typename Traits> api::pipe_out<p1,p2> operator=(basic_pipe<Char, Traits> & p) const {return p;} + template<typename Char, typename Traits> api::pipe_out<p1,p2> operator>(basic_pipe<Char, Traits> & p) const {return p;} + template<typename Char, typename Traits> api::pipe_out<p1,p2> operator=(basic_ipstream<Char, Traits> & p) const {return p.pipe();} + template<typename Char, typename Traits> api::pipe_out<p1,p2> operator>(basic_ipstream<Char, Traits> & p) const {return p.pipe();} + template<typename Char, typename Traits> api::pipe_out<p1,p2> operator=(basic_pstream <Char, Traits> & p) const {return p.pipe();} + template<typename Char, typename Traits> api::pipe_out<p1,p2> operator>(basic_pstream <Char, Traits> & p) const {return p.pipe();} + + api::async_pipe_out<p1, p2> operator=(async_pipe & p) const {return p;} + api::async_pipe_out<p1, p2> operator>(async_pipe & p) const {return p;} - api::async_out_buffer<p1, p2, const asio::mutable_buffer> operator=(const asio::mutable_buffer & buf) const {return buf;}
- api::async_out_buffer<p1, p2, const asio::mutable_buffers_1> operator=(const asio::mutable_buffers_1 & buf) const {return buf;}
- api::async_out_buffer<p1, p2, asio::streambuf> operator=(asio::streambuf & os) const {return os ;}
- - api::async_out_buffer<p1, p2, const asio::mutable_buffer> operator>(const asio::mutable_buffer & buf) const {return buf;}
- api::async_out_buffer<p1, p2, const asio::mutable_buffers_1> operator>(const asio::mutable_buffers_1 & buf) const {return buf;}
- api::async_out_buffer<p1, p2, asio::streambuf> operator>(asio::streambuf & os) const {return os ;}
- - api::async_out_future<p1,p2, std::string> operator=(std::future<std::string> & fut) const { return fut;}
- api::async_out_future<p1,p2, std::string> operator>(std::future<std::string> & fut) const { return fut;}
- api::async_out_future<p1,p2, std::vector<char>> operator=(std::future<std::vector<char>> & fut) const { return fut;}
- api::async_out_future<p1,p2, std::vector<char>> operator>(std::future<std::vector<char>> & fut) const { return fut;}
- - template<int pin, typename = typename std::enable_if<
- (((p1 == 1) && (pin == 2)) ||
- ((p1 == 2) && (pin == 1)))
- && (p2 == -1)>::type>
- constexpr std_out_<1, 2> operator& (const std_out_<pin>&) const
- {
- return std_out_<1, 2> ();
- }
- -};
- -struct close_t
-{
- constexpr close_t() {}
- template<int T, int U>
- api::close_out<T,U> operator()(std_out_<T,U>) {return api::close_out<T,U>();}
-};
+ api::async_out_buffer<p1, p2, const asio::mutable_buffer> operator=(const asio::mutable_buffer & buf) const {return buf;} + api::async_out_buffer<p1, p2, const asio::mutable_buffers_1> operator=(const asio::mutable_buffers_1 & buf) const {return buf;} + api::async_out_buffer<p1, p2, asio::streambuf> operator=(asio::streambuf & os) const {return os ;} + + api::async_out_buffer<p1, p2, const asio::mutable_buffer> operator>(const asio::mutable_buffer & buf) const {return buf;} + api::async_out_buffer<p1, p2, const asio::mutable_buffers_1> operator>(const asio::mutable_buffers_1 & buf) const {return buf;} + api::async_out_buffer<p1, p2, asio::streambuf> operator>(asio::streambuf & os) const {return os ;} + + api::async_out_future<p1,p2, std::string> operator=(std::future<std::string> & fut) const { return fut;} + api::async_out_future<p1,p2, std::string> operator>(std::future<std::string> & fut) const { return fut;} + api::async_out_future<p1,p2, std::vector<char>> operator=(std::future<std::vector<char>> & fut) const { return fut;} + api::async_out_future<p1,p2, std::vector<char>> operator>(std::future<std::vector<char>> & fut) const { return fut;} + + template<int pin, typename = typename std::enable_if< + (((p1 == 1) && (pin == 2)) || + ((p1 == 2) && (pin == 1))) + && (p2 == -1)>::type> + constexpr std_out_<1, 2> operator& (const std_out_<pin>&) const + { + return std_out_<1, 2> (); + } + +}; + +struct close_t +{ + constexpr close_t() {} + template<int T, int U> + api::close_out<T,U> operator()(std_out_<T,U>) {return api::close_out<T,U>();} +}; -}
-///This constant is a utility to allow syntax like `std_out > close` for closing I/O streams.
-constexpr boost::process::detail::close_t close;
-///This constant is a utility to redirect streams to the null-device.
-constexpr boost::process::detail::null_t null;
- -/**
-This property allows to set the input stream for the child process.
- -\section stdin_details Details
- -\subsection stdin_file File Input
+} +///This constant is a utility to allow syntax like `std_out > close` for closing I/O streams. +constexpr boost::process::detail::close_t close; +///This constant is a utility to redirect streams to the null-device. +constexpr boost::process::detail::null_t null; + +/** +This property allows to set the input stream for the child process. + +\section stdin_details Details + +\subsection stdin_file File Input -The file I/O simple redirects the stream to a file, for which the possible types are
+The file I/O simple redirects the stream to a file, for which the possible types are - - `boost::filesystem::path`
- - `std::basic_string<char_type>`
- - `const char_type*`
- - `FILE*`
+ - `boost::filesystem::path` + - `std::basic_string<char_type>` + - `const char_type*` + - `FILE*` -with `char_type` being either `char` or `wchar_t`.
+with `char_type` being either `char` or `wchar_t`. -FILE* is explicitly added, so the process can easily redirect the output stream
-of the child to another output stream of the process. That is:
+FILE* is explicitly added, so the process can easily redirect the output stream +of the child to another output stream of the process. That is: -\code{.cpp}
-system("ls", std_in < stdin);
-\endcode
+\code{.cpp} +system("ls", std_in < stdin); +\endcode -\warning If the launching and the child process use the input, this leads to undefined behaviour.
+\warning If the launching and the child process use the input, this leads to undefined behaviour. -A syntax like `system("ls", std_out > std::cerr)` is not possible, due to the C++
-implementation not providing access to the handle.
+A syntax like `system("ls", std_out > std::cerr)` is not possible, due to the C++ +implementation not providing access to the handle. -The valid expressions for this property are
+The valid expressions for this property are -\code{.cpp}
-std_in < file;
-std_in = file;
-\endcode
+\code{.cpp} +std_in < file; +std_in = file; +\endcode -\subsection stdin_pipe Pipe Input
+\subsection stdin_pipe Pipe Input -As explained in the corresponding section, the boost.process library provides a
-@ref boost::process::async_pipe "async_pipe" class which can be
-used to communicate with child processes.
+As explained in the corresponding section, the boost.process library provides a +@ref boost::process::async_pipe "async_pipe" class which can be +used to communicate with child processes. -\note Technically the @ref boost::process::async_pipe "async_pipe"
-works synchronous here, since no asio implementation is used by the library here.
-The async-operation will then however not end if the process is finished, since
-the pipe remains open. You can use the async_close function with on_exit to fix that.
+\note Technically the @ref boost::process::async_pipe "async_pipe" +works synchronous here, since no asio implementation is used by the library here. +The async-operation will then however not end if the process is finished, since +the pipe remains open. You can use the async_close function with on_exit to fix that. -Valid expressions with pipes are these:
+Valid expressions with pipes are these: -\code{.cpp}
-std_in < pipe;
-std_in = pipe;
-\endcode
+\code{.cpp} +std_in < pipe; +std_in = pipe; +\endcode -Where the valid types for `pipe` are the following:
+Where the valid types for `pipe` are the following: - - `basic_pipe`
- - `async_pipe`
- - `basic_opstream`
- - `basic_pstream`
+ - `basic_pipe` + - `async_pipe` + - `basic_opstream` + - `basic_pstream` -Note that the pipe may also be used between several processes, like this:
+Note that the pipe may also be used between several processes, like this: -\code{.cpp}
-pipe p;
-child c1("nm", "a.out", std_out>p);
-child c2("c++filt", std_in<p);
-\endcode
+\code{.cpp} +pipe p; +child c1("nm", "a.out", std_out>p); +child c2("c++filt", std_in<p); +\endcode -\subsection stdin_async_pipe Asynchronous Pipe Input
+\subsection stdin_async_pipe Asynchronous Pipe Input -Asynchronous Pipe I/O classifies communication which has automatically handling
-of the asynchronous operations by the process library. This means, that a pipe will be
-constructed, the async_read/-write will be automatically started, and that the
-end of the child process will also close the pipe.
+Asynchronous Pipe I/O classifies communication which has automatically handling +of the asynchronous operations by the process library. This means, that a pipe will be +constructed, the async_read/-write will be automatically started, and that the +end of the child process will also close the pipe. -Valid types for pipe I/O are the following:
+Valid types for pipe I/O are the following: - - `boost::asio::const_buffer` \xmlonly <footnote><para> Constructed with <code>boost::asio::buffer</code></para></footnote> \endxmlonly
- - `boost::asio::mutable_buffer` \xmlonly <footnote><para> Constructed with <code>boost::asio::buffer</code></para></footnote> \endxmlonly
- - `boost::asio::streambuf`
+ - `boost::asio::const_buffer` \xmlonly <footnote><para> Constructed with <code>boost::asio::buffer</code></para></footnote> \endxmlonly + - `boost::asio::mutable_buffer` \xmlonly <footnote><para> Constructed with <code>boost::asio::buffer</code></para></footnote> \endxmlonly + - `boost::asio::streambuf` -Valid expressions with pipes are these:
+Valid expressions with pipes are these: -\code{.cpp}
-std_in < buffer;
-std_in = buffer;
-std_out > buffer;
-std_out = buffer;
-std_err > buffer;
-std_err = buffer;
-(std_out & std_err) > buffer;
-(std_out & std_err) = buffer;
-\endcode
+\code{.cpp} +std_in < buffer; +std_in = buffer; +std_out > buffer; +std_out = buffer; +std_err > buffer; +std_err = buffer; +(std_out & std_err) > buffer; +(std_out & std_err) = buffer; +\endcode -\note It is also possible to get a future for std_in, by chaining another `std::future<void>` onto it,
-so you can wait for the input to be completed. It looks like this:
-\code{.cpp}
-std::future<void> fut;
-boost::asio::io_service ios;
-std::string data;
-child c("prog", std_in < buffer(data) > fut, ios);
-fut.get();
-\endcode
+\note It is also possible to get a future for std_in, by chaining another `std::future<void>` onto it, +so you can wait for the input to be completed. It looks like this: +\code{.cpp} +std::future<void> fut; +boost::asio::io_context ios; +std::string data; +child c("prog", std_in < buffer(data) > fut, ios); +fut.get(); +\endcode -\note `boost::asio::buffer` is also available in the `boost::process` namespace.
+\note `boost::asio::buffer` is also available in the `boost::process` namespace. -\warning This feature requires `boost/process/async.hpp` to be included and a reference to `boost::asio::io_service` to be passed to the launching function.
+\warning This feature requires `boost/process/async.hpp` to be included and a reference to `boost::asio::io_context` to be passed to the launching function. -\subsection stdin_close Close
+\subsection stdin_close Close -The input stream can be closed, so it cannot be read from. This will lead to an error when attempted.
+The input stream can be closed, so it cannot be read from. This will lead to an error when attempted. -This can be achieved by the following syntax.
+This can be achieved by the following syntax. -\code{.cpp}
-std_in < close;
-std_in = close;
-std_in.close();
-\endcode
+\code{.cpp} +std_in < close; +std_in = close; +std_in.close(); +\endcode -\subsection stdin_null Null
+\subsection stdin_null Null -The input stream can be redirected to read from the null-device, which means that only `EOF` is read.
+The input stream can be redirected to read from the null-device, which means that only `EOF` is read. -The syntax to achieve that has the following variants:
+The syntax to achieve that has the following variants: -\code{.cpp}
-std_in < null;
-std_in = null;
-std_in.null();
-\endcode
+\code{.cpp} +std_in < null; +std_in = null; +std_in.null(); +\endcode -*/
+*/ -constexpr boost::process::detail::std_in_<void> std_in;
+constexpr boost::process::detail::std_in_<void> std_in; -/**
-This property allows to set the output stream for the child process.
+/** +This property allows to set the output stream for the child process. -\note The Semantic is the same as for \xmlonly <globalname alt="boost::process::std_err">std_err</globalname> \endxmlonly
+\note The Semantic is the same as for \xmlonly <globalname alt="boost::process::std_err">std_err</globalname> \endxmlonly -\note `std_err` and `std_out` can be combined into one stream, with the `operator &`, i.e. `std_out & std_err`.
+\note `std_err` and `std_out` can be combined into one stream, with the `operator &`, i.e. `std_out & std_err`. -\section stdout_details Details
+\section stdout_details Details -\subsection stdout_file File Input
+\subsection stdout_file File Input -The file I/O simple redirects the stream to a file, for which the possible types are
+The file I/O simple redirects the stream to a file, for which the possible types are - - `boost::filesystem::path`
- - `std::basic_string<char_type>`
- - `const char_type*`
- - `FILE*`
+ - `boost::filesystem::path` + - `std::basic_string<char_type>` + - `const char_type*` + - `FILE*` -with `char_type` being either `char` or `wchar_t`.
+with `char_type` being either `char` or `wchar_t`. -FILE* is explicitly added, so the process can easily redirect the output stream
-of the child to another output stream of the process. That is:
+FILE* is explicitly added, so the process can easily redirect the output stream +of the child to another output stream of the process. That is: -\code{.cpp}
-system("ls", std_out < stdin);
-\endcode
+\code{.cpp} +system("ls", std_out < stdin); +\endcode -\warning If the launching and the child process use the input, this leads to undefined behaviour.
+\warning If the launching and the child process use the input, this leads to undefined behaviour. -A syntax like `system("ls", std_out > std::cerr)` is not possible, due to the C++
-implementation not providing access to the handle.
+A syntax like `system("ls", std_out > std::cerr)` is not possible, due to the C++ +implementation not providing access to the handle. -The valid expressions for this property are
+The valid expressions for this property are -\code{.cpp}
-std_out < file;
-std_out = file;
-\endcode
+\code{.cpp} +std_out < file; +std_out = file; +\endcode -\subsection stdout_pipe Pipe Output
+\subsection stdout_pipe Pipe Output -As explained in the corresponding section, the boost.process library provides a
-@ref boost::process::async_pipe "async_pipe" class which can be
-used to communicate with child processes.
+As explained in the corresponding section, the boost.process library provides a +@ref boost::process::async_pipe "async_pipe" class which can be +used to communicate with child processes. -\note Technically the @ref boost::process::async_pipe "async_pipe"
-works like a synchronous pipe here, since no asio implementation is used by the library here.
-The asynchronous operation will then however not end if the process is finished, since
-the pipe remains open. You can use the async_close function with on_exit to fix that.
+\note Technically the @ref boost::process::async_pipe "async_pipe" +works like a synchronous pipe here, since no asio implementation is used by the library here. +The asynchronous operation will then however not end if the process is finished, since +the pipe remains open. You can use the async_close function with on_exit to fix that. -Valid expressions with pipes are these:
+Valid expressions with pipes are these: -\code{.cpp}
-std_out > pipe;
-std_out = pipe;
-\endcode
+\code{.cpp} +std_out > pipe; +std_out = pipe; +\endcode -Where the valid types for `pipe` are the following:
+Where the valid types for `pipe` are the following: - - `basic_pipe`
- - `async_pipe`
- - `basic_ipstream`
- - `basic_pstream`
+ - `basic_pipe` + - `async_pipe` + - `basic_ipstream` + - `basic_pstream` -Note that the pipe may also be used between several processes, like this:
+Note that the pipe may also be used between several processes, like this: -\code{.cpp}
-pipe p;
-child c1("nm", "a.out", std_out>p);
-child c2("c++filt", std_in<p);
-\endcode
+\code{.cpp} +pipe p; +child c1("nm", "a.out", std_out>p); +child c2("c++filt", std_in<p); +\endcode -\subsection stdout_async_pipe Asynchronous Pipe Output
+\subsection stdout_async_pipe Asynchronous Pipe Output -Asynchronous Pipe I/O classifies communication which has automatically handling
-of the async operations by the process library. This means, that a pipe will be
-constructed, the async_read/-write will be automatically started, and that the
-end of the child process will also close the pipe.
+Asynchronous Pipe I/O classifies communication which has automatically handling +of the async operations by the process library. This means, that a pipe will be +constructed, the async_read/-write will be automatically started, and that the +end of the child process will also close the pipe. -Valid types for pipe I/O are the following:
+Valid types for pipe I/O are the following: - - `boost::asio::mutable_buffer` \xmlonly <footnote><para> Constructed with <code>boost::asio::buffer</code></para></footnote> \endxmlonly
- - `boost::asio::streambuf`
- - `std::future<std::vector<char>>`
- - `std::future<std::string>`
+ - `boost::asio::mutable_buffer` \xmlonly <footnote><para> Constructed with <code>boost::asio::buffer</code></para></footnote> \endxmlonly + - `boost::asio::streambuf` + - `std::future<std::vector<char>>` + - `std::future<std::string>` -Valid expressions with pipes are these:
+Valid expressions with pipes are these: -\code{.cpp}
-std_out > buffer;
-std_out = buffer;
-std_err > buffer;
-std_err = buffer;
-(std_out & std_err) > buffer;
-(std_out & std_err) = buffer;
-\endcode
+\code{.cpp} +std_out > buffer; +std_out = buffer; +std_err > buffer; +std_err = buffer; +(std_out & std_err) > buffer; +(std_out & std_err) = buffer; +\endcode -\note `boost::asio::buffer` is also available in the `boost::process` namespace.
+\note `boost::asio::buffer` is also available in the `boost::process` namespace. -\warning This feature requires `boost/process/async.hpp` to be included and a reference to `boost::asio::io_service` to be passed to the launching function.
+\warning This feature requires `boost/process/async.hpp` to be included and a reference to `boost::asio::io_context` to be passed to the launching function. -\subsection stdout_close Close
+\subsection stdout_close Close -The out stream can be closed, so it cannot be write from.
-This will lead to an error when attempted.
+The out stream can be closed, so it cannot be write from. +This will lead to an error when attempted. -This can be achieved by the following syntax.
+This can be achieved by the following syntax. -\code{.cpp}
-std_out > close;
-std_out = close;
-std_out.close();
-\endcode
+\code{.cpp} +std_out > close; +std_out = close; +std_out.close(); +\endcode -\subsection stdout_null Null
+\subsection stdout_null Null -The output stream can be redirected to write to the null-device,
-which means that all output is discarded.
+The output stream can be redirected to write to the null-device, +which means that all output is discarded. -The syntax to achieve that has the following variants:
+The syntax to achieve that has the following variants: -\code{.cpp}
-std_out > null;
-std_out = null;
-std_out.null();
-\endcode
+\code{.cpp} +std_out > null; +std_out = null; +std_out.null(); +\endcode -*/
+*/ -constexpr boost::process::detail::std_out_<1> std_out;
-/**This property allows setting the `stderr` stream. The semantic and syntax is the same as for
- * \xmlonly <globalname alt="boost::process::std_out">std_out</globalname> \endxmlonly .
- */
-constexpr boost::process::detail::std_out_<2> std_err;
+constexpr boost::process::detail::std_out_<1> std_out; +/**This property allows setting the `stderr` stream. The semantic and syntax is the same as for + * \xmlonly <globalname alt="boost::process::std_out">std_out</globalname> \endxmlonly . + */ +constexpr boost::process::detail::std_out_<2> std_err; -}}
-#endif /* INCLUDE_BOOST_PROCESS_IO_HPP_ */
+}} +#endif /* INCLUDE_BOOST_PROCESS_IO_HPP_ */ diff --git a/boost/process/locale.hpp b/boost/process/locale.hpp index c8bcf4f9ea..cacecc6ded 100644 --- a/boost/process/locale.hpp +++ b/boost/process/locale.hpp @@ -1,246 +1,246 @@ -// Copyright (c) 2016 Klemens D. Morgenstern
-// Copyright (c) 2008 Beman Dawes
-// 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_LOCALE_HPP_
-#define BOOST_PROCESS_LOCALE_HPP_
- -#include <system_error>
-#include <boost/process/detail/config.hpp>
- -#if defined(BOOST_WINDOWS_API)
-#include <boost/process/detail/windows/locale.hpp>
-# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
-|| defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
-#include <codecvt>
-#endif
- -#include <locale>
- -namespace boost
-{
-namespace process
-{
-namespace detail
-{
- -class codecvt_category_t : public std::error_category
-{
-public:
- codecvt_category_t(){}
- const char* name() const noexcept override {return "codecvt";}
- std::string message(int ev) const override
- {
- std::string str;
- switch (ev)
- {
- case std::codecvt_base::ok:
- str = "ok";
- break;
- case std::codecvt_base::partial:
- str = "partial";
- break;
- case std::codecvt_base::error:
- str = "error";
- break;
- case std::codecvt_base::noconv:
- str = "noconv";
- break;
- default:
- str = "unknown error";
- }
- return str;
- }
-};
- -}
- -///Internally used error cateory for code conversion.
-inline const std::error_category& codecvt_category()
-{
- static const ::boost::process::detail::codecvt_category_t cat;
- return cat;
-}
- -namespace detail
-{
-//copied from boost.filesystem
-inline std::locale default_locale()
-{
-# if defined(BOOST_WINDOWS_API)
- std::locale global_loc = std::locale();
- return std::locale(global_loc, new boost::process::detail::windows::windows_file_codecvt);
-# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
-|| defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__)
- std::locale global_loc = std::locale();
- return std::locale(global_loc, new std::codecvt_utf8<wchar_t>);
-# else // Other POSIX
- // ISO C calls std::locale("") "the locale-specific native environment", and this
- // locale is the default for many POSIX-based operating systems such as Linux.
- return std::locale("");
-# endif
-}
- -inline std::locale& process_locale()
-{
- static std::locale loc(default_locale());
- return loc;
-}
- -}
- -///The internally used type for code conversion.
-typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
- -///Get a reference to the currently used code converter.
-inline const codecvt_type& codecvt()
-{
- return std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(
- detail::process_locale());
-}
- -///Set the locale of the library.
-inline std::locale imbue(const std::locale& loc)
-{
- std::locale temp(detail::process_locale());
- detail::process_locale() = loc;
- return temp;
-}
- - -namespace detail
-{
- -inline std::size_t convert(const char* from,
- const char* from_end,
- wchar_t* to, wchar_t* to_end,
- const ::boost::process::codecvt_type & cvt =
- ::boost::process::codecvt())
-{
- std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
- const char* from_next;
- wchar_t* to_next;
- - auto res = cvt.in(state, from, from_end, from_next,
- to, to_end, to_next);
- - if (res != std::codecvt_base::ok)
- throw process_error(res, ::boost::process::codecvt_category(),
- "boost::process codecvt to wchar_t");
- - - return to_next - to;
- -}
- -inline std::size_t convert(const wchar_t* from,
- const wchar_t* from_end,
- char* to, char* to_end,
- const ::boost::process::codecvt_type & cvt =
- ::boost::process::codecvt())
-{
- std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
- const wchar_t* from_next;
- char* to_next;
- - std::codecvt_base::result res;
- - if ((res=cvt.out(state, from, from_end, from_next,
- to, to_end, to_next)) != std::codecvt_base::ok)
- throw process_error(res, ::boost::process::codecvt_category(),
- "boost::process codecvt to char");
- - return to_next - to;
-}
- -inline std::wstring convert(const std::string & st,
- const ::boost::process::codecvt_type & cvt =
- ::boost::process::codecvt())
-{
- std::wstring out(st.size() + 10, ' '); //just to be sure
- auto sz = convert(st.c_str(), st.c_str() + st.size(),
- &out.front(), &out.back(), cvt);
- - out.resize(sz);
- return out;
-}
- -inline std::string convert(const std::wstring & st,
- const ::boost::process::codecvt_type & cvt =
- ::boost::process::codecvt())
-{
- std::string out(st.size() * 2, ' '); //just to be sure
- auto sz = convert(st.c_str(), st.c_str() + st.size(),
- &out.front(), &out.back(), cvt);
- - out.resize(sz);
- return out;
-}
+// Copyright (c) 2016 Klemens D. Morgenstern +// Copyright (c) 2008 Beman Dawes +// 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_LOCALE_HPP_ +#define BOOST_PROCESS_LOCALE_HPP_ + +#include <system_error> +#include <boost/process/detail/config.hpp> + +#if defined(BOOST_WINDOWS_API) +#include <boost/process/detail/windows/locale.hpp> +# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \ +|| defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) +#include <codecvt> +#endif + +#include <locale> + +namespace boost +{ +namespace process +{ +namespace detail +{ + +class codecvt_category_t : public std::error_category +{ +public: + codecvt_category_t(){} + const char* name() const noexcept override {return "codecvt";} + std::string message(int ev) const override + { + std::string str; + switch (ev) + { + case std::codecvt_base::ok: + str = "ok"; + break; + case std::codecvt_base::partial: + str = "partial"; + break; + case std::codecvt_base::error: + str = "error"; + break; + case std::codecvt_base::noconv: + str = "noconv"; + break; + default: + str = "unknown error"; + } + return str; + } +}; + +} + +///Internally used error cateory for code conversion. +inline const std::error_category& codecvt_category() +{ + static const ::boost::process::detail::codecvt_category_t cat; + return cat; +} + +namespace detail +{ +//copied from boost.filesystem +inline std::locale default_locale() +{ +# if defined(BOOST_WINDOWS_API) + std::locale global_loc = std::locale(); + return std::locale(global_loc, new boost::process::detail::windows::windows_file_codecvt); +# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \ +|| defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) + std::locale global_loc = std::locale(); + return std::locale(global_loc, new std::codecvt_utf8<wchar_t>); +# else // Other POSIX + // ISO C calls std::locale("") "the locale-specific native environment", and this + // locale is the default for many POSIX-based operating systems such as Linux. + return std::locale(""); +# endif +} + +inline std::locale& process_locale() +{ + static std::locale loc(default_locale()); + return loc; +} + +} + +///The internally used type for code conversion. +typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type; + +///Get a reference to the currently used code converter. +inline const codecvt_type& codecvt() +{ + return std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>( + detail::process_locale()); +} + +///Set the locale of the library. +inline std::locale imbue(const std::locale& loc) +{ + std::locale temp(detail::process_locale()); + detail::process_locale() = loc; + return temp; +} + + +namespace detail +{ + +inline std::size_t convert(const char* from, + const char* from_end, + wchar_t* to, wchar_t* to_end, + const ::boost::process::codecvt_type & cvt = + ::boost::process::codecvt()) +{ + std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports + const char* from_next; + wchar_t* to_next; + + auto res = cvt.in(state, from, from_end, from_next, + to, to_end, to_next); + + if (res != std::codecvt_base::ok) + throw process_error(res, ::boost::process::codecvt_category(), + "boost::process codecvt to wchar_t"); + + + return to_next - to; + +} + +inline std::size_t convert(const wchar_t* from, + const wchar_t* from_end, + char* to, char* to_end, + const ::boost::process::codecvt_type & cvt = + ::boost::process::codecvt()) +{ + std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports + const wchar_t* from_next; + char* to_next; + + std::codecvt_base::result res; + + if ((res=cvt.out(state, from, from_end, from_next, + to, to_end, to_next)) != std::codecvt_base::ok) + throw process_error(res, ::boost::process::codecvt_category(), + "boost::process codecvt to char"); + + return to_next - to; +} + +inline std::wstring convert(const std::string & st, + const ::boost::process::codecvt_type & cvt = + ::boost::process::codecvt()) +{ + std::wstring out(st.size() + 10, ' '); //just to be sure + auto sz = convert(st.c_str(), st.c_str() + st.size(), + &out.front(), &out.back(), cvt); + + out.resize(sz); + return out; +} + +inline std::string convert(const std::wstring & st, + const ::boost::process::codecvt_type & cvt = + ::boost::process::codecvt()) +{ + std::string out(st.size() * 2, ' '); //just to be sure + auto sz = convert(st.c_str(), st.c_str() + st.size(), + &out.front(), &out.back(), cvt); + + out.resize(sz); + return out; +} -inline std::vector<wchar_t> convert(const std::vector<char> & st,
- const ::boost::process::codecvt_type & cvt =
- ::boost::process::codecvt())
-{
- std::vector<wchar_t> out(st.size() + 10); //just to be sure
- auto sz = convert(st.data(), st.data() + st.size(),
- &out.front(), &out.back(), cvt);
+inline std::vector<wchar_t> convert(const std::vector<char> & st, + const ::boost::process::codecvt_type & cvt = + ::boost::process::codecvt()) +{ + std::vector<wchar_t> out(st.size() + 10); //just to be sure + auto sz = convert(st.data(), st.data() + st.size(), + &out.front(), &out.back(), cvt); - out.resize(sz);
- return out;
-}
+ out.resize(sz); + return out; +} -inline std::vector<char> convert(const std::vector<wchar_t> & st,
- const ::boost::process::codecvt_type & cvt =
- ::boost::process::codecvt())
-{
- std::vector<char> out(st.size() * 2); //just to be sure
- auto sz = convert(st.data(), st.data() + st.size(),
- &out.front(), &out.back(), cvt);
+inline std::vector<char> convert(const std::vector<wchar_t> & st, + const ::boost::process::codecvt_type & cvt = + ::boost::process::codecvt()) +{ + std::vector<char> out(st.size() * 2); //just to be sure + auto sz = convert(st.data(), st.data() + st.size(), + &out.front(), &out.back(), cvt); - out.resize(sz);
- return out;
-}
+ out.resize(sz); + return out; +} -inline std::wstring convert(const char *begin, const char* end,
- const ::boost::process::codecvt_type & cvt =
- ::boost::process::codecvt())
-{
- auto size = end-begin;
- std::wstring out(size + 10, ' '); //just to be sure
- using namespace std;
- auto sz = convert(begin, end,
- &out.front(), &out.back(), cvt);
- out.resize(sz);
- return out;
-}
+inline std::wstring convert(const char *begin, const char* end, + const ::boost::process::codecvt_type & cvt = + ::boost::process::codecvt()) +{ + auto size = end-begin; + std::wstring out(size + 10, ' '); //just to be sure + using namespace std; + auto sz = convert(begin, end, + &out.front(), &out.back(), cvt); + out.resize(sz); + return out; +} -inline std::string convert(const wchar_t * begin, const wchar_t *end,
- const ::boost::process::codecvt_type & cvt =
- ::boost::process::codecvt())
-{
- auto size = end-begin;
+inline std::string convert(const wchar_t * begin, const wchar_t *end, + const ::boost::process::codecvt_type & cvt = + ::boost::process::codecvt()) +{ + auto size = end-begin; - std::string out(size * 2, ' '); //just to be sure
- auto sz = convert(begin, end ,
- &out.front(), &out.back(), cvt);
+ std::string out(size * 2, ' '); //just to be sure + auto sz = convert(begin, end , + &out.front(), &out.back(), cvt); - out.resize(sz);
- return out;
-}
+ out.resize(sz); + return out; +} -}
+} -}
-}
+} +} -#endif /* BOOST_PROCESS_LOCALE_HPP_ */
+#endif /* BOOST_PROCESS_LOCALE_HPP_ */ diff --git a/boost/process/pipe.hpp b/boost/process/pipe.hpp index 8af776f966..3af45e05c0 100644 --- a/boost/process/pipe.hpp +++ b/boost/process/pipe.hpp @@ -262,7 +262,7 @@ public: typedef typename Traits::off_type off_type ; ///Get access to the underlying stream_buf - basic_pipebuf<CharT, Traits>* rdbuf() const {return _buf;}; + basic_pipebuf<CharT, Traits>* rdbuf() {return &_buf;}; ///Default constructor. basic_ipstream() : std::basic_istream<CharT, Traits>(nullptr) diff --git a/boost/process/search_path.hpp b/boost/process/search_path.hpp index 1c38a61608..ee1f605252 100644 --- a/boost/process/search_path.hpp +++ b/boost/process/search_path.hpp @@ -39,7 +39,7 @@ namespace boost { namespace process { * * \param filename The base of the filename to find * - * \param path the set of paths so search, defaults to "PATH" environment variable. + * \param path the set of paths to search, defaults to the "PATH" environment variable. * * \returns the absolute path to the executable filename or an * empty string if filename isn't found diff --git a/boost/process/spawn.hpp b/boost/process/spawn.hpp index fb1e3594b1..70ada3ed1b 100644 --- a/boost/process/spawn.hpp +++ b/boost/process/spawn.hpp @@ -42,7 +42,7 @@ but will also cause the system to be unable to wait for the child to exit. \note This will set `SIGCHLD` to `SIGIGN` on posix. \warning This function does not allow asynchronous operations, since it cannot wait for the end of the process. -It will fail to compile if a reference to `boost::asio::io_service` is passed. +It will fail to compile if a reference to `boost::asio::io_context` is passed. */ template<typename ...Args> diff --git a/boost/process/start_dir.hpp b/boost/process/start_dir.hpp index 50a246f4b8..9c3ac64e9f 100644 --- a/boost/process/start_dir.hpp +++ b/boost/process/start_dir.hpp @@ -1,110 +1,110 @@ -// 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
-//
-// 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_START_IN_DIR_HPP
-#define BOOST_PROCESS_START_IN_DIR_HPP
- -#include <boost/process/detail/config.hpp>
-#include <boost/process/detail/handler.hpp>
-#include <boost/process/locale.hpp>
- -#if defined (BOOST_POSIX_API)
-#include <boost/process/detail/posix/start_dir.hpp>
-#elif defined (BOOST_WINDOWS_API)
-#include <boost/process/detail/windows/start_dir.hpp>
-#endif
- -#include <boost/process/detail/config.hpp>
-#include <string>
-#include <boost/filesystem/path.hpp>
- -/** \file boost/process/start_dir.hpp
- *
-Header which provides the start_dir property, which allows to set the directory
-the process shall be started in.
-\xmlonly
-<programlisting>
-namespace boost {
- namespace process {
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::start_dir">start_dir</globalname>;
- }
-}
-</programlisting>
-\endxmlonly
- - */
- -namespace boost { namespace process { namespace detail {
- -struct start_dir_
-{
- constexpr start_dir_() {};
- - template<typename Char>
- api::start_dir_init<Char> operator()(const std::basic_string<Char> & st) const {return {st}; }
- template<typename Char>
- api::start_dir_init<Char> operator()(std::basic_string<Char> && s) const {return {std::move(s)}; }
- template<typename Char>
- api::start_dir_init<Char> operator()(const Char* s) const {return {s}; }
- api::start_dir_init<typename boost::filesystem::path::value_type>
- operator()(const boost::filesystem::path & st) const {return {st.native()}; }
- - template<typename Char>
- api::start_dir_init<Char> operator= (const std::basic_string<Char> & st) const {return {st}; }
- template<typename Char>
- api::start_dir_init<Char> operator= (std::basic_string<Char> && s) const {return {std::move(s)}; }
- template<typename Char>
- api::start_dir_init<Char> operator= (const Char* s) const {return {s}; }
- api::start_dir_init<typename boost::filesystem::path::value_type>
- operator= (const boost::filesystem::path & st) const {return {st.native()}; }
- -};
- -template<> struct is_wchar_t<api::start_dir_init<wchar_t>> : std::true_type {};
- -template<>
-struct char_converter<char, api::start_dir_init<wchar_t>>
-{
- static api::start_dir_init<char> conv(const api::start_dir_init<wchar_t> & in)
- {
- return api::start_dir_init<char>{::boost::process::detail::convert(in.str())};
- }
-};
- -template<>
-struct char_converter<wchar_t, api::start_dir_init<char>>
-{
- static api::start_dir_init<wchar_t> conv(const api::start_dir_init<char> & in)
- {
- return api::start_dir_init<wchar_t>{::boost::process::detail::convert(in.str())};
- }
-};
- -}
- -/**
- -To set the start dir, the `start_dir` property is provided.
- -The valid operations are the following:
- -\code{.cpp}
-start_dir=path
-start_dir(path)
-\endcode
- -It can be used with `std::string`, `std::wstring` and `boost::filesystem::path`.
- - - */
-constexpr ::boost::process::detail::start_dir_ start_dir;
- -}}
- -#endif
+// 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 +// +// 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_START_IN_DIR_HPP +#define BOOST_PROCESS_START_IN_DIR_HPP + +#include <boost/process/detail/config.hpp> +#include <boost/process/detail/handler.hpp> +#include <boost/process/locale.hpp> + +#if defined (BOOST_POSIX_API) +#include <boost/process/detail/posix/start_dir.hpp> +#elif defined (BOOST_WINDOWS_API) +#include <boost/process/detail/windows/start_dir.hpp> +#endif + +#include <boost/process/detail/config.hpp> +#include <string> +#include <boost/filesystem/path.hpp> + +/** \file boost/process/start_dir.hpp + * +Header which provides the start_dir property, which allows to set the directory +the process shall be started in. +\xmlonly +<programlisting> +namespace boost { + namespace process { + <emphasis>unspecified</emphasis> <globalname alt="boost::process::start_dir">start_dir</globalname>; + } +} +</programlisting> +\endxmlonly + + */ + +namespace boost { namespace process { namespace detail { + +struct start_dir_ +{ + constexpr start_dir_() {}; + + template<typename Char> + api::start_dir_init<Char> operator()(const std::basic_string<Char> & st) const {return {st}; } + template<typename Char> + api::start_dir_init<Char> operator()(std::basic_string<Char> && s) const {return {std::move(s)}; } + template<typename Char> + api::start_dir_init<Char> operator()(const Char* s) const {return {s}; } + api::start_dir_init<typename boost::filesystem::path::value_type> + operator()(const boost::filesystem::path & st) const {return {st.native()}; } + + template<typename Char> + api::start_dir_init<Char> operator= (const std::basic_string<Char> & st) const {return {st}; } + template<typename Char> + api::start_dir_init<Char> operator= (std::basic_string<Char> && s) const {return {std::move(s)}; } + template<typename Char> + api::start_dir_init<Char> operator= (const Char* s) const {return {s}; } + api::start_dir_init<typename boost::filesystem::path::value_type> + operator= (const boost::filesystem::path & st) const {return {st.native()}; } + +}; + +template<> struct is_wchar_t<api::start_dir_init<wchar_t>> : std::true_type {}; + +template<> +struct char_converter<char, api::start_dir_init<wchar_t>> +{ + static api::start_dir_init<char> conv(const api::start_dir_init<wchar_t> & in) + { + return api::start_dir_init<char>{::boost::process::detail::convert(in.str())}; + } +}; + +template<> +struct char_converter<wchar_t, api::start_dir_init<char>> +{ + static api::start_dir_init<wchar_t> conv(const api::start_dir_init<char> & in) + { + return api::start_dir_init<wchar_t>{::boost::process::detail::convert(in.str())}; + } +}; + +} + +/** + +To set the start dir, the `start_dir` property is provided. + +The valid operations are the following: + +\code{.cpp} +start_dir=path +start_dir(path) +\endcode + +It can be used with `std::string`, `std::wstring` and `boost::filesystem::path`. + + + */ +constexpr ::boost::process::detail::start_dir_ start_dir; + +}} + +#endif diff --git a/boost/process/system.hpp b/boost/process/system.hpp index bdcac88713..5ed7633233 100644 --- a/boost/process/system.hpp +++ b/boost/process/system.hpp @@ -48,10 +48,10 @@ struct system_impl_success_check : handler template<typename IoService, typename ...Args> inline int system_impl( std::true_type, /*needs ios*/ - std::true_type, /*has io_service*/ + std::true_type, /*has io_context*/ Args && ...args) { - IoService & ios = ::boost::process::detail::get_io_service_var(args...); + IoService & ios = ::boost::process::detail::get_io_context_var(args...); system_impl_success_check check; @@ -76,7 +76,7 @@ inline int system_impl( template<typename IoService, typename ...Args> inline int system_impl( std::true_type, /*needs ios */ - std::false_type, /*has io_service*/ + std::false_type, /*has io_context*/ Args && ...args) { IoService ios; @@ -92,7 +92,7 @@ inline int system_impl( template<typename IoService, typename ...Args> inline int system_impl( std::false_type, /*needs ios*/ - std::true_type, /*has io_service*/ + std::true_type, /*has io_context*/ Args && ...args) { child c(std::forward<Args>(args)...); @@ -105,7 +105,7 @@ inline int system_impl( template<typename IoService, typename ...Args> inline int system_impl( std::false_type, /*has async */ - std::false_type, /*has io_service*/ + std::false_type, /*has io_context*/ Args && ...args) { child c(std::forward<Args>(args)... @@ -131,19 +131,19 @@ int ret = system("ls"); \attention Using this function with synchronous pipes leads to many potential deadlocks. -When using this function with an asynchronous properties and NOT passing an io_service object, -the system function will create one and run it. When the io_service is passed to the function, -the system function will check if it is active, and call the io_service::run function if not. +When using this function with an asynchronous properties and NOT passing an io_context object, +the system function will create one and run it. When the io_context is passed to the function, +the system function will check if it is active, and call the io_context::run function if not. */ template<typename ...Args> inline int system(Args && ...args) { - typedef typename ::boost::process::detail::needs_io_service<Args...>::type + typedef typename ::boost::process::detail::needs_io_context<Args...>::type need_ios; - typedef typename ::boost::process::detail::has_io_service<Args...>::type + typedef typename ::boost::process::detail::has_io_context<Args...>::type has_ios; - return ::boost::process::detail::system_impl<boost::asio::io_service>( + return ::boost::process::detail::system_impl<boost::asio::io_context>( need_ios(), has_ios(), std::forward<Args>(args)...); } diff --git a/boost/process/windows.hpp b/boost/process/windows.hpp index 3bc97a26aa..6e740f958f 100644 --- a/boost/process/windows.hpp +++ b/boost/process/windows.hpp @@ -1,58 +1,58 @@ -// 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_WINDOWS_HPP_
-#define BOOST_PROCESS_WINDOWS_HPP_
- -#include <boost/process/detail/windows/show_window.hpp>
- -/** \file boost/process/windows.hpp
- *
- * Header which provides the windows extensions.
- -\xmlonly
-<programlisting>
-namespace boost {
- namespace process {
- namespace windows {
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::hide">hide</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::maximized">maximized</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::minimized">minimized</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::minimized_not_active">minimized_not_active</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::not_active">not_active</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::show">show</globalname>;
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::show_normal">show_normal</globalname>;
- }
- }
-}
-</programlisting>
- * \endxmlonly
- * \warning Only available on windows.
- * See the parameter documentation of [ShowWindow](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx) for more details.
- */
- -namespace boost { namespace process {
- -///Namespace containing the windows exensions.
-namespace windows {
- -///Hides the window and activates another window.
-constexpr ::boost::process::detail::windows::show_window<::boost::detail::winapi::SW_HIDE_ > hide;
-///Activates the window and displays it as a maximized window.
-constexpr ::boost::process::detail::windows::show_window<::boost::detail::winapi::SW_SHOWMAXIMIZED_ > maximized;
-///Activates the window and displays it as a minimized window.
-constexpr ::boost::process::detail::windows::show_window<::boost::detail::winapi::SW_SHOWMINIMIZED_ > minimized;
-///Displays the window as a minimized window. This value is similar to `minimized`, except the window is not activated.
-constexpr ::boost::process::detail::windows::show_window<::boost::detail::winapi::SW_SHOWMINNOACTIVE_> minimized_not_active;
-///Displays a window in its most recent size and position. This value is similar to show_normal`, except that the window is not activated.
-constexpr ::boost::process::detail::windows::show_window<::boost::detail::winapi::SW_SHOWNOACTIVATE_ > not_active;
-///Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
-constexpr ::boost::process::detail::windows::show_window<::boost::detail::winapi::SW_SHOWNORMAL_ > show;
-///Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
-constexpr ::boost::process::detail::windows::show_window<::boost::detail::winapi::SW_SHOWNORMAL_ > show_normal;
- - -}}}
- -#endif /* BOOST_PROCESS_WINDOWS_HPP_ */
+// 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_WINDOWS_HPP_ +#define BOOST_PROCESS_WINDOWS_HPP_ + +#include <boost/process/detail/windows/show_window.hpp> + +/** \file boost/process/windows.hpp + * + * Header which provides the windows extensions. + +\xmlonly +<programlisting> +namespace boost { + namespace process { + namespace windows { + <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::hide">hide</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::maximized">maximized</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::minimized">minimized</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::minimized_not_active">minimized_not_active</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::not_active">not_active</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::show">show</globalname>; + <emphasis>unspecified</emphasis> <globalname alt="boost::process::windows::show_normal">show_normal</globalname>; + } + } +} +</programlisting> + * \endxmlonly + * \warning Only available on windows. + * See the parameter documentation of [ShowWindow](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx) for more details. + */ + +namespace boost { namespace process { + +///Namespace containing the windows exensions. +namespace windows { + +///Hides the window and activates another window. +constexpr ::boost::process::detail::windows::show_window<::boost::winapi::SW_HIDE_ > hide; +///Activates the window and displays it as a maximized window. +constexpr ::boost::process::detail::windows::show_window<::boost::winapi::SW_SHOWMAXIMIZED_ > maximized; +///Activates the window and displays it as a minimized window. +constexpr ::boost::process::detail::windows::show_window<::boost::winapi::SW_SHOWMINIMIZED_ > minimized; +///Displays the window as a minimized window. This value is similar to `minimized`, except the window is not activated. +constexpr ::boost::process::detail::windows::show_window<::boost::winapi::SW_SHOWMINNOACTIVE_> minimized_not_active; +///Displays a window in its most recent size and position. This value is similar to show_normal`, except that the window is not activated. +constexpr ::boost::process::detail::windows::show_window<::boost::winapi::SW_SHOWNOACTIVATE_ > not_active; +///Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time. +constexpr ::boost::process::detail::windows::show_window<::boost::winapi::SW_SHOWNORMAL_ > show; +///Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time. +constexpr ::boost::process::detail::windows::show_window<::boost::winapi::SW_SHOWNORMAL_ > show_normal; + + +}}} + +#endif /* BOOST_PROCESS_WINDOWS_HPP_ */ |