From 0379ee666835f90c470f430cfc52ee0df5337907 Mon Sep 17 00:00:00 2001 From: Samuel Venable Date: Wed, 22 May 2024 21:32:40 +0000 Subject: [PATCH] Less dependency on libprocstat and various corrections. On FreeBSD I would like to remove dependency on libprocstat completely, and replace it with libkvm to be more like the other *BSD platforms in terms of linker dependencies. This pull request is our first move in that direction. Replace libprocstat with libkvm in cmd --- include/boost/process/v2/ext/impl/cmd.ipp | 64 +------------------ include/boost/process/v2/ext/impl/cwd.ipp | 75 +++++++++++++---------- include/boost/process/v2/ext/impl/env.ipp | 9 +++ 3 files changed, 56 insertions(+), 92 deletions(-) diff --git a/include/boost/process/v2/ext/impl/cmd.ipp b/include/boost/process/v2/ext/impl/cmd.ipp index 79e5655e4..60eb9378f 100644 --- a/include/boost/process/v2/ext/impl/cmd.ipp +++ b/include/boost/process/v2/ext/impl/cmd.ipp @@ -23,16 +23,8 @@ #include #endif -#if defined(__FreeBSD__) -#include -#include -#include -#include -#include -#include -#endif - -#if (defined(__DragonFly__) || defined(__OpenBSD__)) +#if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)) +#include #include #include #include @@ -262,57 +254,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec) return make_cmd_shell_::make(std::move(procargs), argc, argv.release(), fr_func); } -#elif defined(__FreeBSD__) - -shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec) -{ - struct cl_proc_stat - { - void operator()(struct procstat *proc_stat) - { - procstat_close(proc_stat); - } - }; - std::unique_ptr proc_stat{procstat_open_sysctl()}; - if (!proc_stat) - { - BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) - return {}; - } - - struct proc_info_close - { - struct procstat * proc_stat; - - void operator()(struct kinfo_proc * proc_info) - { - procstat_freeprocs(proc_stat, proc_info); - } - }; - - unsigned cntp; - std::unique_ptr proc_info{ - procstat_getprocs(proc_stat.get(), KERN_PROC_PID, pid, &cntp), - proc_info_close{proc_stat.get()}}; - - if (!proc_info) - { - BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) - return {}; - } - - char **cmd = procstat_getargv(proc_stat.get(), proc_info.get(), 0); - if (!cmd) - { - BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) - return {}; - } - auto res = make_cmd_shell_::clone(cmd); - procstat_freeargv(proc_stat.get()); - return res; -} - -#elif defined(__DragonFly__) +#elif (defined(__FreeBSD__) || defined(__DragonFly__)) shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec) { diff --git a/include/boost/process/v2/ext/impl/cwd.ipp b/include/boost/process/v2/ext/impl/cwd.ipp index f1307e0d8..e2e9120a6 100644 --- a/include/boost/process/v2/ext/impl/cwd.ipp +++ b/include/boost/process/v2/ext/impl/cwd.ipp @@ -30,12 +30,11 @@ #endif #if defined(__FreeBSD__) -#include -#include +#include +#include #include -#include +#include #include -#include #endif #if (defined(__NetBSD__) || defined(__OpenBSD__)) @@ -128,30 +127,21 @@ filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec) { filesystem::path path; - unsigned cntp = 0; - procstat *proc_stat = procstat_open_sysctl(); - if (proc_stat) { - kinfo_proc *proc_info = procstat_getprocs(proc_stat, KERN_PROC_PID, pid, &cntp); - if (proc_info) { - filestat_list *head = procstat_getfiles(proc_stat, proc_info, 0); - if (head) { - filestat *fst = nullptr; - STAILQ_FOREACH(fst, head, next) { - if (fst->fs_uflags & PS_FST_UFLAG_CDIR) - path = filesystem::canonical(fst->fs_path, ec); - } - procstat_freefiles(proc_stat, head); - } - else - BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) - procstat_freeprocs(proc_stat, proc_info); + struct kinfo_file kif; + std::size_t sz = 4, len = sizeof(kif); + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_CWD, pid}; + if (sysctl(mib, sz, nullptr, &len, nullptr, 0) == 0) + { + memset(&kif, 0, len); + if (sysctl(mib, sz, &kif, &len, nullptr, 0) == 0) + { + path = filesystem::canonical(kif.kf_path, ec); } else BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) - procstat_close(proc_stat); } else - BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) + BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return path; } @@ -159,8 +149,30 @@ filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec) { + /* filesystem::path path; - /* Probably the hackiest thing ever we are doing here, because the "official" API is broken OS-level. */ + // Official API (broken OS-level) - including code from DragonFly's fstat(1) + // command line interface utility currently requires way too much code FWIW. + std::size_t sz = 4, len = 0; + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_CWD, pid}; + if (sysctl(mib, sz, nullptr, &len, nullptr, 0) == 0) + { + std::vector vecbuff; + vecbuff.resize(len); + if (sysctl(mib, sz, &vecbuff[0], &len, nullptr, 0) == 0) + { + path = filesystem::canonical(&vecbuff[0], ec); + } + else + BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) + } + else + BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) + return path; + */ + + filesystem::path path; + /* Probably the hackiest thing ever we are doing here, because the official API is broken OS-level. */ FILE *fp = popen(("pos=`ans=\\`/usr/bin/fstat -w -p " + std::to_string(pid) + " | /usr/bin/sed -n 1p\\`; " + "/usr/bin/awk -v ans=\"$ans\" 'BEGIN{print index(ans, \"INUM\")}'`; str=`/usr/bin/fstat -w -p " + std::to_string(pid) + " | /usr/bin/sed -n 3p`; /usr/bin/awk -v str=\"$str\" -v pos=\"$pos\" " + @@ -193,7 +205,7 @@ filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec) { - std::string path; + filesystem::path path; #if defined(__NetBSD__) int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_CWD}; const std::size_t sz = 4; @@ -204,17 +216,18 @@ filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code std::size_t len = 0; if (sysctl(mib, sz, nullptr, &len, nullptr, 0) == 0) { - std::string strbuff; - strbuff.resize(len); - if (sysctl(mib, 4, &strbuff[0], &len, nullptr, 0) == 0) + std::vector vecbuff; + vecbuff.resize(len); + if (sysctl(mib, 4, &vecbuff[0], &len, nullptr, 0) == 0) { - filesystem::canonical(strbuff, ec); + path = filesystem::canonical(&vecbuff[0], ec); } else BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) } - - return ""; + else + BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) + return path; } #else diff --git a/include/boost/process/v2/ext/impl/env.ipp b/include/boost/process/v2/ext/impl/env.ipp index a6d87e6fc..f27da4ddb 100644 --- a/include/boost/process/v2/ext/impl/env.ipp +++ b/include/boost/process/v2/ext/impl/env.ipp @@ -21,6 +21,15 @@ #include #endif +#if defined(__FreeBSD__) +#include +#include +#include +#include +#include +#include +#endif + BOOST_PROCESS_V2_BEGIN_NAMESPACE namespace detail {