2
0
mirror of https://github.com/boostorg/process.git synced 2026-01-19 04:22:15 +00:00

bp2::ext::env() Fixes (#415)

* Implement OpenBSD Executable PatH
* Static Cast Device and iNode
* Add Name Spaces to Exe Checker
* Strings to File System Paths

---------

Co-authored-by: freebsd <freebsd@freebsd.lan>
This commit is contained in:
Samuel Venable
2024-10-29 15:06:15 +00:00
committed by Klemens Morgenstern
parent 3ad68a3f2a
commit 7e5dd4075f
8 changed files with 249 additions and 109 deletions

View File

@@ -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>

View File

@@ -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 *;

View File

@@ -10,6 +10,7 @@
#include <boost/process/v2/detail/throw_error.hpp>
#include <vector>
#include <memory>
BOOST_PROCESS_V2_BEGIN_NAMESPACE

View File

@@ -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)
@@ -303,6 +305,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{
int cntp = 0;
kinfo_proc2 *proc_info = nullptr;
struct closer
{
void operator()(kvm_t * kd)
@@ -364,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);
@@ -389,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 {};
}

View File

@@ -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;
@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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