2
0
mirror of https://github.com/boostorg/process.git synced 2026-01-20 16:52:14 +00:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Klemens David Morgenstern
83c2a986cb trait & fwd decl fixes 2019-04-10 13:41:08 +08:00
Klemens David Morgenstern
41fff78e00 Trying to add dynamic_buffer with sfinae as proposed in boostorg/process#56 2019-04-10 12:51:46 +08:00
10 changed files with 65 additions and 94 deletions

View File

@@ -70,7 +70,6 @@ jobs:
python <(curl -s https://report.ci/annotate.py) --tool gcc --input test.log
python <(curl -s https://report.ci/annotate.py) --tool gcc --input no-valgrind.log
cd ../../..
python <(curl -s https://report.ci/upload.py) --name "Circle CI Gcc Tests" --framework boost
bash <(curl -s https://codecov.io/bash) -x gcov || true
echo "BUILD_RESULT: $FAILED"

View File

@@ -105,8 +105,6 @@ script:
# `--coverage` flags required to generate coverage info for Coveralls
- ../../../b2 $MULTITHREAD with-valgrind address-model=64 architecture=x86 $USE_VALGRIND toolset=$TOOLSET cxxflags="--coverage -DBOOST_TRAVISCI_BUILD -std=$CXX_STANDARD" linkflags="--coverage" -sBOOST_BUILD_PATH=.
- ../../../b2 $MULTITHREAD without-valgrind address-model=64 architecture=x86 toolset=$TOOLSET cxxflags="--coverage -DBOOST_TRAVISCI_BUILD -std=$CXX_STANDARD" linkflags="--coverage" -sBOOST_BUILD_PATH=.
- cat /home/travis/boost-local/libs/boost-process/test/report_wait_for.xml
- cat /home/travis/boost-local/libs/boost-process/test/log_wait_for.xml
after_success:
# Copying Coveralls data to a separate folder
- mkdir -p $TRAVIS_BUILD_DIR/coverals
@@ -135,6 +133,6 @@ after_success:
- coveralls-lcov coverals/coverage.info
after_script:
- curl -s https://report.ci/upload.py | python - --name="$BADGE test run"
- curl -s https://report.ci/upload.py | python - --token=$REPORT_CI_TOKEN --name="$BADGE test run"
- bash <(curl -s https://codecov.io/bash)

View File

@@ -16,7 +16,7 @@ In that it is different than other facilities (like sockets) and provides anothe
Pipes are typically used for interprocess communication. The main reason is, that pipes can be directly assigned to the process stdio, i.e. stderr, stdin and stdout.
Additionally, half of the pipe can be inherited to the child process and closed in the father process. This will cause the pipe to be broken when the child process exits.
Though please note, that if the the same thread reads and write to a pipe, it will only talk to itself.
Though please not, that if the the same thread reads and write to a pipe, it will only talk to itself.
[section:anonymous Anonymous Pipes]

View File

@@ -10,11 +10,13 @@
namespace boost { namespace asio {
class mutable_buffer;
class mutable_buffers_1;
template<typename T>
struct is_mutable_buffer_sequence;
template<typename T>
struct is_const_buffer_sequence;
class const_buffer;
class const_buffers_1;
template<typename Allocator>
class basic_streambuf;

View File

@@ -52,10 +52,8 @@ 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(), "dup2() failed");
if (sink != STDOUT_FILENO)
::close(sink);
e.set_error(::boost::process::detail::get_last_error(), "dup3() failed");
::close(sink);
::close(source);
}
@@ -65,9 +63,7 @@ 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");
if (sink != STDOUT_FILENO)
::close(sink);
::close(sink);
::close(source);
}
@@ -79,8 +75,8 @@ void pipe_out<1,2>::on_exec_setup(Executor &e) const
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");
if ((sink != STDOUT_FILENO) && (sink != STDERR_FILENO))
::close(sink);
::close(sink);
::close(source);
}
class async_pipe;

View File

@@ -111,14 +111,11 @@ inline bool wait_until(
}
else if (timeout_pid == 0)
{
do
{
auto ts = get_timespec(time_out - Clock::now());
::timespec rem;
::nanosleep(&ts, &rem);
}
while (rem.tv_sec > 0 || rem.tv_nsec > 0);
auto ts = get_timespec(time_out - Clock::now());
::timespec rem;
::nanosleep(&ts, &rem);
while (rem.tv_sec > 0 || rem.tv_nsec > 0)
::nanosleep(&rem, &rem);
::exit(0);
}
@@ -128,8 +125,8 @@ inline bool wait_until(
~child_cleaner_t()
{
int res;
::kill(pid, SIGTERM);
::waitpid(pid, &res, 0);
::kill(pid, -15);
::waitpid(pid, &res, WNOHANG);
}
};
child_cleaner_t child_cleaner{timeout_pid};

View File

@@ -117,13 +117,9 @@ inline bool wait_until(
}
else if (timeout_pid == 0)
{
do
{
auto ts = get_timespec(time_out - Clock::now());
::timespec rem;
::nanosleep(&ts, &rem);
}
while (rem.tv_sec > 0 || rem.tv_nsec > 0);
auto ts = get_timespec(time_out - Clock::now());
::setpgid(0, p.grp);
::nanosleep(&ts, nullptr);
::exit(0);
}
@@ -133,7 +129,7 @@ inline bool wait_until(
~child_cleaner_t()
{
int res;
::kill(pid, SIGKILL);
::kill(pid, -15);
::waitpid(pid, &res, WNOHANG);
}
};

View File

@@ -10,10 +10,12 @@
namespace boost { namespace asio {
class mutable_buffer;
class mutable_buffers_1;
class const_buffer;
class const_buffers_1;
template<typename T>
struct is_mutable_buffer_sequence;
template<typename T>
struct is_const_buffer_sequence;
template<typename Allocator>
class basic_streambuf;

View File

@@ -122,20 +122,6 @@ system("b2", std_out > null);
namespace boost { namespace process { namespace detail {
template<typename T> using is_streambuf = typename std::is_same<T, boost::asio::streambuf>::type;
template<typename T> using is_const_buffer =
std::integral_constant<bool,
std::is_same< boost::asio::const_buffer, T>::value |
std::is_base_of<boost::asio::const_buffer, T>::value
>;
template<typename T> using is_mutable_buffer =
std::integral_constant<bool,
std::is_same< boost::asio::mutable_buffer, T>::value |
std::is_base_of<boost::asio::mutable_buffer, T>::value
>;
struct null_t {constexpr null_t() {}};
struct close_t;
@@ -177,19 +163,25 @@ struct std_in_
api::async_pipe_in operator=(async_pipe & p) const {return p;}
api::async_pipe_in operator<(async_pipe & p) const {return p;}
template<typename T, typename = typename std::enable_if<
is_const_buffer<T>::value || is_mutable_buffer<T>::value
>::type>
api::async_in_buffer<const T> operator=(const T & buf) const {return buf;}
template<typename T, typename = typename std::enable_if<is_streambuf<T>::value>::type >
api::async_in_buffer<T> operator=(T & buf) const {return buf;}
template<typename T>
auto operator=(const T & buf) const -> typename std::enable_if<asio::is_const_buffer_sequence<T>::value, api::async_in_buffer<const T>>::type {return buf;}
template<typename T>
auto operator<(const T & buf) const -> typename std::enable_if<asio::is_const_buffer_sequence<T>::value, api::async_in_buffer<const T>>::type {return buf;}
template<typename T, typename = typename std::enable_if<
is_const_buffer<T>::value || is_mutable_buffer<T>::value
>::type>
api::async_in_buffer<const T> operator<(const T & buf) const {return buf;}
template<typename T, typename = typename std::enable_if<is_streambuf<T>::value>::type >
api::async_in_buffer<T> operator<(T & buf) const {return buf;}
template<typename T>
auto operator=(T & buf) const -> typename std::enable_if<asio::is_const_buffer_sequence<T>::value, api::async_in_buffer<T>>::type {return buf;}
template<typename T>
auto operator<(T & buf) const -> typename std::enable_if<asio::is_const_buffer_sequence<T>::value, api::async_in_buffer<T>>::type {return buf;}
template<typename Allocator>
api::async_in_buffer<asio::basic_streambuf<Allocator>> operator<(boost::asio::basic_streambuf<Allocator> & p) const {return p;}
template<typename Allocator>
api::async_in_buffer<asio::basic_streambuf<Allocator>> operator=(boost::asio::basic_streambuf<Allocator> & p) const {return p;}
template<typename Allocator>
api::async_in_buffer<asio::basic_streambuf<Allocator>> operator<(const boost::asio::basic_streambuf<Allocator> & p) const {return p;}
template<typename Allocator>
api::async_in_buffer<asio::basic_streambuf<Allocator>> operator=(const boost::asio::basic_streambuf<Allocator> & p) const {return p;}
};
@@ -234,13 +226,24 @@ struct std_out_
api::async_pipe_out<p1, p2> operator=(async_pipe & p) const {return p;}
api::async_pipe_out<p1, p2> operator>(async_pipe & p) const {return p;}
api::async_out_buffer<p1, p2, const asio::mutable_buffer> operator=(const asio::mutable_buffer & buf) const {return buf;}
api::async_out_buffer<p1, p2, const asio::mutable_buffers_1> operator=(const asio::mutable_buffers_1 & buf) const {return buf;}
api::async_out_buffer<p1, p2, asio::streambuf> operator=(asio::streambuf & os) const {return os ;}
template<typename Allocator>
api::async_out_buffer<p1, p2, asio::basic_streambuf<Allocator>> operator=(boost::asio::basic_streambuf<Allocator> & p) const {return p;}
template<typename Allocator>
api::async_out_buffer<p1, p2, asio::basic_streambuf<Allocator>> operator>(boost::asio::basic_streambuf<Allocator> & p) const {return p;}
api::async_out_buffer<p1, p2, const asio::mutable_buffer> operator>(const asio::mutable_buffer & buf) const {return buf;}
api::async_out_buffer<p1, p2, const asio::mutable_buffers_1> operator>(const asio::mutable_buffers_1 & buf) const {return buf;}
api::async_out_buffer<p1, p2, asio::streambuf> operator>(asio::streambuf & os) const {return os ;}
template<typename Buffer>
auto operator=(const Buffer & buf) const
-> typename std::enable_if<asio::is_mutable_buffer_sequence<Buffer>::value, api::async_out_buffer<p1, p2, Buffer>>::type
{
return buf;
}
template<typename Buffer>
auto operator>(const Buffer & buf) const
-> typename std::enable_if<asio::is_mutable_buffer_sequence<Buffer>::value, api::async_out_buffer<p1, p2, Buffer>>::type
{
return buf;
}
api::async_out_future<p1,p2, std::string> operator=(std::future<std::string> & fut) const { return fut;}
api::async_out_future<p1,p2, std::string> operator>(std::future<std::string> & fut) const { return fut;}

View File

@@ -111,26 +111,4 @@ BOOST_AUTO_TEST_CASE(wait_until_ec)
BOOST_CHECK_MESSAGE(!ec, ec.message());
}
BOOST_AUTO_TEST_CASE(wait_for_exit_before_timeout)
{
using boost::unit_test::framework::master_test_suite;
std::error_code ec;
auto launch_time = std::chrono::system_clock::now();
bp::child c(
master_test_suite().argv[1],
bp::args+={"test", "--wait", "1"},
ec
);
BOOST_REQUIRE(!ec);
BOOST_CHECK(c.wait_for(std::chrono::seconds(20)));
auto timeout_t = std::chrono::system_clock::now();
// check that we didn't wait the entire timeout period
BOOST_CHECK_LT(std::chrono::duration_cast<std::chrono::seconds>(timeout_t - launch_time).count(), 20);
}
BOOST_AUTO_TEST_SUITE_END();