mirror of
https://github.com/boostorg/process.git
synced 2026-01-19 04:22:15 +00:00
xproc fixes
This commit is contained in:
committed by
Klemens Morgenstern
parent
f1302430cb
commit
9d51e1cd32
@@ -8,4 +8,6 @@ A special thank you goes to [@http://www.intra2net.com/ Intra2net AG] (especiall
|
||||
|
||||
Great thanks also goes to Boris Schaeling, who despite having boost.process rejected, went on to work on it and maintained it up until this day and participated in the development of the current version.
|
||||
|
||||
Many Thanks, to [@https://github.com/time-killer-games Samuel Venable] for contributing the v2::ext functionality and all the research that went into it.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -263,7 +263,7 @@ public:
|
||||
auto st1 = key + ::boost::process::detail::equal_sign<Char>();
|
||||
while (*p != nullptr)
|
||||
{
|
||||
const auto len = std::char_traits<Char>::length(*p);
|
||||
const int len = std::char_traits<Char>::length(*p);
|
||||
if ((std::distance(st1.begin(), st1.end()) < len)
|
||||
&& std::equal(st1.begin(), st1.end(), *p))
|
||||
break;
|
||||
|
||||
@@ -101,9 +101,8 @@ struct basic_process_handle_signal
|
||||
handle.pid_ = -1;
|
||||
}
|
||||
|
||||
pid_type id() const
|
||||
{ return pid_; }
|
||||
native_handle_type native_handle() {return pid_;}
|
||||
pid_type id() const { return pid_; }
|
||||
native_handle_type native_handle() {return {};}
|
||||
|
||||
void terminate_if_running(error_code &)
|
||||
{
|
||||
|
||||
16
include/boost/process/v2/ext.hpp
Normal file
16
include/boost/process/v2/ext.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Copyright (c) 2023 Klemens Morgenstern (klemens.morgenstern@gmx.net)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_PROCESS_V2_EXT_HPP
|
||||
#define BOOST_PROCESS_V2_EXT_HPP
|
||||
|
||||
#include <boost/process/v2/ext/cmd.hpp>
|
||||
#include <boost/process/v2/ext/cwd.hpp>
|
||||
#include <boost/process/v2/ext/env.hpp>
|
||||
#include <boost/process/v2/ext/exe.hpp>
|
||||
|
||||
#endif //BOOST_PROCESS_V2_EXT_HPP
|
||||
@@ -20,7 +20,8 @@ BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace ext {
|
||||
|
||||
/// Get the argument vector from a given pid
|
||||
/// @{
|
||||
/// Get the argument vector of another process
|
||||
BOOST_PROCESS_V2_DECL shell cmd(pid_type pid, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL shell cmd(pid_type pid);
|
||||
|
||||
@@ -32,15 +33,25 @@ BOOST_PROCESS_V2_DECL shell cmd(HANDLE handle);
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL shell cmd(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return cmd(handle.native_handle(), ec);
|
||||
#else
|
||||
return cmd(handle.id(), ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL shell cmd(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return cmd(handle.native_handle());
|
||||
#else
|
||||
return cmd(handle.id());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
} // namespace ext
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
@@ -15,26 +15,38 @@ BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace ext {
|
||||
|
||||
/// Obtain the current path of a process
|
||||
/// @{
|
||||
/// Obtain the current path of another process
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(pid_type pid, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(pid_type pid);
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return cwd(handle.native_handle(), ec);
|
||||
#else
|
||||
return cwd(handle.id(), ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return cwd(handle.native_handle());
|
||||
#else
|
||||
return cwd(handle.id());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(HANDLE handle, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(HANDLE handle);
|
||||
#endif
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
return cwd(handle.native_handle(), ec);
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL filesystem::path cwd(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
return cwd(handle.native_handle());
|
||||
}
|
||||
|
||||
} // namespace ext
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ namespace ext
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
using native_env_handle_type = wchar_t *;
|
||||
using native_env_iterator = wchar_t *;
|
||||
#elif defined(__FreeBSD__)
|
||||
using native_env_handle_type = char **;
|
||||
using native_env_iterator = char **;
|
||||
#else
|
||||
using native_env_handle_type = char *;
|
||||
using native_env_iterator = char *;
|
||||
@@ -45,6 +48,7 @@ BOOST_PROCESS_V2_DECL const environment::char_type * dereference(native_env_iter
|
||||
|
||||
namespace ext {
|
||||
|
||||
/// The view of an environment
|
||||
struct env_view
|
||||
{
|
||||
using native_handle_type = detail::ext::native_env_handle_type;
|
||||
@@ -105,26 +109,38 @@ struct env_view
|
||||
detail::ext::native_env_handle_deleter> handle_;
|
||||
};
|
||||
|
||||
/// Get the argument vector from a given pid
|
||||
/// @{
|
||||
/// Get the environment of another process.
|
||||
BOOST_PROCESS_V2_DECL env_view env(pid_type pid, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL env_view env(pid_type pid);
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return env(handle.native_handle(), ec);
|
||||
#else
|
||||
return env(handle.id(), ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return env(handle.native_handle());
|
||||
#else
|
||||
return env(handle.id());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
BOOST_PROCESS_V2_DECL env_view env(HANDLE handle, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL env_view env(HANDLE handle);
|
||||
#endif
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
return env(handle.native_handle(), ec);
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
return env(handle.native_handle());
|
||||
}
|
||||
|
||||
} // namespace ext
|
||||
|
||||
|
||||
@@ -16,27 +16,40 @@ BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace ext {
|
||||
|
||||
/// Return the executable path from pid
|
||||
/// @{
|
||||
/// Return the executable of another process by pid or handle.
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(pid_type pid, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(pid_type pid);
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(HANDLE handle, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(HANDLE handle);
|
||||
#endif
|
||||
|
||||
|
||||
template<typename Executor>
|
||||
filesystem::path exe(basic_process_handle<Executor> & handle, error_code & ec)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return exe(handle.native_handle(), ec);
|
||||
#else
|
||||
return exe(handle.id(), ec);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
filesystem::path exe(basic_process_handle<Executor> & handle)
|
||||
{
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
return exe(handle.native_handle());
|
||||
#else
|
||||
return exe(handle.id());
|
||||
#endif
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(HANDLE handle, error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL filesystem::path exe(HANDLE handle);
|
||||
#endif
|
||||
|
||||
} // namespace ext
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
@@ -92,13 +92,12 @@ struct make_cmd_shell_
|
||||
str_lengths += (std::strlen(*c) + 1);
|
||||
}
|
||||
// yes, not the greatest solution.
|
||||
std::string buffer;
|
||||
res.buffer_.resize(str_lengths);
|
||||
|
||||
res.argv_ = new char*[res.argc_ + 1];
|
||||
res.free_argv_ = +[](int argc, char ** argv) {delete[] argv;};
|
||||
res.argv_[res.argc_] = nullptr;
|
||||
auto p = &buffer[sizeof(int) * (res.argc_) + 1];
|
||||
auto p = &*res.buffer_.begin();
|
||||
|
||||
for (int i = 0; i < res.argc_; i++)
|
||||
{
|
||||
@@ -179,7 +178,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
return {};
|
||||
}
|
||||
|
||||
int argc = *reinterpret_cast<int*>(procargs.data());
|
||||
int argc = *reinterpret_cast<const int*>(procargs.data());
|
||||
auto itr = procargs.begin() + sizeof(argc);
|
||||
|
||||
std::unique_ptr<char*[]> argv{new char*[argc + 1]};
|
||||
@@ -305,16 +304,9 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
ec = detail::get_last_error();
|
||||
return {};
|
||||
}
|
||||
struct free_argv
|
||||
{
|
||||
struct procstat * proc_stat;
|
||||
~free_argv()
|
||||
{
|
||||
procstat_freeargv(proc_stat);
|
||||
}
|
||||
};
|
||||
|
||||
return make_cmd_shell_::clone(cmd);
|
||||
auto res = make_cmd_shell_::clone(cmd);
|
||||
procstat_freeargv(proc_stat.get());
|
||||
return res;
|
||||
}
|
||||
|
||||
#elif defined(__DragonFly__)
|
||||
|
||||
@@ -101,10 +101,10 @@ filesystem::path cwd(HANDLE proc)
|
||||
filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
proc_vnodepathinfo vpi;
|
||||
if (proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)) > 0) {
|
||||
if (proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)) > 0)
|
||||
return filesystem::canonical(vpi.pvi_cdir.vip_path, ec);
|
||||
}
|
||||
ec = detail::get_last_error();
|
||||
else
|
||||
ec = detail::get_last_error();
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ const environment::char_type * dereference(native_env_iterator iterator)
|
||||
return iterator;
|
||||
}
|
||||
|
||||
#else
|
||||
#elif (defined(__APPLE___) || defined(__MACH__))
|
||||
|
||||
void native_env_handle_deleter::operator()(native_env_handle_type h) const
|
||||
{
|
||||
@@ -97,6 +97,36 @@ native_env_iterator find_end(native_env_iterator nh)
|
||||
return nh ;
|
||||
}
|
||||
|
||||
const environment::char_type * dereference(native_env_iterator iterator)
|
||||
{
|
||||
return iterator;
|
||||
}
|
||||
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
void native_env_handle_deleter::operator()(native_env_handle_type h) const
|
||||
{
|
||||
delete [] h;
|
||||
}
|
||||
|
||||
native_env_iterator next(native_env_iterator nh)
|
||||
{
|
||||
return ++nh ;
|
||||
}
|
||||
native_env_iterator find_end(native_env_iterator nh)
|
||||
{
|
||||
while (*nh != nullptr)
|
||||
nh++;
|
||||
|
||||
return nh ;
|
||||
}
|
||||
|
||||
const environment::char_type * dereference(native_env_iterator iterator)
|
||||
{
|
||||
return *iterator;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -206,34 +236,35 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
ec = detail::get_last_error();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::uint32_t nargs;
|
||||
memcpy(&nargs, &*procargs.begin(), sizeof(nargs));
|
||||
char *cp = &*procargs.begin() + sizeof(nargs);
|
||||
|
||||
for (; cp < &&*procargs.begin()[size]; cp++) {
|
||||
if (*cp == '\0') break;
|
||||
}
|
||||
for (; cp < &*procargs.end(); cp++)
|
||||
if (*cp == '\0')
|
||||
break;
|
||||
|
||||
if (cp == &procargs[s]) {
|
||||
|
||||
if (cp == &procargs[size])
|
||||
return {};
|
||||
}
|
||||
|
||||
for (; cp < &&*procargs.begin()[size]; cp++) {
|
||||
|
||||
for (; cp < &*procargs.end(); cp++)
|
||||
if (*cp != '\0') break;
|
||||
}
|
||||
|
||||
if (cp == &&*procargs.begin()[size]) {
|
||||
|
||||
if (cp == &*procargs.end())
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
int i = 0;
|
||||
char *sp = cp;
|
||||
std::vector<char> vec;
|
||||
|
||||
while ((*sp != '\0' || i < nargs) && sp < &&*procargs.begin()[size]) {
|
||||
if (i >= nargs) {
|
||||
while ((*sp != '\0' || i < nargs) && sp < &*procargs.end()) {
|
||||
if (i >= nargs)
|
||||
vec.push_back(*sp);
|
||||
}
|
||||
|
||||
sp += 1;
|
||||
}
|
||||
|
||||
@@ -279,6 +310,69 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
return ev;
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
env_view ev;
|
||||
|
||||
unsigned cntp = 0;
|
||||
procstat *proc_stat = procstat_open_sysctl();
|
||||
if (proc_stat != nullptr)
|
||||
{
|
||||
kinfo_proc *proc_info = procstat_getprocs(proc_stat, KERN_PROC_PID, pid, &cntp);
|
||||
if (proc_info != nullptr)
|
||||
{
|
||||
char **env = procstat_getenvv(proc_stat, proc_info, 0);
|
||||
if (env != nullptr)
|
||||
{
|
||||
auto e = env;
|
||||
std::size_t n = 0u, len = 0u;
|
||||
while (e && *e != nullptr)
|
||||
{
|
||||
n ++;
|
||||
len += std::strlen(*e);
|
||||
e++;
|
||||
}
|
||||
std::size_t mem_needed =
|
||||
// environ - nullptr - strlen + null terminators
|
||||
(n * sizeof(char*)) + sizeof(char*) + len + n;
|
||||
|
||||
char * out = new (std::nothrow) char[mem_needed];
|
||||
if (out != nullptr)
|
||||
{
|
||||
auto eno = reinterpret_cast<char**>(out);
|
||||
auto eeo = eno;
|
||||
auto str = out + (n * sizeof(char*)) + sizeof(char*);
|
||||
e = env;
|
||||
while (*e != nullptr)
|
||||
{
|
||||
auto len = std::strlen(*e) + 1u;
|
||||
std::memcpy(str, *e, len);
|
||||
*eno = str;
|
||||
str += len;
|
||||
eno ++;
|
||||
e++;
|
||||
}
|
||||
*eno = nullptr;
|
||||
|
||||
ev.handle_.reset(eeo);
|
||||
}
|
||||
else
|
||||
ec = detail::get_last_error();
|
||||
|
||||
}
|
||||
procstat_freeprocs(proc_stat, proc_info);
|
||||
|
||||
}
|
||||
else
|
||||
ec = detail::get_last_error();
|
||||
procstat_close(proc_stat);
|
||||
}
|
||||
else
|
||||
ec = detail::get_last_error();
|
||||
return ev;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
env_view env(boost::process::v2::pid_type pid)
|
||||
|
||||
@@ -154,7 +154,8 @@ filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code
|
||||
strbuff.resize(len);
|
||||
if (sysctl(mib, 4, &strbuff[0], &len, nullptr, 0) == 0)
|
||||
{
|
||||
return filesystem::canonical(strbuff, ec);
|
||||
strbuff.resize(len - 1);
|
||||
return filesystem::canonical(strbuff, ec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
std::vector<pid_type> vec;
|
||||
vec.reserve(proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, nullptr, 0));
|
||||
if (proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, &proc_info[0], sizeof(pid_type) * cntp))
|
||||
if (proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, &vec[0], sizeof(pid_type) * vec.size()))
|
||||
{
|
||||
ec = detail::get_last_error();
|
||||
return {};
|
||||
|
||||
@@ -111,7 +111,7 @@ void shell::parse_()
|
||||
|
||||
shell::~shell()
|
||||
{
|
||||
if (argv_ != nullptr && free_argv_)
|
||||
if (argv_ != nullptr && free_argv_ != nullptr)
|
||||
free_argv_(argc_, argv_);
|
||||
}
|
||||
|
||||
|
||||
@@ -215,13 +215,13 @@ struct basic_process
|
||||
process_handle_.request_exit(ec);
|
||||
}
|
||||
|
||||
/// Send the process a signal requesting it to stop. This may rely on undocmented functions.
|
||||
/// Send the process a signal requesting it to stop. This may rely on undocumented functions.
|
||||
void suspend(error_code &ec)
|
||||
{
|
||||
process_handle_.suspend(ec);
|
||||
}
|
||||
|
||||
/// Send the process a signal requesting it to stop. This may rely on undocmented functions.
|
||||
/// Send the process a signal requesting it to stop. This may rely on undocumented functions.
|
||||
void suspend()
|
||||
{
|
||||
error_code ec;
|
||||
@@ -231,13 +231,13 @@ struct basic_process
|
||||
}
|
||||
|
||||
|
||||
/// Send the process a signal requesting it to resume. This may rely on undocmented functions.
|
||||
/// Send the process a signal requesting it to resume. This may rely on undocumented functions.
|
||||
void resume(error_code &ec)
|
||||
{
|
||||
process_handle_.resume(ec);
|
||||
}
|
||||
|
||||
/// Send the process a signal requesting it to resume. This may rely on undocmented functions.
|
||||
/// Send the process a signal requesting it to resume. This may rely on undocumented functions.
|
||||
void resume()
|
||||
{
|
||||
error_code ec;
|
||||
|
||||
@@ -59,13 +59,13 @@ test-suite standalone :
|
||||
[ run utf8.cpp test_impl ]
|
||||
[ run cstring_ref.cpp test_impl ]
|
||||
[ run environment.cpp test_impl ]
|
||||
[ run pid.cpp test_impl ]
|
||||
[ run pid.cpp test_impl : : : <target-os>darwin:<build>no ]
|
||||
[ run shell.cpp test_impl ]
|
||||
;
|
||||
|
||||
test-suite with_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 ]
|
||||
[ run ext.cpp test_impl : --log_level=all --catch_system_errors=no -- : target : <target-os>darwin:<build>no ]
|
||||
;
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ BOOST_AUTO_TEST_CASE(test_exe)
|
||||
namespace bp2 = boost::process::v2;
|
||||
auto pth = bp2::ext::exe(bp2::current_pid());
|
||||
BOOST_CHECK(!pth.empty());
|
||||
BOOST_CHECK_EQUAL(master_test_suite().argv[0], pth.string());
|
||||
BOOST_CHECK_EQUAL(bp2::filesystem::canonical(master_test_suite().argv[0]).string(),
|
||||
bp2::filesystem::canonical(pth).string());
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +31,7 @@ BOOST_AUTO_TEST_CASE(test_child_exe)
|
||||
{
|
||||
namespace bp2 = boost::process::v2;
|
||||
using boost::unit_test::framework::master_test_suite;
|
||||
const auto pth = bp2::filesystem::canonical(master_test_suite().argv[1]);
|
||||
const auto pth = bp2::filesystem::canonical(master_test_suite().argv[0]);
|
||||
|
||||
boost::asio::io_context ctx;
|
||||
bp2::process proc(ctx, pth, {"sleep", "10000"});
|
||||
@@ -66,7 +67,7 @@ BOOST_AUTO_TEST_CASE(cmd)
|
||||
BOOST_AUTO_TEST_CASE(cmd_exe)
|
||||
{
|
||||
using boost::unit_test::framework::master_test_suite;
|
||||
const auto pth = master_test_suite().argv[1];
|
||||
const auto pth = master_test_suite().argv[0];
|
||||
|
||||
namespace bp2 = boost::process::v2;
|
||||
|
||||
@@ -101,8 +102,8 @@ BOOST_AUTO_TEST_CASE(test_cwd)
|
||||
BOOST_AUTO_TEST_CASE(test_cwd_exe)
|
||||
{
|
||||
using boost::unit_test::framework::master_test_suite;
|
||||
const auto pth = master_test_suite().argv[1];
|
||||
namespace bp2 = boost::process::v2;
|
||||
const auto pth = bp2::filesystem::absolute(master_test_suite().argv[0]);
|
||||
|
||||
auto tmp = bp2::filesystem::temp_directory_path();
|
||||
|
||||
@@ -122,6 +123,7 @@ BOOST_AUTO_TEST_CASE(test_env)
|
||||
namespace bp2 = boost::process::v2;
|
||||
auto env = bp2::ext::env(bp2::current_pid());
|
||||
|
||||
std::size_t e = 0;
|
||||
|
||||
for (const auto & kp : bp2::environment::current())
|
||||
{
|
||||
@@ -130,15 +132,20 @@ BOOST_AUTO_TEST_CASE(test_env)
|
||||
{
|
||||
return kp.key() == kp_.key();
|
||||
});
|
||||
BOOST_REQUIRE(itr != env.end());
|
||||
BOOST_CHECK_EQUAL(kp.value(), (*itr).value());
|
||||
if (itr != env.end())
|
||||
{
|
||||
BOOST_CHECK_EQUAL(kp.value(), (*itr).value());
|
||||
e++;
|
||||
}
|
||||
|
||||
}
|
||||
BOOST_CHECK_GT(e, 0u);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_env_exe)
|
||||
{
|
||||
using boost::unit_test::framework::master_test_suite;
|
||||
const auto pth = master_test_suite().argv[1];
|
||||
const auto pth = master_test_suite().argv[0];
|
||||
namespace bp2 = boost::process::v2;
|
||||
|
||||
auto tmp = bp2::filesystem::temp_directory_path();
|
||||
|
||||
@@ -18,6 +18,9 @@ BOOST_AUTO_TEST_CASE(test_pid)
|
||||
|
||||
auto all = bp2::all_pids();
|
||||
auto itr = std::find(all.begin(), all.end(), bp2::current_pid());
|
||||
|
||||
#if !defined(__APPLE___) && !defined(__MACH__)
|
||||
BOOST_CHECK_GT(all.size(), 0u);
|
||||
BOOST_CHECK(itr != all.end());
|
||||
|
||||
std::vector<bp2::pid_type> children, grand_children;
|
||||
@@ -36,4 +39,6 @@ BOOST_AUTO_TEST_CASE(test_pid)
|
||||
return (!children.empty() || !grand_children.empty());
|
||||
};
|
||||
BOOST_CHECK_NE(grand_child_pids(bp2::root_pid, children, grand_children), false);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -221,6 +221,8 @@ BOOST_AUTO_TEST_CASE(print_args_out)
|
||||
bpv::error_code ec;
|
||||
|
||||
auto sz = asio::read(rp, st, ec);
|
||||
while (ec == asio::error::interrupted)
|
||||
sz += asio::read(rp, st, ec);
|
||||
|
||||
BOOST_CHECK_NE(sz, 0u);
|
||||
BOOST_CHECK_MESSAGE((ec == asio::error::broken_pipe) || (ec == asio::error::eof), ec.message());
|
||||
@@ -267,6 +269,8 @@ BOOST_AUTO_TEST_CASE(print_args_err)
|
||||
bpv::error_code ec;
|
||||
|
||||
auto sz = asio::read(rp, st, ec);
|
||||
while (ec == asio::error::interrupted)
|
||||
sz += asio::read(rp, st, ec);
|
||||
|
||||
BOOST_CHECK_NE(sz , 0u);
|
||||
BOOST_CHECK_MESSAGE((ec == asio::error::broken_pipe) || (ec == asio::error::eof), ec.message());
|
||||
@@ -320,6 +324,9 @@ BOOST_AUTO_TEST_CASE(echo_file)
|
||||
bpv::error_code ec;
|
||||
|
||||
auto sz = asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
while (ec == asio::error::interrupted)
|
||||
sz += asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
|
||||
BOOST_CHECK(sz != 0);
|
||||
BOOST_CHECK_MESSAGE((ec == asio::error::broken_pipe) || (ec == asio::error::eof), ec.message());
|
||||
BOOST_CHECK_MESSAGE(out == test_data, out);
|
||||
@@ -344,6 +351,9 @@ BOOST_AUTO_TEST_CASE(print_same_cwd)
|
||||
bpv::error_code ec;
|
||||
|
||||
auto sz = asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
while (ec == asio::error::interrupted)
|
||||
sz += asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
|
||||
BOOST_CHECK(sz != 0);
|
||||
BOOST_CHECK_MESSAGE((ec == asio::error::broken_pipe) || (ec == asio::error::eof), ec.message());
|
||||
BOOST_CHECK_MESSAGE(bpv::filesystem::path(out) == bpv::filesystem::current_path(),
|
||||
@@ -373,6 +383,9 @@ BOOST_AUTO_TEST_CASE(popen)
|
||||
std::string res;
|
||||
boost::system::error_code ec;
|
||||
std::size_t n = asio::read(proc, asio::dynamic_buffer(res), ec);
|
||||
while (ec == asio::error::interrupted)
|
||||
n += asio::read(rp, asio::dynamic_buffer(res), ec);
|
||||
|
||||
BOOST_CHECK_MESSAGE(ec == asio::error::eof || ec == asio::error::broken_pipe, ec.message());
|
||||
BOOST_REQUIRE_GE(n, 1u);
|
||||
// remove EOF
|
||||
@@ -406,6 +419,9 @@ BOOST_AUTO_TEST_CASE(print_other_cwd)
|
||||
bpv::error_code ec;
|
||||
|
||||
auto sz = asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
while (ec == asio::error::interrupted)
|
||||
sz += asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
|
||||
BOOST_CHECK(sz != 0);
|
||||
BOOST_CHECK_MESSAGE((ec == asio::error::broken_pipe) || (ec == asio::error::eof), ec.message());
|
||||
BOOST_CHECK_MESSAGE(bpv::filesystem::path(out) == target,
|
||||
@@ -436,7 +452,7 @@ std::string read_env(const char * name, Inits && ... inits)
|
||||
std::string out;
|
||||
bpv::error_code ec;
|
||||
|
||||
auto sz = asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
auto sz = asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
while (ec == asio::error::interrupted)
|
||||
sz += asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
|
||||
@@ -534,6 +550,7 @@ BOOST_AUTO_TEST_CASE(bind_launcher)
|
||||
auto sz = asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
while (ec == asio::error::interrupted)
|
||||
sz += asio::read(rp, asio::dynamic_buffer(out), ec);
|
||||
|
||||
BOOST_CHECK(sz != 0);
|
||||
BOOST_CHECK_MESSAGE((ec == asio::error::broken_pipe) || (ec == asio::error::eof), ec.message());
|
||||
BOOST_CHECK_MESSAGE(bpv::filesystem::path(out) == target,
|
||||
|
||||
Reference in New Issue
Block a user