mirror of
https://github.com/boostorg/process.git
synced 2026-01-20 04:42:24 +00:00
Compare commits
4 Commits
v2_handles
...
boost-1.87
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa83c2f9ff | ||
|
|
9925e82a5f | ||
|
|
7f03295c93 | ||
|
|
64c4cdac83 |
@@ -140,10 +140,7 @@ struct limit_handles_ : handler_base_ext
|
||||
auto itr = std::find(all_handles.begin(), all_handles .end(), handle);
|
||||
::boost::winapi::DWORD_ flags = 0u;
|
||||
if (itr != all_handles.end())
|
||||
*itr = ::boost::winapi::INVALID_HANDLE_VALUE_;
|
||||
else if ((::boost::winapi::GetHandleInformation(*itr, &flags) != 0)
|
||||
&&((flags & ::boost::winapi::HANDLE_FLAG_INHERIT_) == 0)) //it is NOT inherited anyhow, so ignore too
|
||||
*itr = ::boost::winapi::INVALID_HANDLE_VALUE_;
|
||||
*itr = ::boost::winapi::INVALID_HANDLE_VALUE_; // the handle is used mark it as invalid, so it doesn't get reset
|
||||
});
|
||||
|
||||
auto part_itr = std::partition(all_handles.begin(), all_handles.end(),
|
||||
|
||||
@@ -308,7 +308,7 @@ struct basic_process_handle_win
|
||||
public:
|
||||
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, native_exit_code_type))
|
||||
WaitHandler = net::default_completion_token_t<executor_type>>
|
||||
auto async_wait(WaitHandler &&handler = default_completion_token_t<executor_type>())
|
||||
auto async_wait(WaitHandler &&handler = net::default_completion_token_t<executor_type>())
|
||||
-> decltype(net::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
|
||||
async_wait_op_{handle_}, handler, handle_))
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun)
|
||||
extern "C" { extern char **environ; }
|
||||
#endif
|
||||
|
||||
|
||||
@@ -303,14 +303,12 @@ struct process_stdio
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
error_code on_setup(windows::default_launcher & launcher, const filesystem::path &, const std::wstring &)
|
||||
{
|
||||
|
||||
launcher.startup_info.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||
launcher.startup_info.StartupInfo.hStdInput = in.prepare();
|
||||
launcher.startup_info.StartupInfo.hStdOutput = out.prepare();
|
||||
launcher.startup_info.StartupInfo.hStdError = err.prepare();
|
||||
launcher.inherited_handles.reserve(launcher.inherited_handles.size() + 3);
|
||||
launcher.inherited_handles.push_back(launcher.startup_info.StartupInfo.hStdInput);
|
||||
launcher.inherited_handles.push_back(launcher.startup_info.StartupInfo.hStdOutput);
|
||||
launcher.inherited_handles.push_back(launcher.startup_info.StartupInfo.hStdError);
|
||||
launcher.inherit_handles = true;
|
||||
return error_code {};
|
||||
};
|
||||
#else
|
||||
|
||||
@@ -91,21 +91,13 @@ struct as_user_launcher : default_launcher
|
||||
detail::on_error(*this, executable, command_line, ec, inits...);
|
||||
return basic_process<Executor>(exec);
|
||||
}
|
||||
|
||||
if (!inherited_handles.empty())
|
||||
{
|
||||
set_handle_list(ec);
|
||||
if (ec)
|
||||
return basic_process<Executor>(exec);
|
||||
}
|
||||
|
||||
auto ok = ::CreateProcessAsUserW(
|
||||
token,
|
||||
executable.empty() ? nullptr : executable.c_str(),
|
||||
command_line.empty() ? nullptr : &command_line.front(),
|
||||
process_attributes,
|
||||
thread_attributes,
|
||||
inherited_handles.empty() ? FALSE : TRUE,
|
||||
inherit_handles ? TRUE : FALSE,
|
||||
creation_flags,
|
||||
environment,
|
||||
current_directory.empty() ? nullptr : current_directory.c_str(),
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#include <boost/process/v2/error.hpp>
|
||||
|
||||
#include <numeric>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_STANDALONE)
|
||||
@@ -209,8 +207,8 @@ struct default_launcher
|
||||
SECURITY_ATTRIBUTES * process_attributes = nullptr;
|
||||
//// The thread_attributes passed to CreateProcess
|
||||
SECURITY_ATTRIBUTES * thread_attributes = nullptr;
|
||||
/// The inhreited_handles option. bInheritHandles will be true if not empty..
|
||||
std::vector<HANDLE> inherited_handles;
|
||||
/// The bInheritHandles option. Needs to be set to true by any initializers using handles.
|
||||
bool inherit_handles = false;
|
||||
/// The creation flags of the process. Initializers may add to them; extended startupinfo is assumed.
|
||||
DWORD creation_flags{EXTENDED_STARTUPINFO_PRESENT};
|
||||
/// A pointer to the subprocess environment.
|
||||
@@ -296,26 +294,18 @@ struct default_launcher
|
||||
auto command_line = this->build_command_line(executable, std::forward<Args>(args));
|
||||
|
||||
ec = detail::on_setup(*this, executable, command_line, inits...);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
detail::on_error(*this, executable, command_line, ec, inits...);
|
||||
return basic_process<Executor>(exec);
|
||||
}
|
||||
|
||||
if (!inherited_handles.empty())
|
||||
{
|
||||
set_handle_list(ec);
|
||||
if (ec)
|
||||
return basic_process<Executor>(exec);
|
||||
}
|
||||
|
||||
auto ok = ::CreateProcessW(
|
||||
executable.empty() ? nullptr : executable.c_str(),
|
||||
command_line.empty() ? nullptr : &command_line.front(),
|
||||
process_attributes,
|
||||
thread_attributes,
|
||||
inherited_handles.empty() ? FALSE : TRUE,
|
||||
inherit_handles ? TRUE : FALSE,
|
||||
creation_flags,
|
||||
environment,
|
||||
current_directory.empty() ? nullptr : current_directory.c_str(),
|
||||
@@ -413,18 +403,6 @@ struct default_launcher
|
||||
return args;
|
||||
}
|
||||
|
||||
struct lpproc_thread_closer
|
||||
{
|
||||
void operator()(::LPPROC_THREAD_ATTRIBUTE_LIST l)
|
||||
{
|
||||
::DeleteProcThreadAttributeList(l);
|
||||
::HeapFree(GetProcessHeap(), 0, l);
|
||||
}
|
||||
};
|
||||
std::unique_ptr<std::remove_pointer<LPPROC_THREAD_ATTRIBUTE_LIST>::type, lpproc_thread_closer> proc_attribute_list_storage;
|
||||
|
||||
BOOST_PROCESS_V2_DECL LPPROC_THREAD_ATTRIBUTE_LIST get_thread_attribute_list(error_code & ec);
|
||||
BOOST_PROCESS_V2_DECL void set_handle_list(error_code & ec);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -389,7 +389,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
argc++;
|
||||
return make_cmd_shell_::make(
|
||||
{}, argc, cmd,
|
||||
+[](int, char ** argv) {::free(argv);})
|
||||
+[](int, char ** argv) {::free(argv);});
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
|
||||
13
src/pid.cpp
13
src/pid.cpp
@@ -52,6 +52,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <kvm.h>
|
||||
#include <sys/param.h>
|
||||
@@ -710,9 +711,9 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
return vec;
|
||||
}
|
||||
while ((proc_info = kvm_nextproc(kd)))
|
||||
while ((proc_info = kvm_nextproc(kd.get())))
|
||||
{
|
||||
if (kvm_kread(kd, (std::uintptr_t)proc_info->p_pidp, &cur_pid, sizeof(cur_pid)) != -1)
|
||||
if (kvm_kread(kd.get(), (std::uintptr_t)proc_info->p_pidp, &cur_pid, sizeof(cur_pid)) != -1)
|
||||
{
|
||||
vec.insert(vec.begin(), cur_pid.pid_id);
|
||||
}
|
||||
@@ -744,7 +745,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
return ppid;
|
||||
}
|
||||
if ((proc_info = kvm_getproc(kd, pid)))
|
||||
if ((proc_info = kvm_getproc(kd.get(), pid)))
|
||||
{
|
||||
ppid = proc_info->p_ppid;
|
||||
}
|
||||
@@ -767,17 +768,17 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr);
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr)};
|
||||
if (!kd)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
return vec;
|
||||
}
|
||||
while ((proc_info = kvm_nextproc(kd)))
|
||||
while ((proc_info = kvm_nextproc(kd.get())))
|
||||
{
|
||||
if (proc_info->p_ppid == pid)
|
||||
{
|
||||
if (kvm_kread(kd, (std::uintptr_t)proc_info->p_pidp, &cur_pid, sizeof(cur_pid)) != -1)
|
||||
if (kvm_kread(kd.get(), (std::uintptr_t)proc_info->p_pidp, &cur_pid, sizeof(cur_pid)) != -1)
|
||||
{
|
||||
vec.insert(vec.begin(), cur_pid.pid_id);
|
||||
}
|
||||
|
||||
@@ -75,45 +75,6 @@ namespace windows
|
||||
return itr - begin;
|
||||
}
|
||||
|
||||
LPPROC_THREAD_ATTRIBUTE_LIST default_launcher::get_thread_attribute_list(error_code & ec)
|
||||
{
|
||||
if (startup_info.lpAttributeList != nullptr)
|
||||
return startup_info.lpAttributeList;
|
||||
SIZE_T size;
|
||||
if (!(::InitializeProcThreadAttributeList(NULL, 1, 0, &size) ||
|
||||
GetLastError() == ERROR_INSUFFICIENT_BUFFER))
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList = reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(::HeapAlloc(::GetProcessHeap(), 0, size));
|
||||
if (lpAttributeList == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (!::InitializeProcThreadAttributeList(lpAttributeList, 1, 0, &size))
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
::HeapFree(GetProcessHeap(), 0, lpAttributeList);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
proc_attribute_list_storage.reset(lpAttributeList);
|
||||
startup_info.lpAttributeList = proc_attribute_list_storage.get();
|
||||
return startup_info.lpAttributeList;
|
||||
}
|
||||
|
||||
void default_launcher::set_handle_list(error_code & ec)
|
||||
{
|
||||
auto tl = get_thread_attribute_list(ec);
|
||||
if (ec)
|
||||
return;
|
||||
if (!::UpdateProcThreadAttribute(
|
||||
tl, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
|
||||
inherited_handles.data(), inherited_handles.size() * sizeof(HANDLE), nullptr, nullptr))
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
}
|
||||
|
||||
}
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
|
||||
@@ -148,12 +148,17 @@ BOOST_AUTO_TEST_CASE(async_nowait, *boost::unit_test::timeout(10))
|
||||
boost::asio::io_context io_context;
|
||||
bp::child c(
|
||||
master_test_suite().argv[1],
|
||||
"test", "--exit-code", "221",
|
||||
"test", "--exit-code", "121",
|
||||
ec,
|
||||
bp::on_exit=[](int exit_code, std::error_code) mutable {},
|
||||
io_context
|
||||
);
|
||||
BOOST_REQUIRE(!ec);
|
||||
io_context.run_for(std::chrono::milliseconds(100));
|
||||
BOOST_CHECK_EQUAL(221, c.exit_code());
|
||||
while (c.running())
|
||||
{
|
||||
io_context.run_for(std::chrono::milliseconds(10));
|
||||
io_context.restart();
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(121, c.exit_code());
|
||||
}
|
||||
Reference in New Issue
Block a user