mirror of
https://github.com/boostorg/process.git
synced 2026-01-26 06:42:26 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89c5b589c3 | ||
|
|
4183c66490 | ||
|
|
9cdc1be868 | ||
|
|
b9cb5dc0ee | ||
|
|
4cc469b2a4 | ||
|
|
6e4d1e29d2 | ||
|
|
dada865fd0 | ||
|
|
380dd1b00f | ||
|
|
7cb7af6c8b | ||
|
|
90cbe7cec0 | ||
|
|
8a61f8daa3 |
@@ -139,7 +139,7 @@ struct exe_cmd_init<char> : boost::process::detail::api::handler_base_ext
|
|||||||
}
|
}
|
||||||
static exe_cmd_init cmd_shell(std::string&& cmd)
|
static exe_cmd_init cmd_shell(std::string&& cmd)
|
||||||
{
|
{
|
||||||
std::vector<std::string> args = {"-c", "\"" + cmd + "\""};
|
std::vector<std::string> args = {"-c", cmd};
|
||||||
std::string sh = shell().string();
|
std::string sh = shell().string();
|
||||||
|
|
||||||
return exe_cmd_init(
|
return exe_cmd_init(
|
||||||
|
|||||||
@@ -155,8 +155,8 @@ class executor
|
|||||||
void write_error(const std::error_code & ec, const char * msg)
|
void write_error(const std::error_code & ec, const char * msg)
|
||||||
{
|
{
|
||||||
//I am the child
|
//I am the child
|
||||||
const auto len = std::strlen(msg);
|
const auto len = static_cast<int>(std::strlen(msg));
|
||||||
int data[2] = {ec.value(), static_cast<int>(len + 1)};
|
int data[2] = {ec.value(), len + 1};
|
||||||
|
|
||||||
boost::ignore_unused(::write(_pipe_sink, &data[0], sizeof(int) * 2));
|
boost::ignore_unused(::write(_pipe_sink, &data[0], sizeof(int) * 2));
|
||||||
boost::ignore_unused(::write(_pipe_sink, msg, len));
|
boost::ignore_unused(::write(_pipe_sink, msg, len));
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ public:
|
|||||||
auto st1 = key + ::boost::process::detail::equal_sign<Char>();
|
auto st1 = key + ::boost::process::detail::equal_sign<Char>();
|
||||||
while (*p != nullptr)
|
while (*p != nullptr)
|
||||||
{
|
{
|
||||||
const int len = std::char_traits<Char>::length(*p);
|
const auto len = std::char_traits<Char>::length(*p);
|
||||||
if ((std::distance(st1.begin(), st1.end()) < len)
|
if ((std::distance(st1.begin(), st1.end()) < len)
|
||||||
&& std::equal(st1.begin(), st1.end(), *p))
|
&& std::equal(st1.begin(), st1.end(), *p))
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -12,6 +12,16 @@
|
|||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
#if !defined(BOOST_PROCESS_V2_DISABLE_UNDOCUMENTED_API)
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
LONG WINAPI NtResumeProcess(HANDLE ProcessHandle);
|
||||||
|
LONG WINAPI NtSuspendProcess(HANDLE ProcessHandle);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -113,6 +123,33 @@ void check_running_(HANDLE handle, error_code & ec, DWORD & exit_status)
|
|||||||
ec = detail::get_last_error();
|
ec = detail::get_last_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_PROCESS_V2_DISABLE_UNDOCUMENTED_API)
|
||||||
|
void suspend_(HANDLE handle, error_code & ec)
|
||||||
|
{
|
||||||
|
auto nt_err = NtSuspendProcess(handle);
|
||||||
|
if (nt_err > 0xC0000000)
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume_(HANDLE handle, error_code & ec)
|
||||||
|
{
|
||||||
|
|
||||||
|
auto nt_err = NtResumeProcess(handle);
|
||||||
|
if (nt_err > 0xC0000000)
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void suspend_(HANDLE, error_code & ec)
|
||||||
|
{
|
||||||
|
ec.assign(ERROR_CALL_NOT_IMPLEMENTED, system_category());
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume_(HANDLE handle, error_code & ec)
|
||||||
|
{
|
||||||
|
|
||||||
|
ec.assign(ERROR_CALL_NOT_IMPLEMENTED, system_category());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_PROCESS_V2_HEADER_ONLY)
|
#if !defined(BOOST_PROCESS_V2_HEADER_ONLY)
|
||||||
template struct basic_process_handle_win<>;
|
template struct basic_process_handle_win<>;
|
||||||
|
|||||||
@@ -183,6 +183,41 @@ struct basic_process_handle_fd
|
|||||||
detail::throw_error(ec, "request_exit");
|
detail::throw_error(ec, "request_exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void suspend()
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
error_code ec;
|
||||||
|
suspend(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "suspend");
|
||||||
|
}
|
||||||
|
|
||||||
|
void suspend(error_code &ec)
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
if (::kill(pid_, SIGCONT) == -1)
|
||||||
|
ec = get_last_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume()
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
error_code ec;
|
||||||
|
resume(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "resume");
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume(error_code &ec)
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
if (::kill(pid_, SIGTERM) == -1)
|
||||||
|
ec = get_last_error();
|
||||||
|
}
|
||||||
void terminate(native_exit_code_type &exit_status, error_code &ec)
|
void terminate(native_exit_code_type &exit_status, error_code &ec)
|
||||||
{
|
{
|
||||||
if (pid_ <= 0)
|
if (pid_ <= 0)
|
||||||
|
|||||||
@@ -212,6 +212,42 @@ struct basic_process_handle_fd_or_signal
|
|||||||
detail::throw_error(ec, "request_exit");
|
detail::throw_error(ec, "request_exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void suspend()
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
error_code ec;
|
||||||
|
suspend(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "suspend");
|
||||||
|
}
|
||||||
|
|
||||||
|
void suspend(error_code &ec)
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
if (::kill(pid_, SIGCONT) == -1)
|
||||||
|
ec = get_last_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume()
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
error_code ec;
|
||||||
|
resume(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "resume");
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume(error_code &ec)
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
if (::kill(pid_, SIGTERM) == -1)
|
||||||
|
ec = get_last_error();
|
||||||
|
}
|
||||||
|
|
||||||
void terminate(native_exit_code_type &exit_status, error_code &ec)
|
void terminate(native_exit_code_type &exit_status, error_code &ec)
|
||||||
{
|
{
|
||||||
if (pid_ <= 0)
|
if (pid_ <= 0)
|
||||||
|
|||||||
@@ -180,6 +180,50 @@ struct basic_process_handle_signal
|
|||||||
detail::throw_error(ec, "request_exit");
|
detail::throw_error(ec, "request_exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void interrupt(error_code &ec)
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
if (::kill(pid_, SIGTERM) == -1)
|
||||||
|
ec = get_last_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
void suspend()
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
error_code ec;
|
||||||
|
suspend(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "suspend");
|
||||||
|
}
|
||||||
|
|
||||||
|
void suspend(error_code &ec)
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
if (::kill(pid_, SIGCONT) == -1)
|
||||||
|
ec = get_last_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume()
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
error_code ec;
|
||||||
|
resume(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "resume");
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume(error_code &ec)
|
||||||
|
{
|
||||||
|
if (pid_ <= 0)
|
||||||
|
return ;
|
||||||
|
if (::kill(pid_, SIGTERM) == -1)
|
||||||
|
ec = get_last_error();
|
||||||
|
}
|
||||||
|
|
||||||
void terminate(native_exit_code_type &exit_status, error_code &ec)
|
void terminate(native_exit_code_type &exit_status, error_code &ec)
|
||||||
{
|
{
|
||||||
if (pid_ <= 0)
|
if (pid_ <= 0)
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ BOOST_PROCESS_V2_DECL void terminate_if_running_(void * handle);
|
|||||||
BOOST_PROCESS_V2_DECL bool check_handle_(void* handle, error_code & ec);
|
BOOST_PROCESS_V2_DECL bool check_handle_(void* handle, error_code & ec);
|
||||||
BOOST_PROCESS_V2_DECL bool check_pid_(pid_type pid_, error_code & ec);
|
BOOST_PROCESS_V2_DECL bool check_pid_(pid_type pid_, error_code & ec);
|
||||||
BOOST_PROCESS_V2_DECL void interrupt_(pid_type pid_, error_code & ec);
|
BOOST_PROCESS_V2_DECL void interrupt_(pid_type pid_, error_code & ec);
|
||||||
|
BOOST_PROCESS_V2_DECL void suspend_(void * handle, error_code & ec);
|
||||||
|
BOOST_PROCESS_V2_DECL void resume_(void * handle, error_code & ec);
|
||||||
BOOST_PROCESS_V2_DECL void terminate_(void * handle, error_code & ec, native_exit_code_type & exit_code);
|
BOOST_PROCESS_V2_DECL void terminate_(void * handle, error_code & ec, native_exit_code_type & exit_code);
|
||||||
BOOST_PROCESS_V2_DECL void request_exit_(pid_type pid_, error_code & ec);
|
BOOST_PROCESS_V2_DECL void request_exit_(pid_type pid_, error_code & ec);
|
||||||
BOOST_PROCESS_V2_DECL void check_running_(void* handle, error_code & ec, native_exit_code_type & exit_status);
|
BOOST_PROCESS_V2_DECL void check_running_(void* handle, error_code & ec, native_exit_code_type & exit_status);
|
||||||
@@ -176,6 +178,32 @@ struct basic_process_handle_win
|
|||||||
detail::throw_error(ec, "request_exit");
|
detail::throw_error(ec, "request_exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void suspend(error_code &ec)
|
||||||
|
{
|
||||||
|
detail::suspend_(handle_.native_handle(), ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void suspend()
|
||||||
|
{
|
||||||
|
error_code ec;
|
||||||
|
suspend(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "suspend");
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume(error_code &ec)
|
||||||
|
{
|
||||||
|
detail::resume_(handle_.native_handle(), ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resume()
|
||||||
|
{
|
||||||
|
error_code ec;
|
||||||
|
suspend(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "resume");
|
||||||
|
}
|
||||||
|
|
||||||
void terminate(native_exit_code_type &exit_status, error_code &ec)
|
void terminate(native_exit_code_type &exit_status, error_code &ec)
|
||||||
{
|
{
|
||||||
if (!detail::check_handle_(handle_.native_handle(), ec))
|
if (!detail::check_handle_(handle_.native_handle(), ec))
|
||||||
|
|||||||
@@ -6,12 +6,21 @@
|
|||||||
#define BOOST_PROCESS_V2_IMPL_PID_IPP
|
#define BOOST_PROCESS_V2_IMPL_PID_IPP
|
||||||
|
|
||||||
#include <boost/process/v2/detail/config.hpp>
|
#include <boost/process/v2/detail/config.hpp>
|
||||||
|
#include <boost/process/v2/detail/last_error.hpp>
|
||||||
|
#include <boost/process/v2/detail/throw_error.hpp>
|
||||||
#include <boost/process/v2/pid.hpp>
|
#include <boost/process/v2/pid.hpp>
|
||||||
|
|
||||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if (defined(__APPLE__) && defined(__MACH__))
|
||||||
|
#include <sys/proc_info.h>
|
||||||
|
#include <libproc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||||
@@ -22,6 +31,220 @@ pid_type current_pid() {return ::GetCurrentProcessId();}
|
|||||||
pid_type current_pid() {return ::getpid();}
|
pid_type current_pid() {return ::getpid();}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||||
|
std::vector<pid_type> all_pids(error_code & ec)
|
||||||
|
{
|
||||||
|
std::vector<pid_type> vec;
|
||||||
|
HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if (!hp)
|
||||||
|
{
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESSENTRY32 pe;
|
||||||
|
pe.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
if (Process32First(hp, &pe)) {
|
||||||
|
do {
|
||||||
|
vec.push_back(pe.th32ProcessID);
|
||||||
|
} while (Process32Next(hp, &pe));
|
||||||
|
}
|
||||||
|
CloseHandle(hp);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif (defined(__APPLE__) && defined(__MACH__))
|
||||||
|
|
||||||
|
std::vector<pid_type> all_pids(error_code & ec)
|
||||||
|
{
|
||||||
|
std::vector<pid_type> vec;
|
||||||
|
vec.resize(proc_listpids(PROC_ALL_PIDS, 0, nullptr, 0));
|
||||||
|
|
||||||
|
if (proc_listpids(PROC_ALL_PIDS, 0, &vec[0], sizeof(pid_type) * vec))
|
||||||
|
{
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto itr = std::partition(vec.begin(), vec.end(), [](pid_type pt) {return pt != 0;});
|
||||||
|
vec.erase(itr, vec.end());
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__linux__)
|
||||||
|
|
||||||
|
std::vector<pid_type> all_pids(error_code & ec)
|
||||||
|
{
|
||||||
|
std::vector<pid_type> vec;
|
||||||
|
DIR *proc = opendir("/proc");
|
||||||
|
if (proc == nullptr)
|
||||||
|
{
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
struct dirent *ent = nullptr;
|
||||||
|
while ((ent = readdir(proc) != nullptr))
|
||||||
|
{
|
||||||
|
if (!isdigit(*ent->d_name))
|
||||||
|
continue;
|
||||||
|
vec.push_back(atoi(ent->d_name));
|
||||||
|
}
|
||||||
|
closedir(proc);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
|
||||||
|
std::vector<pid_type> all_pids(error_code & ec)
|
||||||
|
{
|
||||||
|
std::vector<pid_type> vec;
|
||||||
|
int cntp = 0;
|
||||||
|
kinfo_proc *proc_info = kinfo_getallproc(&cntp);
|
||||||
|
if (proc_info)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < cntp; i++)
|
||||||
|
vec.push_back(proc_info[i].ki_pid);
|
||||||
|
free(proc_info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__DragonFly__)
|
||||||
|
|
||||||
|
std::vector<pid_type> all_pids(error_code & ec)
|
||||||
|
{
|
||||||
|
std::vector<pid_type> vec;
|
||||||
|
int cntp = 0;
|
||||||
|
kinfo_proc *proc_info = nullptr;
|
||||||
|
const char *nlistf, *memf;
|
||||||
|
nlistf = memf = "/dev/null";
|
||||||
|
kd = kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr);
|
||||||
|
if (!kd)
|
||||||
|
{
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((proc_info = kvm_getprocs(kd, KERN_PROC_ALL, 0, &cntp)))
|
||||||
|
{
|
||||||
|
vec.reserve(cntp);
|
||||||
|
for (int i = 0; i < cntp; i++)
|
||||||
|
if (proc_info[i].kp_pid >= 0)
|
||||||
|
vec.push_back(proc_info[i].kp_pid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
|
||||||
|
kvm_close(kd);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
|
||||||
|
std::vector<pid_type> all_pids(error_code & ec)
|
||||||
|
{
|
||||||
|
std::vector<pid_type> vec;
|
||||||
|
int cntp = 0;
|
||||||
|
kinfo_proc2 *proc_info = nullptr;
|
||||||
|
kd = kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr);
|
||||||
|
if (!kd)
|
||||||
|
{
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
if ((proc_info = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &cntp)))
|
||||||
|
{
|
||||||
|
vec.reserve(cntp);
|
||||||
|
for (int i = cntp - 1; i >= 0; i--) {
|
||||||
|
vec.push_back(proc_info[i].p_pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
kvm_close(kd);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__OpenBSD__)
|
||||||
|
|
||||||
|
std::vector<pid_type> all_pids(error_code & ec)
|
||||||
|
{
|
||||||
|
std::vector<pid_type> vec;
|
||||||
|
int cntp = 0;
|
||||||
|
kinfo_proc *proc_info = nullptr;
|
||||||
|
kd = kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr);
|
||||||
|
|
||||||
|
if (!kd)
|
||||||
|
{
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
if ((proc_info = kvm_getprocs(kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &cntp)))
|
||||||
|
{
|
||||||
|
vec.reserve(cntp);
|
||||||
|
for (int i = 0; i < cntp; i++) {
|
||||||
|
if (proc_info[i].kp_pid >= 0) {
|
||||||
|
vec.push_back(proc_info[i].kp_pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
kvm_close(kd);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__sun)
|
||||||
|
|
||||||
|
std::vector<pid_type> all_pids(error_code & ec)
|
||||||
|
{
|
||||||
|
std::vector<pid_type> vec;
|
||||||
|
struct pid cur_pid;
|
||||||
|
proc *proc_info = nullptr;
|
||||||
|
kd = kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr);
|
||||||
|
if (!kd)
|
||||||
|
{
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((proc_info = kvm_nextproc(kd)))
|
||||||
|
{
|
||||||
|
if (kvm_kread(kd, (std::uintptr_t)proc_info->p_pidp, &cur_pid, sizeof(cur_pid)) != -1) {
|
||||||
|
vec.insert(vec.begin(), cur_pid.pid_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ec = detail::get_last_error();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kvm_close(kd);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Platform not supported"
|
||||||
|
|
||||||
|
|
||||||
|
#endif defined(BOOST_PROCESS_V2_WINDOWS)
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<pid_type> all_pids()
|
||||||
|
{
|
||||||
|
error_code ec;
|
||||||
|
auto res = all_pids(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "all_pids");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOST_PROCESS_V2_END_NAMESPACE
|
BOOST_PROCESS_V2_END_NAMESPACE
|
||||||
|
|
||||||
#endif //BOOST_PROCESS_V2_IMPL_PID_IPP
|
#endif //BOOST_PROCESS_V2_IMPL_PID_IPP
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#define BOOST_PROCESS_V2_PID_HPP
|
#define BOOST_PROCESS_V2_PID_HPP
|
||||||
|
|
||||||
#include <boost/process/v2/detail/config.hpp>
|
#include <boost/process/v2/detail/config.hpp>
|
||||||
|
#include <boost/process/v2/detail/throw_error.hpp>
|
||||||
|
|
||||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@@ -31,6 +32,12 @@ typedef int pid_type;
|
|||||||
/// Get the process id of the current process.
|
/// Get the process id of the current process.
|
||||||
BOOST_PROCESS_V2_DECL pid_type current_pid();
|
BOOST_PROCESS_V2_DECL pid_type current_pid();
|
||||||
|
|
||||||
|
/// List all available pids.
|
||||||
|
BOOST_PROCESS_V2_DECL std::vector<pid_type> all_pids(error_code & ec);
|
||||||
|
|
||||||
|
/// List all available pids.
|
||||||
|
BOOST_PROCESS_V2_DECL std::vector<pid_type> all_pids();
|
||||||
|
|
||||||
BOOST_PROCESS_V2_END_NAMESPACE
|
BOOST_PROCESS_V2_END_NAMESPACE
|
||||||
|
|
||||||
#if defined(BOOST_PROCESS_V2_HEADER_ONLY)
|
#if defined(BOOST_PROCESS_V2_HEADER_ONLY)
|
||||||
|
|||||||
@@ -214,6 +214,37 @@ struct basic_process
|
|||||||
process_handle_.request_exit(ec);
|
process_handle_.request_exit(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send the process a signal requesting it to stop. This may rely on undocmented 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.
|
||||||
|
void suspend()
|
||||||
|
{
|
||||||
|
error_code ec;
|
||||||
|
suspend(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "suspend");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Send the process a signal requesting it to resume. This may rely on undocmented 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.
|
||||||
|
void resume()
|
||||||
|
{
|
||||||
|
error_code ec;
|
||||||
|
suspend(ec);
|
||||||
|
if (ec)
|
||||||
|
detail::throw_error(ec, "resume");
|
||||||
|
}
|
||||||
|
|
||||||
/// Throwing @overload void terminate(native_exit_code_type &exit_code, error_code & ec)
|
/// Throwing @overload void terminate(native_exit_code_type &exit_code, error_code & ec)
|
||||||
void terminate()
|
void terminate()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ lib test_impl : test_impl.cpp filesystem :
|
|||||||
<link>static
|
<link>static
|
||||||
<target-os>windows:<source>shell32
|
<target-os>windows:<source>shell32
|
||||||
<target-os>windows:<source>user32
|
<target-os>windows:<source>user32
|
||||||
|
<target-os>windows:<source>Ntdll
|
||||||
;
|
;
|
||||||
|
|
||||||
test-suite standalone :
|
test-suite standalone :
|
||||||
|
|||||||
@@ -12,4 +12,8 @@ BOOST_AUTO_TEST_CASE(test_pid)
|
|||||||
{
|
{
|
||||||
namespace bp2 = boost::process::v2;
|
namespace bp2 = boost::process::v2;
|
||||||
BOOST_CHECK_NE(bp2::current_pid(), static_cast<bp2::pid_type>(0));
|
BOOST_CHECK_NE(bp2::current_pid(), static_cast<bp2::pid_type>(0));
|
||||||
|
|
||||||
|
auto all = bp2::all_pids();
|
||||||
|
auto itr = std::find(all.begin(), all.end(), bp2::current_pid());
|
||||||
|
BOOST_CHECK(itr != all.end());
|
||||||
}
|
}
|
||||||
@@ -149,6 +149,8 @@ BOOST_AUTO_TEST_CASE(terminate)
|
|||||||
|
|
||||||
BOOST_CHECK_MESSAGE(!sh.empty(), sh);
|
BOOST_CHECK_MESSAGE(!sh.empty(), sh);
|
||||||
bpv::process proc(ctx, sh, {});
|
bpv::process proc(ctx, sh, {});
|
||||||
|
proc.suspend();
|
||||||
|
proc.resume();
|
||||||
proc.terminate();
|
proc.terminate();
|
||||||
proc.wait();
|
proc.wait();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user