diff --git a/include/boost/process/detail/handler.hpp b/include/boost/process/detail/handler.hpp index 8afe1f19..2a351857 100644 --- a/include/boost/process/detail/handler.hpp +++ b/include/boost/process/detail/handler.hpp @@ -66,9 +66,6 @@ private: } -constexpr boost::process::detail::make_handler_t on_setup; -constexpr boost::process::detail::make_handler_t on_error; -constexpr boost::process::detail::make_handler_t on_success; }} diff --git a/include/boost/process/detail/traits/cmd_or_exe.hpp b/include/boost/process/detail/traits/cmd_or_exe.hpp index 00217480..cf230f70 100644 --- a/include/boost/process/detail/traits/cmd_or_exe.hpp +++ b/include/boost/process/detail/traits/cmd_or_exe.hpp @@ -48,6 +48,9 @@ template<> struct initializer_tag> { typedef cmd_or_exe_t template<> struct initializer_tag> { typedef cmd_or_exe_tag type;}; template<> struct initializer_tag> { typedef cmd_or_exe_tag type;}; +template<> struct initializer_tag> { typedef cmd_or_exe_tag type;}; +template<> struct initializer_tag> { typedef cmd_or_exe_tag type;}; + template<> struct initializer_tag { typedef cmd_or_exe_tag type; diff --git a/include/boost/process/detail/windows/env_init.hpp b/include/boost/process/detail/windows/env_init.hpp index 8b15f2a6..3c941004 100644 --- a/include/boost/process/detail/windows/env_init.hpp +++ b/include/boost/process/detail/windows/env_init.hpp @@ -25,8 +25,8 @@ struct env_init : public ::boost::process::detail::handler_base env_init(boost::process::basic_environment && env) : env(std::move(env)) {}; env_init(const boost::process::basic_environment & env) : env(env) {}; - ::boost::detail::winapi::DWORD_ creation_flag(char) {return 0u;} - ::boost::detail::winapi::DWORD_ creation_flag(wchar_t) + constexpr static ::boost::detail::winapi::DWORD_ creation_flag(char) {return 0u;} + constexpr static ::boost::detail::winapi::DWORD_ creation_flag(wchar_t) { return ::boost::detail::winapi::CREATE_UNICODE_ENVIRONMENT_; } @@ -42,7 +42,7 @@ struct env_init : public ::boost::process::detail::handler_base } exec.env = e; - exec.creation_flags |= creation_flags(Char()); + exec.creation_flags |= creation_flag(Char()); } }; diff --git a/include/boost/process/detail/windows/executor.hpp b/include/boost/process/detail/windows/executor.hpp index f2de7c2a..286baa44 100644 --- a/include/boost/process/detail/windows/executor.hpp +++ b/include/boost/process/detail/windows/executor.hpp @@ -80,6 +80,12 @@ struct startup_info_impl nullptr }; startup_info_t & startup_info = startup_info_ex.StartupInfo; + + void set_startup_info_ex() + { + startup_info.cb = sizeof(startup_info_ex_t); + creation_flags = ::boost::detail::winapi::EXTENDED_STARTUPINFO_PRESENT_; + } }; diff --git a/include/boost/process/extend.hpp b/include/boost/process/extend.hpp new file mode 100644 index 00000000..4ca28413 --- /dev/null +++ b/include/boost/process/extend.hpp @@ -0,0 +1,70 @@ +// 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_EXTENSIONS_HPP_ +#define BOOST_PROCESS_EXTENSIONS_HPP_ + +#include + +#if defined(BOOST_WINDOWS_API) +#include +#include +#else +#include +#include +#endif + +namespace boost { +namespace process { +namespace asio { +class io_service; +} +namespace detail { +template +inline asio::io_service& get_io_service(const Tuple & tup); +} + + +///Namespace for extensions @attention This is experimental. +namespace extend { + +#if defined(BOOST_WINDOWS_API) + +template +using windows_executor = ::boost::process::detail::windows::executor; +template +struct posix_executor; + +#else + +template +using posix_executor = ::boost::process::detail::posix::executor; +template +struct windows_executor; + +#endif + +using ::boost::process::detail::handler; +using ::boost::process::detail::api::require_io_service; +using ::boost::process::detail::api::async_handler; + +constexpr boost::process::detail::make_handler_t on_setup; +constexpr boost::process::detail::make_handler_t on_error; +constexpr boost::process::detail::make_handler_t on_success; + +#if defined(BOOST_POSIX_API) +///This handler is invoked if the fork fails. +constexpr static ::boost::process::detail::make_handler_t<::boost::process::detail::posix::on_fork_error_ > on_fork_error; +///This handler is invoked if the fork succeeded. +constexpr static ::boost::process::detail::make_handler_t<::boost::process::detail::posix::on_exec_setup_ > on_exec_setup; +///This handler is invoked if the exec call errored. +constexpr static ::boost::process::detail::make_handler_t<::boost::process::detail::posix::on_exec_error_ > on_exec_error; +#endif + +} +} +} + +#endif diff --git a/include/boost/process/posix.hpp b/include/boost/process/posix.hpp index e43679c7..0c8f70a3 100644 --- a/include/boost/process/posix.hpp +++ b/include/boost/process/posix.hpp @@ -50,12 +50,7 @@ namespace posix { * */ constexpr static ::boost::process::detail::posix::fd_ fd; -///This handler is invoked if the fork fails. -constexpr static ::boost::process::detail::make_handler_t<::boost::process::detail::posix::on_fork_error_ > on_fork_error; -///This handler is invoked if the fork succeeded. -constexpr static ::boost::process::detail::make_handler_t<::boost::process::detail::posix::on_exec_setup_ > on_exec_setup; -///This handler is invoked if the exec call errored. -constexpr static ::boost::process::detail::make_handler_t<::boost::process::detail::posix::on_exec_error_ > on_exec_error; + /** This property lets you modify the handling of `SIGCHLD` for this call. It will be reset afterwards. It can be set to default, by the expression `sig.dfl()`, set to ignore with `sig.ign()` or diff --git a/test/Jamfile.jam b/test/Jamfile.jam index a5302117..bc3c6715 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -14,6 +14,7 @@ import os ; if [ os.name ] = NT { lib ws2_32 ; + lib shell32 ; } project : requirements @@ -25,7 +26,7 @@ project : requirements NT,gcc:ws2_32 ; -searched-lib shell32 ; + import testing ; @@ -70,13 +71,11 @@ test-suite execution : [ run extensions.cpp system filesystem : : sparring_partner ] [ run env.cpp program_options system filesystem : : sparring_partner ] [ run group.cpp system thread filesystem : : sub_launch ] - [ run posix_specific.cpp system filesystem : : sparring_partner : no linux:yes ] [ run run_exe.cpp filesystem : : sparring_partner ] [ run run_exe_path.cpp filesystem : : sparring_partner ] [ run search_path.cpp filesystem system : : : windows:shell32 ] [ run shell.cpp filesystem system : : sparring_partner ] [ run shell_path.cpp filesystem system ] - [ run show_window.cpp filesystem system : : sparring_partner : no windows:yes ] [ run system_test1.cpp filesystem system : : sparring_partner ] [ run system_test2.cpp filesystem system : : sparring_partner ] [ run spawn.cpp filesystem system : : sparring_partner ] @@ -86,4 +85,6 @@ test-suite execution : # [ run vfork.cpp system filesystem : : sparring_partner : no linux:yes ] [ run wait.cpp system filesystem : : sparring_partner ] [ compile-fail spawn_fail.cpp ] + [ run posix_specific.cpp system filesystem : : sparring_partner : no linux:yes ] + [ run windows_specific.cpp filesystem system : : sparring_partner : no windows:yes ] : bare ; diff --git a/test/error.cpp b/test/error.cpp index 4ccda79a..ac7662a2 100644 --- a/test/error.cpp +++ b/test/error.cpp @@ -13,10 +13,12 @@ #include #include +#include #include #include + namespace bp = boost::process; struct err_set @@ -46,7 +48,7 @@ BOOST_AUTO_TEST_CASE(setup_error) { es.ec.assign(42, std::system_category()); std::error_code ec; - bp::child c(master_test_suite().argv[1], ec, bp::on_setup(es)); + bp::child c(master_test_suite().argv[1], ec, bp::extend::on_setup(es)); BOOST_CHECK(!c.running()); BOOST_CHECK(ec); @@ -57,7 +59,7 @@ BOOST_AUTO_TEST_CASE(setup_error) { es.ec.assign(24, std::system_category()); es.msg = "MyMessage"; - bp::child c(master_test_suite().argv[1], bp::on_setup(es)); + bp::child c(master_test_suite().argv[1], bp::extend::on_setup(es)); } catch( bp::process_error & se) @@ -78,7 +80,7 @@ BOOST_AUTO_TEST_CASE(success_error) { es.ec.assign(22, std::system_category()); std::error_code ec; - bp::child c(master_test_suite().argv[1], ec, bp::on_success(es)); + bp::child c(master_test_suite().argv[1], ec, bp::extend::on_success(es)); BOOST_CHECK(!c.running()); @@ -91,7 +93,7 @@ BOOST_AUTO_TEST_CASE(success_error) { es.ec.assign(23, std::system_category()); es.msg = "MyMessage"; - bp::child c(master_test_suite().argv[1], bp::on_success(es)); + bp::child c(master_test_suite().argv[1], bp::extend::on_success(es)); } diff --git a/test/extensions.cpp b/test/extensions.cpp index 95f4c9aa..1bb17742 100644 --- a/test/extensions.cpp +++ b/test/extensions.cpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace bp = boost::process; @@ -54,8 +55,8 @@ BOOST_AUTO_TEST_CASE(extensions) bp::child c( "Wrong-Command", "test", - bp::on_setup=re, - bp::on_error=se, + bp::extend::on_setup=re, + bp::extend::on_error=se, bp::ignore_error ); BOOST_CHECK(!se.ec); diff --git a/test/show_window.cpp b/test/show_window.cpp deleted file mode 100644 index fb682856..00000000 --- a/test/show_window.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// 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) - -#define BOOST_TEST_MAIN -#define BOOST_TEST_IGNORE_SIGCHLD -#include -#include -#include -#include - -#include - -namespace bp = boost::process; - -BOOST_AUTO_TEST_CASE(show_window) -{ - using boost::unit_test::framework::master_test_suite; - - bp::ipstream is; - - std::error_code ec; - bp::child c( - master_test_suite().argv[1], - "test", "--windows-print-showwindow", - bp::windows::show_normal, - bp::std_out>is, - ec - ); - BOOST_REQUIRE(!ec); - - int i; - is >> i; - BOOST_CHECK_EQUAL(i, SW_SHOWNORMAL); -} diff --git a/test/windows_specific.cpp b/test/windows_specific.cpp new file mode 100644 index 00000000..c31b6871 --- /dev/null +++ b/test/windows_specific.cpp @@ -0,0 +1,92 @@ +// 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) + +#define BOOST_TEST_MAIN +#define BOOST_TEST_IGNORE_SIGCHLD +#include +#include +#include +#include +#include + +#include + +namespace bp = boost::process; + +BOOST_AUTO_TEST_CASE(show_window) +{ + using boost::unit_test::framework::master_test_suite; + + bp::ipstream is; + + std::error_code ec; + bp::child c( + master_test_suite().argv[1], + "test", "--windows-print-showwindow", + bp::windows::show_normal, + bp::std_out>is, + ec + ); + BOOST_REQUIRE(!ec); + + int i; + is >> i; + BOOST_CHECK_EQUAL(i, SW_SHOWNORMAL); +} + + +#if ( BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6 ) + +struct set_startup_info +{ + int &cnt; + template + void operator()(T &e) const + { + cnt++; + BOOST_CHECK_EQUAL(e.startup_info.cb, sizeof(::boost::detail::winapi::STARTUPINFOA_)); + e.set_startup_info_ex(); + } + +}; + +struct check_startup_info +{ + int &cnt; + template + void operator()(T &e) const + { + cnt++; + BOOST_CHECK(e.creation_flags & ::boost::detail::winapi::EXTENDED_STARTUPINFO_PRESENT_); + BOOST_CHECK_EQUAL(e.startup_info.cb, sizeof(::boost::detail::winapi::STARTUPINFOEXA_)); + } + +}; + +BOOST_AUTO_TEST_CASE(startup_info_ex) +{ + using boost::unit_test::framework::master_test_suite; + + bp::ipstream is; + + int cnt = 0; + + std::error_code ec; + bp::child c( + master_test_suite().argv[1], + bp::extend::on_setup(set_startup_info{cnt}), + bp::extend::on_success(check_startup_info{cnt}), + bp::std_out>is, + ec + ); + BOOST_REQUIRE(!ec); + BOOST_CHECK_EQUAL(cnt, 2); +} + +#endif