From 7e5dd4075f3d29d7f8cc50c1c8a670eb8164d8a7 Mon Sep 17 00:00:00 2001 From: Samuel Venable Date: Tue, 29 Oct 2024 15:06:15 +0000 Subject: [PATCH] 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 --- include/boost/process/v2/ext/cmd.hpp | 1 + include/boost/process/v2/ext/env.hpp | 4 +- include/boost/process/v2/pid.hpp | 1 + src/ext/cmd.cpp | 30 ++-- src/ext/env.cpp | 228 ++++++++++++++++++--------- src/ext/exe.cpp | 2 +- src/pid.cpp | 90 +++++++++-- test/v2/Jamfile.jam | 2 - 8 files changed, 249 insertions(+), 109 deletions(-) diff --git a/include/boost/process/v2/ext/cmd.hpp b/include/boost/process/v2/ext/cmd.hpp index 6308885e..b429465b 100644 --- a/include/boost/process/v2/ext/cmd.hpp +++ b/include/boost/process/v2/ext/cmd.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include diff --git a/include/boost/process/v2/ext/env.hpp b/include/boost/process/v2/ext/env.hpp index 8c634739..4e2a92ca 100644 --- a/include/boost/process/v2/ext/env.hpp +++ b/include/boost/process/v2/ext/env.hpp @@ -8,6 +8,7 @@ #define BOOST_PROCESS_V2_ENV_HPP #include #include +#include #include #include @@ -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 *; diff --git a/include/boost/process/v2/pid.hpp b/include/boost/process/v2/pid.hpp index 8c6779b2..e705b949 100644 --- a/include/boost/process/v2/pid.hpp +++ b/include/boost/process/v2/pid.hpp @@ -10,6 +10,7 @@ #include #include +#include BOOST_PROCESS_V2_BEGIN_NAMESPACE diff --git a/src/ext/cmd.cpp b/src/ext/cmd.cpp index de1e06cc..519a1bc9 100644 --- a/src/ext/cmd.cpp +++ b/src/ext/cmd.cpp @@ -52,6 +52,7 @@ #endif #if defined(__sun) +#include #include #include #include @@ -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 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 {}; } diff --git a/src/ext/env.cpp b/src/ext/env.cpp index 44dc5d5f..35af73a0 100644 --- a/src/ext/env.cpp +++ b/src/ext/env.cpp @@ -23,6 +23,7 @@ #if (defined(__APPLE__) && defined(__MACH__)) #include #if !TARGET_OS_IOS + #include #include #include #include @@ -34,21 +35,52 @@ #endif #if defined(__FreeBSD__) -#include -#include +#include +#include +#include +#include #include -#include +#include #include -#include +#endif + +#if defined(__DragonFly__) +#include +#include +#include +#include +#endif + +#if defined(__NetBSD__) +#include +#include +#include +#include +#include +#include #endif #if defined(__OpenBSD__) +#include +#include #include #include #include #include #endif +#if defined(__sun) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 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 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(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 vec; + int cntp = 0; + kinfo_proc2 *proc_info = nullptr; + + struct closer + { + void operator()(kvm_t * kd) + { + kvm_close(kd); + } + }; + + std::unique_ptr 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 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 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 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) diff --git a/src/ext/exe.cpp b/src/ext/exe.cpp index 9e6e78ea..0f05f8ab 100644 --- a/src/ext/exe.cpp +++ b/src/ext/exe.cpp @@ -39,7 +39,7 @@ #if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)) #include #include -#if !defined(__FreeBSD__) +#if !defined(__FreeBSD__) && !defined(__NetBSD__) #include #endif #endif diff --git a/src/pid.cpp b/src/pid.cpp index 7713b822..950ed946 100644 --- a/src/pid.cpp +++ b/src/pid.cpp @@ -29,10 +29,11 @@ #endif #if defined(__FreeBSD__) -#include +#include +#include +#include +#include #include -#include -#include #endif #if (defined(__DragonFly__) || defined(__OpenBSD__)) @@ -277,13 +278,29 @@ std::vector all_pids(boost::system::error_code & ec) { std::vector 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 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 all_pids(boost::system::error_code & ec) pid_type parent_pid(pid_type pid, boost::system::error_code & ec) { pid_type ppid = static_cast(-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 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 child_pids(pid_type pid, boost::system::error_code & ec) { std::vector 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 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 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 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 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 all_pids(boost::system::error_code & ec) std::vector 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(-1); int cntp = 0; kinfo_proc2 *proc_info = nullptr; + struct closer { void operator()(kvm_t * kd) @@ -498,6 +553,7 @@ std::vector child_pids(pid_type pid, boost::system::error_code & ec) std::vector vec; int cntp = 0; kinfo_proc2 *proc_info = nullptr; + struct closer { void operator()(kvm_t * kd) @@ -535,6 +591,7 @@ std::vector all_pids(boost::system::error_code & ec) std::vector 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(-1); int cntp = 0; kinfo_proc *proc_info = nullptr; + struct closer { void operator()(kvm_t * kd) @@ -598,6 +656,7 @@ std::vector child_pids(pid_type pid, boost::system::error_code & ec) std::vector vec; int cntp = 0; kinfo_proc *proc_info = nullptr; + struct closer { void operator()(kvm_t * kd) @@ -636,6 +695,7 @@ std::vector all_pids(boost::system::error_code & ec) std::vector 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(-1); proc *proc_info = nullptr; + struct closer { void operator()(kvm_t * kd) @@ -697,6 +758,7 @@ std::vector child_pids(pid_type pid, boost::system::error_code & ec) std::vector vec; struct pid cur_pid; proc *proc_info = nullptr; + struct closer { void operator()(kvm_t * kd) diff --git a/test/v2/Jamfile.jam b/test/v2/Jamfile.jam index 86774c6a..20aaf06f 100644 --- a/test/v2/Jamfile.jam +++ b/test/v2/Jamfile.jam @@ -21,9 +21,7 @@ project : requirements windows:_WIN32_WINNT=0x0601 linux:-lpthread freebsd:-lpthread - freebsd:-lutil freebsd:-lkvm - freebsd:-lprocstat bsd:-lpthread bsd:-lkvm netbsd:-lpthread