Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Less dependency on libprocstat and various corrections. #373

Merged
merged 6 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 3 additions & 61 deletions include/boost/process/v2/ext/impl/cmd.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,8 @@
#include <cstdio>
#endif

#if defined(__FreeBSD__)
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/user.h>
#include <libprocstat.h>
#endif

#if (defined(__DragonFly__) || defined(__OpenBSD__))
#if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__))
#include <fcntl.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysctl.h>
Expand Down Expand Up @@ -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<struct procstat, cl_proc_stat> 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<struct kinfo_proc, proc_info_close> 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)
{
Expand Down
75 changes: 44 additions & 31 deletions include/boost/process/v2/ext/impl/cwd.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@
#endif

#if defined(__FreeBSD__)
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <cstring>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <libprocstat.h>
#endif

#if (defined(__NetBSD__) || defined(__OpenBSD__))
Expand Down Expand Up @@ -128,39 +127,52 @@ 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;
}

#elif defined(__DragonFly__)

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<char> 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\" " +
Expand Down Expand Up @@ -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;
Expand All @@ -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<char> 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
Expand Down
9 changes: 9 additions & 0 deletions include/boost/process/v2/ext/impl/env.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
#include <cstdio>
#endif

#if defined(__FreeBSD__)
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/user.h>
#include <libprocstat.h>
#endif

BOOST_PROCESS_V2_BEGIN_NAMESPACE

namespace detail {
Expand Down
Loading