diff --git a/README.md b/README.md index f49bc030..0ab69544 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,4 @@ Distributed under the [Boost Software License, Version 1.0](http://www.boost.org ### Dependency -This library requires boost 1.62. Since this is not released yet you can clone the winapi module from [here](https://github.com/boostorg/winapi) to get it to work. You will need to overwrite the current code in boost/libs/winapi. +This library requires boost 1.63. Since this is not released yet you can clone the winapi module from [here](https://github.com/boostorg/winapi) to get it to work. You will need to overwrite the current code in boost/libs/winapi. diff --git a/doc/tutorial.qbk b/doc/tutorial.qbk index 285f718e..ea115af3 100644 --- a/doc/tutorial.qbk +++ b/doc/tutorial.qbk @@ -51,7 +51,7 @@ namespace bp = boost::process; //we will assume this for all further examples bp::system("g++ main.cpp"); ``` -The first thing we can do, is to seperate the command and the executable into +The first thing we can do, is to separate the command and the executable into two parts, so it is more readable and can be built by a function. ``` diff --git a/include/boost/process/async.hpp b/include/boost/process/async.hpp index 40d28210..b6967819 100644 --- a/include/boost/process/async.hpp +++ b/include/boost/process/async.hpp @@ -71,7 +71,7 @@ struct async_builder { boost::asio::io_service * ios; - void operator()(boost::asio::io_service & ios) {this->ios = &ios;}; + void operator()(boost::asio::io_service & ios_) {this->ios = &ios_;}; typedef api::io_service_ref result_type; api::io_service_ref get_initializer() {return api::io_service_ref (*ios);}; diff --git a/include/boost/process/async_pipe.hpp b/include/boost/process/async_pipe.hpp index c5f56665..68757741 100644 --- a/include/boost/process/async_pipe.hpp +++ b/include/boost/process/async_pipe.hpp @@ -184,27 +184,27 @@ public: WriteHandler && handler); ///Get the asio handle of the pipe sink. - const handle_type & sink () const; + const handle_type & sink () const &; ///Get the asio handle of the pipe source. - const handle_type & source() const; + const handle_type & source() const &; + + ///Get the asio handle of the pipe sink. + handle_type && sink () &&; + ///Get the asio handle of the pipe source. + handle_type && source() &&; + + /// Move the source out of this class and change the io_service. Qualified as rvalue. \attention Will always move. + handle_type source(::boost::asio::io_service& ios) &&; + /// Move the sink out of this class and change the io_service. Qualified as rvalue. \attention Will always move + handle_type sink (::boost::asio::io_service& ios) &&; + + /// Copy the source out of this class and change the io_service. \attention Will always copy. + handle_type source(::boost::asio::io_service& ios) const &; + /// Copy the sink out of this class and change the io_service. \attention Will always copy + handle_type sink (::boost::asio::io_service& ios) const &; + - ///Steal, i.e. move, the source out of this class. - handle_type steal_source(); - ///Steal, i.e. move the sink out of this class. - handle_type steal_sink(); - ///Steal, i.e. move, the source out of this class and change the io_service. - handle_type steal_source(::boost::asio::io_service& ios); - ///Steal, i.e. move, the sink out of this class and change the io_service. - handle_type steal_sink (::boost::asio::io_service& ios); - ///Clone the source. - handle_type clone_source() const; - ///Clone the sink. - handle_type clone_sink() const; - ///Clone the source and replace the io_service. - handle_type clone_source(::boost::asio::io_service& ios) const; - ///Clone the sink and replace the io_service. - handle_type clone_sink (::boost::asio::io_service& ios) const }; #else diff --git a/include/boost/process/detail/posix/async_pipe.hpp b/include/boost/process/detail/posix/async_pipe.hpp index 64a4b67a..d6569239 100644 --- a/include/boost/process/detail/posix/async_pipe.hpp +++ b/include/boost/process/detail/posix/async_pipe.hpp @@ -151,40 +151,31 @@ public: } - const handle_type & sink () const {return _sink;} - const handle_type & source() const {return _source;} + const handle_type & sink () const & {return _sink;} + const handle_type & source() const & {return _source;} - handle_type steal_source() { return steal_source(_source.get_io_service()); } - handle_type steal_sink() { return steal_sink(_sink.get_io_service()); } + handle_type && source()&& { return std::move(_sink); } + handle_type && sink() && { return std::move(_source); } - handle_type steal_source(::boost::asio::io_service& ios) + handle_type source(::boost::asio::io_service& ios) && { ::boost::asio::posix::stream_descriptor stolen(ios, _source.native_handle()); _source.assign(-1); return stolen; } - handle_type steal_sink (::boost::asio::io_service& ios) + handle_type sink (::boost::asio::io_service& ios) && { ::boost::asio::posix::stream_descriptor stolen(ios, _sink.native_handle()); _sink.assign(-1); return stolen; } - handle_type clone_source() const - { - return clone_source(const_cast(_source).get_io_service()); - } - handle_type clone_sink() const - { - return clone_sink(const_cast(_sink).get_io_service()); - } - - handle_type clone_source(::boost::asio::io_service& ios) const + handle_type source(::boost::asio::io_service& ios) const & { auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native(); return ::boost::asio::posix::stream_descriptor(ios, ::dup(source_in)); } - handle_type clone_sink (::boost::asio::io_service& ios) const + handle_type sink (::boost::asio::io_service& ios) const & { auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native(); return ::boost::asio::posix::stream_descriptor(ios, ::dup(sink_in)); diff --git a/include/boost/process/detail/windows/async_in.hpp b/include/boost/process/detail/windows/async_in.hpp index 62e7f706..81f1bfa9 100644 --- a/include/boost/process/detail/windows/async_in.hpp +++ b/include/boost/process/detail/windows/async_in.hpp @@ -88,7 +88,7 @@ struct async_in_buffer : ::boost::process::detail::windows::async_handler }); }; - }; + } template void on_setup(WindowsExecutor &exec) { diff --git a/include/boost/process/detail/windows/async_out.hpp b/include/boost/process/detail/windows/async_out.hpp index 1d01379e..eed5ec96 100644 --- a/include/boost/process/detail/windows/async_out.hpp +++ b/include/boost/process/detail/windows/async_out.hpp @@ -106,7 +106,7 @@ struct async_out_buffer : ::boost::process::detail::windows::async_handler - }; + } template void on_setup(WindowsExecutor &exec) { @@ -181,7 +181,7 @@ struct async_out_future : ::boost::process::detail::windows::async_handler }); }; - }; + } template void on_setup(WindowsExecutor &exec) diff --git a/include/boost/process/detail/windows/async_pipe.hpp b/include/boost/process/detail/windows/async_pipe.hpp index 3c1d93a1..c2fa385e 100644 --- a/include/boost/process/detail/windows/async_pipe.hpp +++ b/include/boost/process/detail/windows/async_pipe.hpp @@ -164,35 +164,26 @@ public: _sink.async_write_some(buffers, std::forward(handler)); } - const handle_type & sink () const {return _sink;} - const handle_type & source() const {return _source;} + const handle_type & sink () const & {return _sink;} + const handle_type & source() const & {return _source;} - handle_type steal_source() { return steal_source(_source.get_io_service()); } - handle_type steal_sink() { return steal_sink(_sink.get_io_service()); } + handle_type && source() && { return std::move(_source); } + handle_type && sink() && { return std::move(_sink); } - handle_type steal_source(::boost::asio::io_service& ios) + handle_type source(::boost::asio::io_service& ios) && { ::boost::asio::windows::stream_handle stolen(ios, _source.native_handle()); _source.assign(::boost::detail::winapi::INVALID_HANDLE_VALUE_); return stolen; } - handle_type steal_sink (::boost::asio::io_service& ios) + handle_type sink (::boost::asio::io_service& ios) && { ::boost::asio::windows::stream_handle stolen(ios, _sink.native_handle()); _sink.assign(::boost::detail::winapi::INVALID_HANDLE_VALUE_); return stolen; } - handle_type clone_source() const - { - return clone_source(const_cast(_source).get_io_service()); - } - handle_type clone_sink() const - { - return clone_sink(const_cast(_sink).get_io_service()); - } - - handle_type clone_source(::boost::asio::io_service& ios) const + handle_type source(::boost::asio::io_service& ios) const & { auto proc = ::boost::detail::winapi::GetCurrentProcess(); @@ -208,7 +199,7 @@ public: return ::boost::asio::windows::stream_handle(ios, source); } - handle_type clone_sink (::boost::asio::io_service& ios) const + handle_type sink (::boost::asio::io_service& ios) const & { auto proc = ::boost::detail::winapi::GetCurrentProcess(); diff --git a/include/boost/process/detail/windows/basic_pipe.hpp b/include/boost/process/detail/windows/basic_pipe.hpp index acfd8417..c06ae1b6 100644 --- a/include/boost/process/detail/windows/basic_pipe.hpp +++ b/include/boost/process/detail/windows/basic_pipe.hpp @@ -79,7 +79,7 @@ public: else throw std::system_error(ec, "WriteFile failed"); } - return write_len; + return static_cast(write_len); } int_type read(char_type * data, int_type count) { @@ -94,7 +94,7 @@ public: else throw std::system_error(ec, "ReadFile failed"); } - return read_len; + return static_cast(read_len); } bool is_open() diff --git a/include/boost/process/detail/windows/child_handle.hpp b/include/boost/process/detail/windows/child_handle.hpp index 0f357f45..16ce31dd 100644 --- a/include/boost/process/detail/windows/child_handle.hpp +++ b/include/boost/process/detail/windows/child_handle.hpp @@ -82,14 +82,14 @@ struct child_handle ::boost::detail::winapi::BOOL_ value; if (!::boost::detail::winapi::IsProcessInJob(proc_info.hProcess, nullptr, &value)) throw_last_error("IsProcessinJob Failed"); - return value; + 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)) ec = get_last_error(); - return value; + return value!=0; } }; diff --git a/include/boost/process/detail/windows/environment.hpp b/include/boost/process/detail/windows/environment.hpp index a9f14e3e..58b795a5 100644 --- a/include/boost/process/detail/windows/environment.hpp +++ b/include/boost/process/detail/windows/environment.hpp @@ -255,7 +255,7 @@ inline void basic_environment_impl::set(const string_type &id, const strin { reset(id); - std::vector insertion; + std::vector insertion; insertion.insert(insertion.end(), id.begin(), id.end()); insertion.push_back('='); diff --git a/include/boost/process/detail/windows/executor.hpp b/include/boost/process/detail/windows/executor.hpp index 5f44b33a..14ec1146 100644 --- a/include/boost/process/detail/windows/executor.hpp +++ b/include/boost/process/detail/windows/executor.hpp @@ -175,13 +175,13 @@ public: child operator()() { - on_setup_t on_setup(*this); - boost::fusion::for_each(seq, on_setup); + on_setup_t on_setup_fn(*this); + boost::fusion::for_each(seq, on_setup_fn); if (_ec) { - on_error_t on_error(*this, _ec); - boost::fusion::for_each(seq, on_error); + on_error_t on_error_fn(*this, _ec); + boost::fusion::for_each(seq, on_error_fn); return child(); } @@ -203,8 +203,8 @@ public: if (err_code != 0) { _ec.clear(); - on_success_t on_success(*this); - boost::fusion::for_each(seq, on_success); + on_success_t on_success_fn(*this); + boost::fusion::for_each(seq, on_success_fn); } else set_error(::boost::process::detail::get_last_error(), @@ -212,8 +212,8 @@ public: if ( _ec) { - on_error_t on_error(*this, _ec); - boost::fusion::for_each(seq, on_error); + on_error_t on_err(*this, _ec); + boost::fusion::for_each(seq, on_err); return child(); } else diff --git a/include/boost/process/detail/windows/group_handle.hpp b/include/boost/process/detail/windows/group_handle.hpp index 40de6beb..709da657 100644 --- a/include/boost/process/detail/windows/group_handle.hpp +++ b/include/boost/process/detail/windows/group_handle.hpp @@ -143,14 +143,14 @@ struct group_handle if (!::boost::detail::winapi::IsProcessInJob(proc, _job_object, &is)) throw_last_error(); - return is; + 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)) ec = get_last_error(); - return is; + return is!=0; } bool valid() const @@ -180,7 +180,7 @@ inline bool in_group() if (!::boost::detail::winapi::IsProcessInJob(boost::detail::winapi::GetCurrentProcess(), nullptr, &res)) throw_last_error("IsProcessInJob failed"); - return res; + return res!=0; } diff --git a/include/boost/process/detail/windows/io_service_ref.hpp b/include/boost/process/detail/windows/io_service_ref.hpp index 264b346d..e1ea08d5 100644 --- a/include/boost/process/detail/windows/io_service_ref.hpp +++ b/include/boost/process/detail/windows/io_service_ref.hpp @@ -66,7 +66,7 @@ struct async_handler_collector 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. diff --git a/include/boost/process/detail/windows/locale.hpp b/include/boost/process/detail/windows/locale.hpp index dc8b3455..4b7711e4 100644 --- a/include/boost/process/detail/windows/locale.hpp +++ b/include/boost/process/detail/windows/locale.hpp @@ -8,6 +8,7 @@ #define BOOST_PROCESS_DETAIL_WINDOWS_LOCALE_HPP_ #include +#include #include #include @@ -39,6 +40,7 @@ class windows_file_codecvt 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_; @@ -46,7 +48,7 @@ class windows_file_codecvt int count; if ((count = ::boost::detail::winapi::MultiByteToWideChar(codepage, ::boost::detail::winapi::MB_PRECOMPOSED_, from, - from_end - from, to, to_end - to)) == 0) + static_cast(from_end - from), to, static_cast(to_end - to))) == 0) { return error; // conversion failed } @@ -61,6 +63,7 @@ class windows_file_codecvt 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_; @@ -68,7 +71,7 @@ class windows_file_codecvt int count; if ((count = ::boost::detail::winapi::WideCharToMultiByte(codepage, ::boost::detail::winapi::WC_NO_BEST_FIT_CHARS_, from, - from_end - from, to, to_end - to, 0, 0)) == 0) + static_cast(from_end - from), to, static_cast(to_end - to), 0, 0)) == 0) { return error; // conversion failed } diff --git a/include/boost/process/detail/windows/on_exit.hpp b/include/boost/process/detail/windows/on_exit.hpp index 782d5e22..8b7acabc 100644 --- a/include/boost/process/detail/windows/on_exit.hpp +++ b/include/boost/process/detail/windows/on_exit.hpp @@ -35,7 +35,7 @@ struct on_exit_ : boost::process::detail::windows::async_handler handler(static_cast(exit_code), ec); }; - }; + } }; diff --git a/include/boost/process/detail/windows/wait_group.hpp b/include/boost/process/detail/windows/wait_group.hpp index 4da295b8..449985f2 100644 --- a/include/boost/process/detail/windows/wait_group.hpp +++ b/include/boost/process/detail/windows/wait_group.hpp @@ -13,7 +13,7 @@ namespace boost { namespace process { namespace detail { namespace windows { -class group_handle; +struct group_handle; inline void wait(const group_handle &p) { diff --git a/include/boost/process/environment.hpp b/include/boost/process/environment.hpp index 669cd095..b7a0d84f 100644 --- a/include/boost/process/environment.hpp +++ b/include/boost/process/environment.hpp @@ -54,8 +54,8 @@ struct const_entry return string_type(); } string_type get_name() const {return string_type(_name.begin(), _name.end());} - explicit const_entry(string_type&& name, pointer data, environment_t & env) : - _name(std::move(name)), _data(data), _env(&env) {} + explicit const_entry(string_type&& name, pointer data, environment_t & env_) : + _name(std::move(name)), _data(data), _env(&env_) {} explicit const_entry(string_type &&name, environment_t & env) : _name(std::move(name)), _data(nullptr), _env(&env) {} diff --git a/include/boost/process/pipe.hpp b/include/boost/process/pipe.hpp index 6a2f804f..4e8a53a1 100644 --- a/include/boost/process/pipe.hpp +++ b/include/boost/process/pipe.hpp @@ -183,7 +183,9 @@ struct basic_pipebuf : std::basic_streambuf auto len = &_read.back() - this->egptr() ; - auto res = _pipe.read(this->egptr(), len); + auto res = _pipe.read( + this->egptr(), + static_cast(len)); if (res == 0) return traits_type::eof(); @@ -198,10 +200,12 @@ struct basic_pipebuf : std::basic_streambuf void pipe(pipe_type&& p) {_pipe = std::move(p); } ///Set the pipe of the streambuf. void pipe(const pipe_type& p) {_pipe = p; } - ///Get a const reference of the pipe. - const pipe_type &pipe() const {return _pipe;} - ///Get a reference of the pipe. \note Is a reference so it can be moved. - pipe_type &pipe() {return _pipe;} + ///Get a reference to the pipe. + pipe_type & pipe() & {return _pipe;} + ///Get a const reference to the pipe. + const pipe_type &pipe() const & {return _pipe;} + ///Get a rvalue reference to the pipe. Qualified as rvalue. + pipe_type && pipe() && {return std::move(_pipe);} private: pipe_type _pipe; std::vector _write; @@ -213,7 +217,8 @@ private: return false; auto base = this->pbase(); - auto wrt = _pipe.write(base, this->pptr() - base); + auto wrt = _pipe.write(base, + static_cast(this->pptr() - base)); std::ptrdiff_t diff = this->pptr() - base; if (wrt < diff) @@ -293,10 +298,12 @@ public: void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); } ///Set the pipe of the streambuf. void pipe(const pipe_type& p) {_buf.pipe(p); } - ///Get a const reference of the pipe. - const pipe_type &pipe() const {return _buf.pipe();} - ///Get a reference of the pipe. \note Is a reference so it can be moved. - pipe_type &pipe() {return _buf.pipe();} + ///Get a reference to the pipe. + pipe_type & pipe() & {return _buf.pipe();} + ///Get a const reference to the pipe. + const pipe_type &pipe() const & {return _buf.pipe();} + ///Get a rvalue reference to the pipe. Qualified as rvalue. + pipe_type && pipe() && {return std::move(_buf).pipe();} }; typedef basic_ipstream ipstream; @@ -365,10 +372,12 @@ public: void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); } ///Set the pipe of the streambuf. void pipe(const pipe_type& p) {_buf.pipe(p); } - ///Get a const reference of the pipe. - const pipe_type &pipe() const {return _buf.pipe();} - ///Get a reference of the pipe. \note Is a reference so it can be moved. - pipe_type &pipe() {return _buf.pipe();} + ///Get a reference to the pipe. + pipe_type & pipe() & {return _buf.pipe();} + ///Get a const reference to the pipe. + const pipe_type &pipe() const & {return _buf.pipe();} + ///Get a rvalue reference to the pipe. Qualified as rvalue. + pipe_type && pipe() && {return std::move(_buf).pipe();} }; typedef basic_opstream opstream; @@ -438,10 +447,12 @@ public: void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); } ///Set the pipe of the streambuf. void pipe(const pipe_type& p) {_buf.pipe(p); } - ///Get a const reference of the pipe. - const pipe_type &pipe() const {return _buf.pipe();} - ///Get a reference of the pipe. \note Is a reference so it can be moved. - pipe_type &pipe() {return _buf.pipe();} + ///Get a reference to the pipe. + pipe_type & pipe() & {return _buf.pipe();} + ///Get a const reference to the pipe. + const pipe_type &pipe() const & {return _buf.pipe();} + ///Get a rvalue reference to the pipe. Qualified as rvalue. + pipe_type && pipe() && {return std::move(_buf).pipe();} }; typedef basic_pstream pstream; diff --git a/test/Jamfile.jam b/test/Jamfile.jam index be07a130..01d98439 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -16,7 +16,8 @@ if [ os.name ] = NT } project : requirements - msvc:_SCL_5SECURE_NO_WARNINGS + msvc:_SCL_SECURE_NO_WARNINGS + msvc:_CRT_SECURE_NO_DEPRECATE windows:WIN32_LEAN_AND_MEAN linux:-lpthread NT,cw:ws2_32 @@ -38,14 +39,14 @@ alias coroutine : /boost//coroutine : static ; exe sparring_partner : sparring_partner.cpp program_options system filesystem iostreams : off ; - -exe sub_launch : sub_launcher.cpp program_options iostreams system filesystem : off ; + +exe sub_launch : sub_launcher.cpp program_options iostreams system filesystem : off ; test-suite bare : [ run environment.cpp system filesystem ] [ run pipe.cpp system filesystem ] ; - + test-suite execution : [ run async.cpp system thread filesystem : : sparring_partner ] [ run async_fut.cpp system thread filesystem : : sparring_partner ]