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

Compare commits

..

49 Commits

Author SHA1 Message Date
Klemens Morgenstern
0d2da65866 ec use locations. 2023-02-08 00:10:20 +08:00
Klemens Morgenstern
7c3ba4b784 xproc fixes 2023-02-08 00:10:20 +08:00
Samuel Venable
1e60fcd830 extern process management. 2023-02-06 20:43:32 +08:00
Klemens Morgenstern
d6bcb0014a switched to BOOST_DEPRECATED. 2023-02-06 20:34:16 +08:00
Klemens Morgenstern
e5f0f245bd added clang 3.8. noexcept deduction. 2023-02-06 20:34:16 +08:00
Klemens Morgenstern
a4a3770501 disabled terminate test for freebsd. 2023-02-06 20:34:16 +08:00
Klemens Morgenstern
1e5892b8fb [drone] Removed mlocate dep. 2023-02-06 20:34:16 +08:00
Ivan Efimov
85b29d6442 Fix string construction in native_environment_impl::get 2023-02-06 20:33:12 +08:00
Klemens Morgenstern
b9ee759365 Deprecated wait_for & wait_until. 2023-02-06 20:05:09 +08:00
Klemens Morgenstern
f3b163a933 Switched vector in list of sigclhd_service.
Closes #175
2023-02-06 20:01:15 +08:00
Gary Miguel
be2ae2c3cf fix error message 2023-02-06 19:29:13 +08:00
Klemens
b2f5ebc760 ec fix for search_path with std::filesystem.
closes #287.
2023-02-06 19:09:37 +08:00
Orgad Shaneh
e34557faa0 Fix crash on search_path on Windows when PATHEXT is not found 2023-02-06 19:09:07 +08:00
Klemens Morgenstern
a9f083f45c Update process.cpp 2022-12-13 13:50:03 +08:00
Klemens Morgenstern
b5ab94c932 Disabled some tests for freebsd & added interrupt handling to osx test. 2022-12-13 10:45:47 +08:00
sdarwin
9ceda79fa2 Update metadata 2022-12-13 09:22:13 +08:00
Klemens Morgenstern
68cbeae491 Typo fix. 2022-12-13 09:19:45 +08:00
Klemens Morgenstern
ae778f36a8 Include fixes. 2022-11-11 11:14:46 +08:00
Sam Darwin
0671e4a133 Drone: update freebsd jobs (#274) 2022-11-01 10:40:04 +08:00
Klemens Morgenstern
cbf944c57b using scope-exit limit group_wait. 2022-11-01 03:08:12 +08:00
Klemens Morgenstern
5f2b8c53f4 Disabled limit_fd for freebsd. 2022-11-01 02:58:31 +08:00
Klemens Morgenstern
dac3614a38 group wait test on_scope exit fix. 2022-10-31 12:25:30 +08:00
Klemens Morgenstern
2fc71ca0a3 Disabled pdfork by default, bc of asio errors. 2022-10-31 11:23:49 +08:00
Klemens Morgenstern
404682d75d Increased timeout for sporadically failing test. 2022-10-31 11:21:48 +08:00
Klemens Morgenstern
9fbbdc3421 Merge pull request #276 from Flamefire/patch-1
Update .drone.star
2022-10-23 11:21:09 +08:00
Alexander Grund
3df0009a2f Update .drone.star
Remove the `image` param which is superflous, misleading and may become an error. See https://github.com/boostorg/boost-ci/pull/189

[skip ci]
2022-10-22 11:26:04 +02:00
Klemens Morgenstern
ecb384b253 Improved error message for OSX. 2022-10-21 12:03:31 +08:00
Klemens Morgenstern
05bce942c1 passing a pipe into sh test. 2022-10-12 11:54:05 +08:00
Klemens Morgenstern
dcf5d8ce41 Added return_type to async_result<code_as_error_t> 2022-10-12 10:54:30 +08:00
Klemens Morgenstern
4209f8ee6e Minor bugfixes 2022-10-12 01:12:28 +08:00
Klemens Morgenstern
d9513269cc Enabled freebsd build 2022-10-11 21:03:33 +08:00
Klemens
293f28dab6 Fixed async_system. 2022-09-20 13:45:43 +08:00
Klemens
fe1b629b5d Added bind_launcher. 2022-09-18 22:13:57 +08:00
Klemens
278fa57214 Added code_as_error completion handler. 2022-09-18 17:56:47 +08:00
Klemens Morgenstern
1addfba12e Added WIN32_LEAN_AND_MEAN to cmake 2022-09-17 20:39:01 +08:00
Klemens Morgenstern
4cc469b2a4 Merge pull request #252 from grtowel1510f/patch-1
fix issue #251 - fix simple shell command in posix
2022-09-14 11:38:37 +08:00
Klemens Morgenstern
6e4d1e29d2 Merge pull request #271 from boostorg/shell_v2
Shell v2
2022-09-02 20:30:03 +08:00
Klemens Morgenstern
dada865fd0 Merge pull request #269 from boostorg/klemens-morgenstern-patch-2
Closes #266
2022-09-02 20:29:20 +08:00
Klemens Morgenstern
380dd1b00f Merge pull request #268 from boostorg/klemens-morgenstern-patch-1
Closes #267
2022-09-02 20:28:50 +08:00
Klemens
7832cb6af3 Shell(posix) fixes. 2022-09-02 18:43:35 +08:00
Klemens Morgenstern
68f4c50be9 Exeuction support for shell. 2022-09-02 18:25:40 +08:00
Klemens Morgenstern
cd226a7616 Implemented shell on windows. 2022-09-02 17:05:49 +08:00
Klemens Morgenstern
4243ce72f8 Windows bugfixes. 2022-09-02 16:46:45 +08:00
Klemens
9065833e61 Added shell class. 2022-08-31 23:54:22 +08:00
Klemens Morgenstern
7cb7af6c8b Closes #267 2022-08-31 15:40:57 +08:00
Klemens Morgenstern
90cbe7cec0 Closes #266 2022-08-31 15:35:51 +08:00
Klemens
df33c1ad7b Fixed unsafe post-fork allocs for fd_whitelist. 2022-08-31 15:35:41 +08:00
Klemens
bbabea30dd Added reaping child for execve error, closes #265. 2022-08-31 15:35:41 +08:00
grtowel1510f
8a61f8daa3 fix issue #251 - fix simple shell command in posix
see issue #251 for description.
2022-05-21 14:59:37 +00:00
10 changed files with 79 additions and 126 deletions

View File

@@ -155,15 +155,13 @@ private:
std::vector<char*> exe_cmd_init<char>::make_cmd()
{
// any string must be writable.
static char empty_string[1] = "";
std::vector<char*> vec;
if (!exe.empty())
vec.push_back(exe.empty() ? empty_string : &exe.front());
vec.push_back(&exe.front());
if (!args.empty()) {
for (auto & v : args)
vec.push_back(v.empty() ? empty_string : &v.front());
vec.push_back(&v.front());
}
vec.push_back(nullptr);

View File

@@ -7,11 +7,8 @@
#ifndef BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_
#define BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/consign.hpp>
#include <boost/asio/append.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/asio/strand.hpp>
#include <boost/optional.hpp>
@@ -29,43 +26,6 @@ class sigchld_service : public boost::asio::detail::service_base<sigchld_service
std::list<std::pair<::pid_t, std::function<void(int, std::error_code)>>> _receivers;
inline void _handle_signal(const boost::system::error_code & ec);
struct initiate_async_wait_op
{
sigchld_service * self;
template<typename Initiation>
void operator()(Initiation && init, ::pid_t pid)
{
// check if the child actually is running first
int status;
auto pid_res = ::waitpid(pid, &status, WNOHANG);
if (pid_res < 0)
{
auto ec = get_last_error();
boost::asio::post(
self->_strand,
asio::append(std::forward<Initiation>(init), pid_res, ec));
}
else if ((pid_res == pid) && (WIFEXITED(status) || WIFSIGNALED(status)))
boost::asio::post(
self->_strand,
boost::asio::append(std::forward<Initiation>(init), status, std::error_code{}));
else //still running
{
sigchld_service * self_ = self;
if (self->_receivers.empty())
self->_signal_set.async_wait(
boost::asio::bind_executor(
self->_strand,
[self_](const boost::system::error_code &ec, int)
{
self_->_handle_signal(ec);
}));
self->_receivers.emplace_back(pid, init);
}
}
};
public:
sigchld_service(boost::asio::io_context & io_context)
: boost::asio::detail::service_base<sigchld_service>(io_context)
@@ -77,10 +37,47 @@ public:
void (int, std::error_code))
async_wait(::pid_t pid, SignalHandler && handler)
{
return boost::asio::async_initiate<
SignalHandler,
void(int, std::error_code)>(
initiate_async_wait_op{this}, handler, pid);
boost::asio::async_completion<
SignalHandler, void(boost::system::error_code)> init{handler};
auto & h = init.completion_handler;
boost::asio::dispatch(
_strand,
[this, pid, h]
{
//check if the child actually is running first
int status;
auto pid_res = ::waitpid(pid, &status, WNOHANG);
if (pid_res < 0)
{
auto ec = get_last_error();
boost::asio::post(
_strand,
[pid_res, ec, h]
{
h(pid_res, ec);
});
}
else if ((pid_res == pid) && (WIFEXITED(status) || WIFSIGNALED(status)))
boost::asio::post(
_strand,
[status, h]
{
h(status, {}); //successfully exited already
});
else //still running
{
if (_receivers.empty())
_signal_set.async_wait(
[this](const boost::system::error_code &ec, int)
{
boost::asio::dispatch(_strand, [this, ec]{this->_handle_signal(ec);});
});
_receivers.emplace_back(pid, h);
}
});
return init.result.get();
}
void shutdown() override
{

View File

@@ -488,7 +488,7 @@ struct key
using string_type = std::basic_string<char_type, traits_type>;
using string_view_type = basic_string_view<char_type, traits_type>;
key() {}
key() noexcept = default;
key( const key& p ) = default;
key( key&& p ) noexcept = default;
key( const string_type& source ) : value_(source) {}
@@ -524,11 +524,7 @@ struct key
~key() = default;
key& operator=( const key& p ) = default;
key& operator=( key&& p )
{
value_ = std::move(p.value_);
return *this;
}
key& operator=( key&& p ) noexcept(std::is_nothrow_move_constructible<string_type>::value) = default;
key& operator=( string_type&& source )
{
value_ = std::move(source);
@@ -712,7 +708,7 @@ struct value
using string_type = std::basic_string<char_type, traits_type>;
using string_view_type = basic_cstring_ref<char_type, traits_type>;
value() {}
value() noexcept = default;
value( const value& p ) = default;
value( const string_type& source ) : value_(source) {}
@@ -746,11 +742,7 @@ struct value
~value() = default;
value& operator=( const value& p ) = default;
value& operator=( value&& p )
{
value_ = std::move(p.value_);
return *this;
}
value& operator=( value&& p ) noexcept(std::is_nothrow_move_constructible<string_type>::value) = default;
value& operator=( string_type&& source )
{
value_ = std::move(source);
@@ -943,7 +935,7 @@ struct key_value_pair
using string_type = std::basic_string<char_type>;
using string_view_type = basic_cstring_ref<char_type>;
key_value_pair() {}
key_value_pair() noexcept = default;
key_value_pair( const key_value_pair& p ) = default;
key_value_pair( key_value_pair&& p ) noexcept = default;
key_value_pair(key_view key, value_view value) : value_(key.basic_string<char_type, traits_type>() + equality_sign +
@@ -1007,11 +999,7 @@ struct key_value_pair
~key_value_pair() = default;
key_value_pair& operator=( const key_value_pair& p ) = default;
key_value_pair& operator=( key_value_pair&& p )
{
value_ = std::move(p.value_);
return *this;
}
key_value_pair& operator=( key_value_pair&& p ) noexcept(std::is_nothrow_move_constructible<string_type>::value) = default;
key_value_pair& operator=( string_type&& source )
{
value_ = std::move(source);

View File

@@ -147,14 +147,15 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
std::vector<pid_type> all_pids(boost::system::error_code & ec)
{
std::vector<pid_type> vec;
vec.resize(proc_listpids(PROC_ALL_PIDS, 0, nullptr, 0) / sizeof(pid_type));
const auto sz = proc_listpids(PROC_ALL_PIDS, 0, &vec[0], sizeof(pid_type) * vec.size());
if (sz < 0)
vec.reserve(proc_listpids(PROC_ALL_PIDS, 0, nullptr, 0));
if (proc_listpids(PROC_ALL_PIDS, 0, &vec[0], sizeof(pid_type) * vec.size()))
{
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
return {};
}
vec.resize(sz);
auto itr = std::partition(vec.begin(), vec.end(), [](pid_type pt) {return pt != 0;});
vec.erase(itr, vec.end());
std::reverse(vec.begin(), vec.end());
return vec;
}
@@ -175,14 +176,15 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
{
std::vector<pid_type> vec;
vec.resize(proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, nullptr, 0) / sizeof(pid_type));
const auto sz = proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, &vec[0], sizeof(pid_type) * vec.size());
if (sz < 0)
vec.reserve(proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, nullptr, 0));
if (proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, &vec[0], sizeof(pid_type) * vec.size()))
{
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
return {};
}
vec.resize(sz);
auto itr = std::partition(vec.begin(), vec.end(), [](pid_type pt) {return pt != 0;});
vec.erase(itr, vec.end());
std::reverse(vec.begin(), vec.end());
return vec;
}

View File

@@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(multithreaded_async_pipe)
asio::io_context ioc;
std::vector<std::thread> threads;
for (auto i = 0u; i < std::thread::hardware_concurrency(); i++)
for (int i = 0; i < std::thread::hardware_concurrency(); i++)
{
threads.emplace_back([&ioc]
{

View File

@@ -83,24 +83,3 @@ BOOST_AUTO_TEST_CASE(implicit)
BOOST_TEST_MESSAGE(ec.message());
BOOST_CHECK_EQUAL(ret, 21);
}
BOOST_AUTO_TEST_CASE(empty_cmd)
{
using boost::unit_test::framework::master_test_suite;
std::error_code ec;
fs::path pth = master_test_suite().argv[1];
auto env = boost::this_process::environment();
auto itr = std::find_if(env.begin(), env.end(),
[](const bp::native_environment::entry_type & e){return boost::to_upper_copy(e.get_name()) == "PATH";});
BOOST_REQUIRE(itr != env.end());
(*itr) += fs::canonical(fs::absolute(pth.parent_path())).string();
BOOST_REQUIRE(itr != env.end());
bp::system("sparring_partner \"\" ", ec);
}

View File

@@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(wait_group_test, *boost::unit_test::timeout(5))
BOOST_CHECK_MESSAGE(!ec, ec.message());
BOOST_REQUIRE(c2.in_group(ec));
BOOST_CHECK_MESSAGE(!ec, ec.message());
g.wait(ec);
g.wait();
BOOST_CHECK(!c1.running());
BOOST_CHECK(!c2.running());

View File

@@ -59,11 +59,11 @@ test-suite standalone :
[ run utf8.cpp test_impl ]
[ run cstring_ref.cpp test_impl ]
[ run environment.cpp test_impl ]
[ run pid.cpp test_impl : : : <target-os>darwin:<build>no ]
[ run shell.cpp test_impl ]
;
test-suite with_target :
[ run pid.cpp test_impl : --log_level=all --catch_system_errors=no -- : target ]
[ run process.cpp test_impl : --log_level=all --catch_system_errors=no -- : target ]
[ run windows.cpp test_impl : --log_level=all --catch_system_errors=no -- : target : <build>no <target-os>windows:<build>yes <target-os>windows:<source>Advapi32 ]
[ run ext.cpp test_impl : --log_level=all --catch_system_errors=no -- : target : <target-os>darwin:<build>no ]

View File

@@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(cmd_exe)
BOOST_CHECK_EQUAL(bp2::detail::conv_string<char>(ref.data(), ref.size()), pth);
BOOST_REQUIRE_EQUAL(cm.argc(), args.size() + 1);
for (auto i = 0u; i < args.size(); i++)
for (auto i = 0; i < args.size(); i++)
{
ref = cm.argv()[i + 1];

View File

@@ -5,12 +5,10 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/process/v2/pid.hpp>
#include <boost/process/v2/process.hpp>
#include <boost/test/unit_test.hpp>
#include <algorithm>
#include <thread>
#include <vector>
BOOST_AUTO_TEST_CASE(test_pid)
@@ -24,30 +22,21 @@ BOOST_AUTO_TEST_CASE(test_pid)
BOOST_CHECK_GT(all.size(), 0u);
BOOST_CHECK(itr != all.end());
std::vector<bp2::pid_type> children, grand_children;
auto grand_child_pids = [](bp2::pid_type pid,
std::vector<bp2::pid_type> & children,
std::vector<bp2::pid_type> & grand_children)
{
children = bp2::child_pids(pid);
for (unsigned i = 0; i < children.size(); i++)
{
std::vector<bp2::pid_type> tmp1;
std::vector<bp2::pid_type> tmp2 = bp2::child_pids(children[i]);
tmp1.insert(std::end(tmp1), std::begin(tmp2), std::end(tmp2));
grand_children = tmp1;
}
return (!children.empty() || !grand_children.empty());
};
BOOST_CHECK_NE(grand_child_pids(bp2::root_pid, children, grand_children), false);
}
BOOST_AUTO_TEST_CASE(child_pid)
{
namespace bp2 = boost::process::v2;
using boost::unit_test::framework::master_test_suite;
const auto pth = bp2::filesystem::absolute(master_test_suite().argv[1]);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
auto cs = bp2::child_pids(bp2::current_pid());
boost::asio::io_context ctx;
bp2::process proc(ctx, pth, {"sleep", "50000"});
std::this_thread::sleep_for(std::chrono::milliseconds(20));
auto c2 = bp2::child_pids(bp2::current_pid());
BOOST_CHECK_LT(cs.size(), c2.size());
BOOST_CHECK(std::find(cs.begin(), cs.end(), proc.id()) == cs.end());
BOOST_CHECK(std::find(c2.begin(), c2.end(), proc.id()) != c2.end());
proc.terminate();
proc.wait();
auto c3 = bp2::child_pids(bp2::current_pid());
BOOST_CHECK(std::find(c3.begin(), c3.end(), proc.id()) == c3.end());
BOOST_CHECK_LT(c3.size(), c2.size());
}