mirror of
https://github.com/boostorg/process.git
synced 2026-01-20 16:52:14 +00:00
Compare commits
30 Commits
openbsd-fi
...
v2_handles
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6239f63c7 | ||
|
|
58586e420c | ||
|
|
7e5dd4075f | ||
|
|
3ad68a3f2a | ||
|
|
8a8ca8b7ab | ||
|
|
817128108a | ||
|
|
941e93b587 | ||
|
|
e827d14542 | ||
|
|
f218a6a6c1 | ||
|
|
11a0d0d7c1 | ||
|
|
fdfb5043cb | ||
|
|
e46a514629 | ||
|
|
36954338d8 | ||
|
|
a44fd24523 | ||
|
|
eb6b49c090 | ||
|
|
928674d2e3 | ||
|
|
894f371898 | ||
|
|
7ed1648032 | ||
|
|
a96f7a04e0 | ||
|
|
46b71d5e96 | ||
|
|
9f104634a9 | ||
|
|
c492c93062 | ||
|
|
12192d35d3 | ||
|
|
f741b0d120 | ||
|
|
211a3134b6 | ||
|
|
642bd7cf5c | ||
|
|
8df45b8f68 | ||
|
|
54479a7372 | ||
|
|
9761be99bb | ||
|
|
e5e898f363 |
@@ -11,7 +11,7 @@
|
||||
]
|
||||
]
|
||||
|
||||
[note Process v1 will be deprecated in the future. Use v2 for new projects.]
|
||||
[note Process v1 will be deprecated in the next release (1.88). Use v2 for new projects.]
|
||||
|
||||
[include v1.qbk]
|
||||
[include v2.qbk]
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
[include v1/design.qbk]
|
||||
[include v1/extend.qbk]
|
||||
[include v1/faq.qbk]
|
||||
[xinclude reference_v2.xml]
|
||||
[xinclude reference_v1.xml]
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2024 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_BASIC_STREAM_INPUT_HPP
|
||||
#define BOOST_PROCESS_BASIC_STREAM_INPUT_HPP
|
||||
|
||||
#include <boost/process/v2/detail/config.hpp>
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename Executor>
|
||||
basic_stream_input<Executor> open_stdin(Executor executor, bool duplicate = true);
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#endif //BOOST_PROCESS_BASIC_STREAM_INPUT_HPP
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2024 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_EXPERIMENTAL_STREAM_INPUT_HPP
|
||||
#define BOOST_PROCESS_V2_EXPERIMENTAL_STREAM_INPUT_HPP
|
||||
|
||||
#include <boost/process/v2/detail/config.hpp>
|
||||
#include <boost/process/v2/experimental/basic_stream_input.hpp>
|
||||
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
typedef basic_stream_input<> stream_input;
|
||||
|
||||
BOOST_PROCESS_V2_END_NAMESPACE
|
||||
|
||||
#endif //BOOST_PROCESS_V2_EXPERIMENTAL_STREAM_INPUT_HPP
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/process/v2/detail/config.hpp>
|
||||
#include <boost/process/v2/detail/throw_error.hpp>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define BOOST_PROCESS_V2_ENV_HPP
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/process/v2/detail/config.hpp>
|
||||
#include <boost/process/v2/detail/throw_error.hpp>
|
||||
@@ -26,9 +27,6 @@ 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 *;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <boost/process/v2/detail/throw_error.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
@@ -303,12 +303,14 @@ 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.inherit_handles = true;
|
||||
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);
|
||||
return error_code {};
|
||||
};
|
||||
#else
|
||||
|
||||
@@ -91,13 +91,21 @@ 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,
|
||||
inherit_handles ? TRUE : FALSE,
|
||||
inherited_handles.empty() ? FALSE : TRUE,
|
||||
creation_flags,
|
||||
environment,
|
||||
current_directory.empty() ? nullptr : current_directory.c_str(),
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <boost/process/v2/error.hpp>
|
||||
|
||||
#include <numeric>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(BOOST_PROCESS_V2_STANDALONE)
|
||||
@@ -207,8 +209,8 @@ struct default_launcher
|
||||
SECURITY_ATTRIBUTES * process_attributes = nullptr;
|
||||
//// The thread_attributes passed to CreateProcess
|
||||
SECURITY_ATTRIBUTES * thread_attributes = nullptr;
|
||||
/// The bInheritHandles option. Needs to be set to true by any initializers using handles.
|
||||
bool inherit_handles = false;
|
||||
/// The inhreited_handles option. bInheritHandles will be true if not empty..
|
||||
std::vector<HANDLE> inherited_handles;
|
||||
/// 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.
|
||||
@@ -294,18 +296,26 @@ 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,
|
||||
inherit_handles ? TRUE : FALSE,
|
||||
inherited_handles.empty() ? FALSE : TRUE,
|
||||
creation_flags,
|
||||
environment,
|
||||
current_directory.empty() ? nullptr : current_directory.c_str(),
|
||||
@@ -403,6 +413,18 @@ 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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
#include <cstdlib>
|
||||
#include <sys/types.h>
|
||||
#include <kvm.h>
|
||||
#include <sys/param.h>
|
||||
@@ -274,6 +275,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
const char *nlistf, *memf;
|
||||
nlistf = memf = "/dev/null";
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -283,7 +285,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return {};}
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
|
||||
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp)))
|
||||
{
|
||||
char **cmd = kvm_getargv(kd.get(), proc_info, 0);
|
||||
@@ -301,10 +303,9 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
|
||||
std::vector<std::string> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc2 *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -315,7 +316,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
|
||||
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return vec;}
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
|
||||
if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &cntp)))
|
||||
{
|
||||
char **cmd = kvm_getargv2(kd.get(), proc_info, 0);
|
||||
@@ -326,14 +327,13 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
return vec;
|
||||
return {};
|
||||
}
|
||||
|
||||
#elif defined(__OpenBSD__)
|
||||
|
||||
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
|
||||
@@ -346,7 +346,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return vec;}
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
|
||||
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cntp)))
|
||||
{
|
||||
char **cmd = kvm_getargv(kd.get(), proc_info, 0);
|
||||
@@ -367,22 +367,29 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
char **cmd = nullptr;
|
||||
proc *proc_info = nullptr;
|
||||
user *proc_user = nullptr;
|
||||
kvm_t *kd = kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr);
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return {};}
|
||||
if ((proc_info = kvm_getproc(kd, pid)))
|
||||
|
||||
struct closer
|
||||
{
|
||||
if ((proc_user = kvm_getu(kd, proc_info)))
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
if (!kvm_getcmd(kd, proc_info, proc_user, &cmd, nullptr))
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
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 {};}
|
||||
if ((proc_info = kvm_getproc(kd.get(), pid)))
|
||||
{
|
||||
if ((proc_user = kvm_getu(kd.get(), proc_info)))
|
||||
{
|
||||
if (!kvm_getcmd(kd.get(), proc_info, proc_user, &cmd, nullptr))
|
||||
{
|
||||
int argc = 0;
|
||||
for (int i = 0; cmd[i] != nullptr; i++)
|
||||
argc ++;
|
||||
shell res = make_cmd_shell_::make(
|
||||
argc++;
|
||||
return make_cmd_shell_::make(
|
||||
{}, argc, cmd,
|
||||
+[](int, char ** argv) {::free(argv);})
|
||||
kvm_close(kd);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
@@ -392,8 +399,6 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
|
||||
kvm_close(kd);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
230
src/ext/env.cpp
230
src/ext/env.cpp
@@ -23,6 +23,7 @@
|
||||
#if (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <TargetConditionals.h>
|
||||
#if !TARGET_OS_IOS
|
||||
#include <algorithm>
|
||||
#include <sys/proc_info.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <libproc.h>
|
||||
@@ -34,21 +35,52 @@
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <kvm.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/user.h>
|
||||
#include <libprocstat.h>
|
||||
#endif
|
||||
|
||||
#if defined(__DragonFly__)
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <sys/types.h>
|
||||
#include <kvm.h>
|
||||
#endif
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <kvm.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <kvm.h>
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <kvm.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/proc.h>
|
||||
#endif
|
||||
|
||||
BOOST_PROCESS_V2_BEGIN_NAMESPACE
|
||||
|
||||
namespace detail {
|
||||
@@ -105,7 +137,7 @@ const environment::char_type * dereference(native_env_iterator iterator)
|
||||
return iterator;
|
||||
}
|
||||
|
||||
#elif (defined(__APPLE___) || defined(__MACH__)) || defined(__OpenBSD__)
|
||||
#elif (defined(__APPLE___) || defined(__MACH__)) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun)
|
||||
|
||||
void native_env_handle_deleter::operator()(native_env_handle_type h) const
|
||||
{
|
||||
@@ -130,31 +162,6 @@ 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
|
||||
|
||||
}
|
||||
@@ -338,72 +345,90 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
return ev;
|
||||
}
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
env_view ev;
|
||||
std::vector<char> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
const char *nlistf, *memf;
|
||||
nlistf = memf = "/dev/null";
|
||||
|
||||
unsigned cntp = 0;
|
||||
procstat *proc_stat = procstat_open_sysctl();
|
||||
if (proc_stat != nullptr)
|
||||
struct closer
|
||||
{
|
||||
kinfo_proc *proc_info = procstat_getprocs(proc_stat, KERN_PROC_PID, pid, &cntp);
|
||||
if (proc_info != nullptr)
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
char **env = procstat_getenvv(proc_stat, proc_info, 0);
|
||||
if (env != nullptr)
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
|
||||
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp))) {
|
||||
char **env = kvm_getenvv(kd.get(), proc_info, 0);
|
||||
if (env) {
|
||||
for (int i = 0; env[i] != nullptr; i++)
|
||||
{
|
||||
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
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
|
||||
for (int j = 0; j < strlen(env[i]); j++)
|
||||
vec.push_back(env[i][j]);
|
||||
vec.push_back('\0');
|
||||
}
|
||||
procstat_freeprocs(proc_stat, proc_info);
|
||||
|
||||
vec.push_back('\0');
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
procstat_close(proc_stat);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
|
||||
env_view ev;
|
||||
ev.handle_.reset(new char[vec.size()]());
|
||||
std::copy(vec.begin(), vec.end(), ev.handle_.get());
|
||||
return ev;
|
||||
}
|
||||
|
||||
#elif defined(__NetBSD__)
|
||||
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
std::vector<char> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc2 *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
|
||||
if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &cntp))) {
|
||||
char **env = kvm_getenvv2(kd.get(), proc_info, 0);
|
||||
if (env) {
|
||||
for (int i = 0; env[i] != nullptr; i++)
|
||||
{
|
||||
for (int j = 0; j < strlen(env[i]); j++)
|
||||
vec.push_back(env[i][j]);
|
||||
vec.push_back('\0');
|
||||
}
|
||||
vec.push_back('\0');
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
|
||||
env_view ev;
|
||||
ev.handle_.reset(new char[vec.size()]());
|
||||
std::copy(vec.begin(), vec.end(), ev.handle_.get());
|
||||
return ev;
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
|
||||
std::vector<char> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
@@ -417,7 +442,7 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
|
||||
if (!kd.get()) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return {};}
|
||||
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
|
||||
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cntp)))
|
||||
{
|
||||
char **env = kvm_getenvv(kd.get(), proc_info, 0);
|
||||
@@ -442,6 +467,53 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
std::copy(vec.begin(), vec.end(), ev.handle_.get());
|
||||
return ev;
|
||||
}
|
||||
#elif defined(__sun)
|
||||
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
std::vector<char> vec;
|
||||
char **env = nullptr;
|
||||
proc *proc_info = nullptr;
|
||||
user *proc_user = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
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 {};}
|
||||
if ((proc_info = kvm_getproc(kd.get(), pid)))
|
||||
{
|
||||
if ((proc_user = kvm_getu(kd.get(), proc_info)))
|
||||
{
|
||||
if (!kvm_getcmd(kd.get(), proc_info, proc_user, nullptr, &env))
|
||||
{
|
||||
for (int i = 0; env[i] != nullptr; i++)
|
||||
{
|
||||
for (int j = 0; j < strlen(env[i]); j++)
|
||||
vec.push_back(env[i][j]);
|
||||
vec.push_back('\0');
|
||||
}
|
||||
vec.push_back('\0');
|
||||
free(env);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
|
||||
env_view ev;
|
||||
ev.handle_.reset(new char[vec.size()]());
|
||||
std::copy(vec.begin(), vec.end(), ev.handle_.get());
|
||||
return ev;
|
||||
}
|
||||
#endif
|
||||
|
||||
env_view env(boost::process::v2::pid_type pid)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__))
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#if !defined(__FreeBSD__)
|
||||
#if !defined(__FreeBSD__) && !defined(__NetBSD__)
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
90
src/pid.cpp
90
src/pid.cpp
@@ -29,10 +29,11 @@
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <kvm.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/user.h>
|
||||
#include <libutil.h>
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
#if (defined(__DragonFly__) || defined(__OpenBSD__))
|
||||
@@ -277,13 +278,29 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
|
||||
{
|
||||
std::vector<pid_type> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = kinfo_getallproc(&cntp);
|
||||
if (proc_info)
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
const char *nlistf, *memf;
|
||||
nlistf = memf = "/dev/null";
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
|
||||
if (!kd)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
return vec;
|
||||
}
|
||||
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp)))
|
||||
{
|
||||
vec.reserve(cntp);
|
||||
for (int i = 0; i < cntp; i++)
|
||||
for (int i = 0; i < cntp; i++)
|
||||
vec.push_back(proc_info[i].ki_pid);
|
||||
free(proc_info);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
@@ -293,11 +310,28 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
|
||||
pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
pid_type ppid = static_cast<pid_type>(-1);
|
||||
kinfo_proc *proc_info = kinfo_getproc(pid);
|
||||
if (proc_info)
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
const char *nlistf, *memf;
|
||||
nlistf = memf = "/dev/null";
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
|
||||
if (!kd)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
return ppid;
|
||||
}
|
||||
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp)))
|
||||
{
|
||||
ppid = proc_info->ki_ppid;
|
||||
free(proc_info);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
@@ -307,9 +341,26 @@ 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;
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = kinfo_getallproc(&cntp);
|
||||
if (proc_info)
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
const char *nlistf, *memf;
|
||||
nlistf = memf = "/dev/null";
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
{
|
||||
kvm_close(kd);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
|
||||
if (!kd)
|
||||
{
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
return vec;
|
||||
}
|
||||
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp)))
|
||||
{
|
||||
vec.reserve(cntp);
|
||||
for (int i = 0; i < cntp; i++)
|
||||
@@ -319,7 +370,6 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
|
||||
vec.push_back(proc_info[i].ki_pid);
|
||||
}
|
||||
}
|
||||
free(proc_info);
|
||||
}
|
||||
else
|
||||
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
|
||||
@@ -335,6 +385,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
const char *nlistf, *memf;
|
||||
nlistf = memf = "/dev/null";
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -368,6 +419,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
const char *nlistf, *memf;
|
||||
nlistf = memf = "/dev/null";
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -401,6 +453,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
const char *nlistf, *memf;
|
||||
nlistf = memf = "/dev/null";
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -438,6 +491,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
|
||||
std::vector<pid_type> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc2 *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -470,6 +524,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
|
||||
pid_type ppid = static_cast<pid_type>(-1);
|
||||
int cntp = 0;
|
||||
kinfo_proc2 *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -498,6 +553,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
|
||||
std::vector<pid_type> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc2 *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -535,6 +591,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
|
||||
std::vector<pid_type> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -570,6 +627,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
|
||||
pid_type ppid = static_cast<pid_type>(-1);
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -598,6 +656,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
|
||||
std::vector<pid_type> vec;
|
||||
int cntp = 0;
|
||||
kinfo_proc *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -636,6 +695,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
|
||||
std::vector<pid_type> vec;
|
||||
struct pid cur_pid;
|
||||
proc *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -669,6 +729,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
|
||||
{
|
||||
pid_type ppid = static_cast<pid_type>(-1);
|
||||
proc *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
@@ -697,6 +758,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
|
||||
std::vector<pid_type> vec;
|
||||
struct pid cur_pid;
|
||||
proc *proc_info = nullptr;
|
||||
|
||||
struct closer
|
||||
{
|
||||
void operator()(kvm_t * kd)
|
||||
|
||||
@@ -75,6 +75,45 @@ 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
|
||||
|
||||
|
||||
@@ -21,9 +21,7 @@ project : requirements
|
||||
<target-os>windows:<define>_WIN32_WINNT=0x0601
|
||||
<target-os>linux:<linkflags>-lpthread
|
||||
<target-os>freebsd:<linkflags>-lpthread
|
||||
<target-os>freebsd:<linkflags>-lutil
|
||||
<target-os>freebsd:<linkflags>-lkvm
|
||||
<target-os>freebsd:<linkflags>-lprocstat
|
||||
<target-os>bsd:<linkflags>-lpthread
|
||||
<target-os>bsd:<linkflags>-lkvm
|
||||
<target-os>netbsd:<linkflags>-lpthread
|
||||
|
||||
Reference in New Issue
Block a user