Skip to content
This repository has been archived by the owner on Jun 11, 2022. It is now read-only.

Commit

Permalink
Merge branch 'develop' into limit_fd
Browse files Browse the repository at this point in the history
# Conflicts:
#	include/boost/process/detail/posix/pipe_out.hpp
#	test/Jamfile.jam
  • Loading branch information
klemens-morgenstern committed May 12, 2019
2 parents 6263e74 + 28126b3 commit cbaa913
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 95 deletions.
3 changes: 1 addition & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
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
bash <(curl -s https://codecov.io/bash) -x gcov > /dev/null || true
echo "BUILD_RESULT: $FAILED"
exit $FAILED
10 changes: 4 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ os:
- linux
- osx

secure: "vs7qgXb0lQg8CTyDPSi3RQtOIOtssaCkBIx86UoEvTXwJCTOLPe7ZufQ0lobn0OVWo261AMx9GbumBBzqfsvJc1G6ixGBVwymiGli/R8DZDvvg9UdljsEk65s/XbujE/9qh97zKGGioFyCn1Bmf5+SdDAxsuXTZm/cBny5VxYaaCR7s2cFUmp4up/djqg1GI7uwBh3ceodT3OL1X3dlMV59gOJWWNsB+RO9b9DPhTW7nOlMNRiEFik4rweecQB0JS8LaHDjYwzIRrGYHX+lR9cE/O8GCCHcUOmq9jCozDdxx+HZRu4rb1ST1RiDbvYaoeTif0Df1fVXHWOoO2D4NlXB6tJPXw2mkop00j6zkcydUJYid6T1lwfEpXAhd5A9FvOIXO5hoju1wlqfkU2eFQ9Na8z8bCIX2niZmveZWp4Ag52gEPzJMFx9hHGT8J4FWMvkqTWezux1sPZrjZjc0kXdJrIp84D9MsBc1sKrxOAOb5ekSfIK5n4JDkgUtuwMSTvEdWqNJXFPZq1rEu4GTwX99z3/XF+pM5XaCDQtZ/zUA5SPHhy0dKLH/BvceUqLJt53+lMcpsltJDB+XxQ/CFL7IdgR91OKGus/z4dbVWiSdkoNvcuZqjQLFLOMVNxoqC6PRvDAEhpy21j/5GUPvM5baQS7IEin0NF7bOTtXJdY="

env:
matrix:
- BADGE=linux
Expand Down Expand Up @@ -73,7 +71,7 @@ before_install:
# Set this to the name of the library
- PROJECT_TO_TEST=`basename $TRAVIS_BUILD_DIR`
- echo "Testing $PROJECT_TO_TEST"
- if [ $TRAVIS_OS_NAME = "osx" ]; then brew install gcc5; brew install valgrind; brew install llvm; TOOLSET=clang; BOOST_TEST_CATCH_SYSTEM_ERRORS=no; MULTITHREAD=-j8; else TOOLSET=gcc-5; USE_VALGRIND="testing.launcher=valgrind valgrind=on"; fi
- if [ $TRAVIS_OS_NAME = "osx" ]; then brew install gcc5; brew install valgrind; brew install llvm; TOOLSET=clang; BOOST_TEST_CATCH_SYSTEM_ERRORS=no; MULTITHREAD=-j8; else TOOLSET=gcc-5; REPORT_CI=--boost-process-report-ci USE_VALGRIND="testing.launcher=valgrind valgrind=on"; fi
# Cloning Boost libraries (fast nondeep cloning)
- BOOST=$HOME/boost-local
- git init $BOOST
Expand Down Expand Up @@ -103,8 +101,8 @@ before_install:
- echo BOOST_TEST_CATCH_SYSTEM_ERRORS $BOOST_TEST_CATCH_SYSTEM_ERRORS
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=.
- ../../../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=. $REPORT_CI
- ../../../b2 $MULTITHREAD without-valgrind address-model=64 architecture=x86 toolset=$TOOLSET cxxflags="--coverage -DBOOST_TRAVISCI_BUILD -std=$CXX_STANDARD" linkflags="--coverage" -sBOOST_BUILD_PATH=. $REPORT_CI
after_success:
# Copying Coveralls data to a separate folder
- mkdir -p $TRAVIS_BUILD_DIR/coverals
Expand Down Expand Up @@ -133,6 +131,6 @@ after_success:
- coveralls-lcov coverals/coverage.info

after_script:
- curl -s https://report.ci/upload.py | python - --token=$REPORT_CI_TOKEN --name="$BADGE test run"
- curl -s https://report.ci/upload.py | python - --name="$BADGE test run"
- bash <(curl -s https://codecov.io/bash)

2 changes: 1 addition & 1 deletion doc/concepts.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -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 not, that if the the same thread reads and write to a pipe, it will only talk to itself.
Though please note, that if the the same thread reads and write to a pipe, it will only talk to itself.

[section:anonymous Anonymous Pipes]

Expand Down
24 changes: 9 additions & 15 deletions include/boost/process/detail/posix/pipe_out.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,15 @@
#include <boost/process/pipe.hpp>
#include <boost/process/detail/posix/handler.hpp>
#include <unistd.h>
#include <array>
#include <boost/process/detail/used_handles.hpp>

namespace boost { namespace process { namespace detail { namespace posix {

template<int p1, int p2>
struct pipe_out : handler_base_ext, ::boost::process::detail::uses_handles
struct pipe_out : handler_base_ext
{
int sink;
int source; //opposite end

std::array<int, 4> get_used_handles()
{
const auto pp1 = p1 != -1 ? p1 : p2;
const auto pp2 = p2 != -1 ? p2 : p1;

return {source, sink, pp1, pp2};
}

pipe_out(int sink, int source) : sink(sink), source(source) {}

template<typename T>
Expand Down Expand Up @@ -63,7 +53,9 @@ 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");
::close(sink);

if (sink != STDOUT_FILENO)
::close(sink);
::close(source);
}

Expand All @@ -73,7 +65,9 @@ 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);

if (sink != STDOUT_FILENO)
::close(sink);
::close(source);
}

Expand All @@ -85,8 +79,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");
::close(sink);
::close(source);
if ((sink != STDOUT_FILENO) && (sink != STDERR_FILENO))
::close(sink);
}

class async_pipe;
Expand Down
2 changes: 1 addition & 1 deletion include/boost/process/detail/posix/terminate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ inline void terminate(const child_handle &p, std::error_code &ec) noexcept
ec.clear();

int status;
::waitpid(p.pid, &status, 0); //just to clean it up
::waitpid(p.pid, &status, WNOHANG); //just to clean it up
}

inline void terminate(const child_handle &p)
Expand Down
50 changes: 33 additions & 17 deletions include/boost/process/detail/posix/wait_for_exit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,18 @@ inline bool wait_until(
const std::chrono::time_point<Clock, Duration>& time_out,
std::error_code & ec) noexcept
{

::sigset_t sigset;

sigemptyset(&sigset);
sigaddset(&sigset, SIGCHLD);
if (sigemptyset(&sigset) != 0)
{
ec = get_last_error();
return false;
}
if (sigaddset(&sigset, SIGCHLD) != 0)
{
ec = get_last_error();
return false;
}

auto get_timespec =
[](const Duration & dur)
Expand All @@ -69,8 +76,8 @@ inline bool wait_until(
return ts;
};

pid_t ret;
int status;
int ret;
int status{0};

struct ::sigaction old_sig;
if (-1 == ::sigaction(SIGCHLD, nullptr, &old_sig))
Expand Down Expand Up @@ -113,9 +120,17 @@ inline bool wait_until(
{
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);

while (ts.tv_sec > 0 || ts.tv_nsec > 0)
{
if (::nanosleep(&ts, &rem) != 0)
{
auto err = errno;
if ((err == EINVAL) || (err == EFAULT))
break;
}
ts = get_timespec(time_out - Clock::now());
}
::exit(0);
}

Expand All @@ -125,27 +140,28 @@ inline bool wait_until(
~child_cleaner_t()
{
int res;
::kill(pid, SIGTERM);
::waitpid(pid, &res, WNOHANG);
::kill(pid, SIGKILL);
::waitpid(pid, &res, 0);
}
};
child_cleaner_t child_cleaner{timeout_pid};

do
{
int ret_sig = 0;
int sig_;
if ((::waitpid(timeout_pid, &status, WNOHANG) != 0)
&& (WIFEXITED(status) || WIFSIGNALED(status)))
ret_sig = ::sigwait(&sigset, nullptr);
errno = 0;
&& (WIFEXITED(status) || WIFSIGNALED(status)))
return false;

ret = ::waitpid(p.pid, &status, WNOHANG);
ret = ::sigwait(&sigset, &sig_);
errno = 0;

if ((ret_sig == SIGCHLD) &&
if ((ret == SIGCHLD) &&
(old_sig.sa_handler != SIG_DFL) && (old_sig.sa_handler != SIG_IGN))
old_sig.sa_handler(ret);

if (ret <= 0)
ret = ::waitpid(p.pid, &status, WNOHANG);
if (ret == 0) // == > is running
{
timed_out = Clock::now() >= time_out;
if (timed_out)
Expand Down
Loading

0 comments on commit cbaa913

Please sign in to comment.