summaryrefslogtreecommitdiff
path: root/boost/process/detail
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:11:01 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2019-12-05 15:11:01 +0900
commit3fdc3e5ee96dca5b11d1694975a65200787eab86 (patch)
tree5c1733853892b8397d67706fa453a9bd978d2102 /boost/process/detail
parent88e602c57797660ebe0f9e15dbd64c1ff16dead3 (diff)
downloadboost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.gz
boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.tar.bz2
boost-3fdc3e5ee96dca5b11d1694975a65200787eab86.zip
Imported Upstream version 1.66.0upstream/1.66.0
Diffstat (limited to 'boost/process/detail')
-rw-r--r--boost/process/detail/async_handler.hpp36
-rw-r--r--boost/process/detail/basic_cmd.hpp584
-rw-r--r--boost/process/detail/child_decl.hpp6
-rw-r--r--boost/process/detail/config.hpp11
-rw-r--r--boost/process/detail/handler.hpp108
-rw-r--r--boost/process/detail/posix/asio_fwd.hpp19
-rw-r--r--boost/process/detail/posix/async_handler.hpp54
-rw-r--r--boost/process/detail/posix/async_in.hpp190
-rw-r--r--boost/process/detail/posix/async_out.hpp338
-rw-r--r--boost/process/detail/posix/async_pipe.hpp83
-rw-r--r--boost/process/detail/posix/basic_pipe.hpp8
-rw-r--r--boost/process/detail/posix/child_handle.hpp2
-rw-r--r--boost/process/detail/posix/environment.hpp644
-rw-r--r--boost/process/detail/posix/executor.hpp5
-rw-r--r--boost/process/detail/posix/file_descriptor.hpp152
-rw-r--r--boost/process/detail/posix/file_in.hpp80
-rw-r--r--boost/process/detail/posix/file_out.hpp102
-rw-r--r--boost/process/detail/posix/group_ref.hpp2
-rw-r--r--boost/process/detail/posix/handler.hpp112
-rw-r--r--boost/process/detail/posix/io_context_ref.hpp (renamed from boost/process/detail/posix/io_service_ref.hpp)269
-rw-r--r--boost/process/detail/posix/null_in.hpp56
-rw-r--r--boost/process/detail/posix/null_out.hpp116
-rw-r--r--boost/process/detail/posix/on_exit.hpp52
-rw-r--r--boost/process/detail/posix/pipe_in.hpp180
-rw-r--r--boost/process/detail/posix/pipe_out.hpp232
-rw-r--r--boost/process/detail/posix/search_path.hpp1
-rw-r--r--boost/process/detail/posix/sigchld_service.hpp113
-rw-r--r--boost/process/detail/posix/wait_for_exit.hpp105
-rw-r--r--boost/process/detail/posix/wait_group.hpp37
-rw-r--r--boost/process/detail/traits.hpp26
-rw-r--r--boost/process/detail/traits/async.hpp36
-rw-r--r--boost/process/detail/traits/cmd_or_exe.hpp114
-rw-r--r--boost/process/detail/traits/decl.hpp98
-rw-r--r--boost/process/detail/traits/env.hpp60
-rw-r--r--boost/process/detail/traits/error.hpp30
-rw-r--r--boost/process/detail/windows/asio_fwd.hpp10
-rw-r--r--boost/process/detail/windows/async_handler.hpp54
-rw-r--r--boost/process/detail/windows/async_in.hpp210
-rw-r--r--boost/process/detail/windows/async_out.hpp355
-rw-r--r--boost/process/detail/windows/async_pipe.hpp233
-rw-r--r--boost/process/detail/windows/basic_cmd.hpp342
-rw-r--r--boost/process/detail/windows/basic_pipe.hpp134
-rw-r--r--boost/process/detail/windows/child_handle.hpp44
-rw-r--r--boost/process/detail/windows/close_in.hpp8
-rw-r--r--boost/process/detail/windows/close_out.hpp18
-rw-r--r--boost/process/detail/windows/cmd.hpp72
-rw-r--r--boost/process/detail/windows/compare_handles.hpp18
-rw-r--r--boost/process/detail/windows/env_init.hpp12
-rw-r--r--boost/process/detail/windows/environment.hpp650
-rw-r--r--boost/process/detail/windows/executor.hpp40
-rw-r--r--boost/process/detail/windows/file_descriptor.hpp208
-rw-r--r--boost/process/detail/windows/file_in.hpp88
-rw-r--r--boost/process/detail/windows/file_out.hpp126
-rw-r--r--boost/process/detail/windows/group_handle.hpp42
-rw-r--r--boost/process/detail/windows/group_ref.hpp8
-rw-r--r--boost/process/detail/windows/handler.hpp24
-rw-r--r--boost/process/detail/windows/io_context_ref.hpp (renamed from boost/process/detail/windows/io_service_ref.hpp)320
-rw-r--r--boost/process/detail/windows/is_running.hpp12
-rw-r--r--boost/process/detail/windows/job_workaround.hpp82
-rw-r--r--boost/process/detail/windows/locale.hpp206
-rw-r--r--boost/process/detail/windows/null_in.hpp82
-rw-r--r--boost/process/detail/windows/null_out.hpp150
-rw-r--r--boost/process/detail/windows/on_exit.hpp79
-rw-r--r--boost/process/detail/windows/pipe_in.hpp178
-rw-r--r--boost/process/detail/windows/pipe_out.hpp244
-rw-r--r--boost/process/detail/windows/search_path.hpp45
-rw-r--r--boost/process/detail/windows/shell_path.hpp14
-rw-r--r--boost/process/detail/windows/show_window.hpp54
-rw-r--r--boost/process/detail/windows/start_dir.hpp72
-rw-r--r--boost/process/detail/windows/terminate.hpp16
-rw-r--r--boost/process/detail/windows/wait_for_exit.hpp114
-rw-r--r--boost/process/detail/windows/wait_group.hpp44
72 files changed, 4309 insertions, 4160 deletions
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;