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 asio_no_deprecated
Browse files Browse the repository at this point in the history
  • Loading branch information
klemens-morgenstern committed Apr 6, 2019
2 parents 2a6c23e + 1b476b0 commit 34f05b9
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 54 deletions.
98 changes: 48 additions & 50 deletions include/boost/process/detail/posix/executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,47 +22,12 @@
#include <errno.h>
#include <unistd.h>

#if !defined(__GLIBC__)
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#endif

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

inline int execvpe(const char* filename, char * const arg_list[], char* env[])
{
#if defined(__GLIBC__)
return ::execvpe(filename, arg_list, env);
#else
//use my own implementation
std::string fn = filename;
if ((fn.find('/') == std::string::npos) && ::access(fn.c_str(), X_OK))
{
auto e = ::environ;
while ((*e != nullptr) && !boost::starts_with(*e, "PATH="))
e++;

if (e != nullptr)
{
std::vector<std::string> path;
boost::split(path, *e, boost::is_any_of(":"));

for (const std::string & pp : path)
{
auto p = pp + "/" + filename;
if (!::access(p.c_str(), X_OK))
{
fn = p;
break;
}
}
}
}
return ::execve(fn.c_str(), arg_list, env);
#endif
}

template<typename Executor>
struct on_setup_t
{
Expand Down Expand Up @@ -300,6 +265,36 @@ class executor
set_error(ec, std::move(msg));
}

std::string prepare_cmd_style_fn; //buffer

inline void prepare_cmd_style() //this does what execvpe does - but we execute it in the father process, to avoid allocations.
{
//use my own implementation
prepare_cmd_style_fn = exe;
if ((prepare_cmd_style_fn.find('/') == std::string::npos) && ::access(prepare_cmd_style_fn.c_str(), X_OK))
{
auto e = ::environ;
while ((*e != nullptr) && !boost::starts_with(*e, "PATH="))
e++;

if (e != nullptr)
{
std::vector<std::string> path;
boost::split(path, *e, boost::is_any_of(":"));

for (const std::string & pp : path)
{
auto p = pp + "/" + exe;
if (!::access(p.c_str(), X_OK))
{
prepare_cmd_style_fn = p;
break;
}
}
}
}
exe = prepare_cmd_style_fn.c_str();
}

std::error_code _ec;
std::string _msg;
Expand Down Expand Up @@ -338,6 +333,8 @@ child executor<Sequence>::invoke(boost::mpl::true_, boost::mpl::false_) //ignore
boost::fusion::for_each(seq, call_on_setup(*this));
if (_ec)
return child();
if (cmd_style)
prepare_cmd_style();

this->pid = ::fork();
if (pid == -1)
Expand All @@ -349,10 +346,7 @@ child executor<Sequence>::invoke(boost::mpl::true_, boost::mpl::false_) //ignore
else if (pid == 0)
{
boost::fusion::for_each(seq, call_on_exec_setup(*this));
if (cmd_style)
::boost::process::detail::posix::execvpe(exe, cmd_line, env);
else
::execve(exe, cmd_line, env);
::execve(exe, cmd_line, env);
auto ec = boost::process::detail::get_last_error();
boost::fusion::for_each(seq, call_on_exec_error(*this, ec));
_exit(EXIT_FAILURE);
Expand All @@ -372,11 +366,14 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::false_)
struct pipe_guard
{
int p[2];
pipe_guard() : p{-1,-1} {}

~pipe_guard()
{
::close(p[0]);
::close(p[1]);
if (p[0] != -1)
::close(p[0]);
if (p[1] != -1)
::close(p[1]);
}
} p{};

Expand All @@ -400,6 +397,9 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::false_)
return child();
}

if (cmd_style)
prepare_cmd_style();

this->pid = ::fork();
if (pid == -1)
{
Expand All @@ -415,10 +415,7 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::false_)
::close(p.p[0]);

boost::fusion::for_each(seq, call_on_exec_setup(*this));
if (cmd_style)
::boost::process::detail::posix::execvpe(exe, cmd_line, env);
else
::execve(exe, cmd_line, env);
::execve(exe, cmd_line, env);
_ec = boost::process::detail::get_last_error();
_msg = "execve failed";
boost::fusion::for_each(seq, call_on_exec_error(*this, _ec));
Expand All @@ -430,8 +427,10 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::false_)
return child();
}


::close(p.p[1]);
p.p[1] = -1;
_read_error(p.p[0]);

}
if (_ec)
{
Expand Down Expand Up @@ -494,6 +493,8 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::true_)
return child();
}
_ec.clear();
if (cmd_style)
this->prepare_cmd_style();

this->pid = ::vfork();
if (pid == -1)
Expand All @@ -509,10 +510,7 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::true_)
{
boost::fusion::for_each(seq, call_on_exec_setup(*this));

if (cmd_style)
::boost::process::detail::posix::execvpe(exe, cmd_line, env);
else
::execve(exe, cmd_line, env);
::execve(exe, cmd_line, env);

_ec = boost::process::detail::get_last_error();
_msg = "execve failed";
Expand Down
5 changes: 2 additions & 3 deletions test/Jamfile.jam
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ exe sub_launch : sub_launcher.cpp program_options iostreams system filesystem :

rule test-options ( name )
{
return --log_sink=log_$(name).xml --log_format=XML --log_level=error --report_sink=report_$(name).xml --report_format=XML --report_level=detailed -- ;
# return --log_sink=log_$(name).xml --log_format=XML --log_level=error --report_sink=report_$(name).xml --report_format=XML --report_level=detailed -- ;
return --log_level=error --report_level=detailed -- ;
}


Expand All @@ -69,8 +70,6 @@ test-suite bare :
[ compile asio_no_deprecated.cpp ]
;

echo [ test-options foo ] ;

test-suite with-valgrind :
[ run async.cpp system thread filesystem : [ test-options async ] : sparring_partner ]
[ run async_fut.cpp system thread filesystem : [ test-options async_fut ] : sparring_partner ]
Expand Down
4 changes: 3 additions & 1 deletion test/pipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <thread>

#include <boost/process/pipe.hpp>
#include <boost/process/environment.hpp>

using namespace std;
namespace bp = boost::process;
Expand Down Expand Up @@ -38,7 +39,8 @@ BOOST_AUTO_TEST_CASE(named, *boost::unit_test::timeout(2))
#if defined( BOOST_WINDOWS_API )
bp::pipe pipe("\\\\.\\pipe\\pipe_name");
#elif defined( BOOST_POSIX_API )
bp::pipe pipe("./test_pipe");
const auto home_path = boost::this_process::environment()["HOME"].to_string();
bp::pipe pipe(home_path + "/.boost_process_test_pipe");
#endif

std::string in = "xyz";
Expand Down
2 changes: 2 additions & 0 deletions test/pipe_fwd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ BOOST_AUTO_TEST_CASE(sync_io, *boost::unit_test::timeout(5))
);
BOOST_REQUIRE(!ec);

BOOST_TEST_INFO("Launching child 2");

bp::child c2(
master_test_suite().argv[1],
bp::args={"test", "--prefix-once", "hello "},
Expand Down

0 comments on commit 34f05b9

Please sign in to comment.