forked from lix-project/lix
gc: Read arguments on darwin
This commit is contained in:
parent
8ce48856e8
commit
b02f1564d3
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <sys/proc_info.h>
|
#include <sys/proc_info.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
#include <libproc.h>
|
#include <libproc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -427,6 +428,8 @@ static void readProcfsRoots(const Path & storeDir, UncheckedRoots & unchecked)
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
static void readLibprocRoots(const Path & storeDir, UncheckedRoots & unchecked)
|
static void readLibprocRoots(const Path & storeDir, UncheckedRoots & unchecked)
|
||||||
{
|
{
|
||||||
|
auto storePathRegex = std::regex(quoteRegexChars(storeDir) + R"(/[0-9a-z]+[0-9a-zA-Z\+\-\._\?=]*)");
|
||||||
|
|
||||||
int pidBufSize = proc_listpids(PROC_ALL_PIDS, 0, nullptr, 0);
|
int pidBufSize = proc_listpids(PROC_ALL_PIDS, 0, nullptr, 0);
|
||||||
if (pidBufSize <= 0 || pidBufSize % sizeof(int) != 0)
|
if (pidBufSize <= 0 || pidBufSize % sizeof(int) != 0)
|
||||||
throw SysError("Listing PIDs");
|
throw SysError("Listing PIDs");
|
||||||
|
@ -497,12 +500,40 @@ static void readLibprocRoots(const Path & storeDir, UncheckedRoots & unchecked)
|
||||||
if ((errno == ESRCH) || (errno == EINVAL) || (errno == EPERM)) break;
|
if ((errno == ESRCH) || (errno == EINVAL) || (errno == EPERM)) break;
|
||||||
throw SysError("Getting pid %1% region path", pid);
|
throw SysError("Getting pid %1% region path", pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
unchecked[std::string(regionInfo.prp_vip.vip_path)].emplace("{libproc/region}");
|
unchecked[std::string(regionInfo.prp_vip.vip_path)].emplace("{libproc/region}");
|
||||||
|
|
||||||
nextAddr = regionInfo.prp_prinfo.pri_address + regionInfo.prp_prinfo.pri_size;
|
nextAddr = regionInfo.prp_prinfo.pri_address + regionInfo.prp_prinfo.pri_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Arguments and environment variables
|
||||||
|
// We can't read environment variables of binaries with with entitlements unless
|
||||||
|
// nix has the `com.apple.private.read-environment-variables` entitlement or SIP is off
|
||||||
|
// We can read arguments for all applications though.
|
||||||
|
|
||||||
|
// Yes, it's a sysctl, the proc_info and sysctl APIs are mostly similar,
|
||||||
|
// but both have exclusive capabilities
|
||||||
|
// We don't care about what is args and what is environment so we could use
|
||||||
|
// KERN_PROCARGS, but KERN_PROCARGS2 saves about 20ms in my testing
|
||||||
|
int sysctlName[3] = {CTL_KERN, KERN_PROCARGS2, pid};
|
||||||
|
size_t argsSize = 0;
|
||||||
|
if (sysctl(sysctlName, 3, nullptr, &argsSize, nullptr, 0) < 0) {
|
||||||
|
throw SysError("Reading pid %1% arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> args(argsSize);
|
||||||
|
|
||||||
|
if (sysctl(sysctlName, 3, args.data(), &argsSize, nullptr, 0) < 0) {
|
||||||
|
throw SysError("Reading pid %1% arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argsSize < args.size())
|
||||||
|
args.resize(argsSize);
|
||||||
|
|
||||||
|
auto env_end = std::sregex_iterator{};
|
||||||
|
for (auto i = std::sregex_iterator{args.begin(), args.end(), storePathRegex}; i != env_end; ++i)
|
||||||
|
unchecked[i->str()].emplace("{libproc/args}");
|
||||||
|
|
||||||
|
|
||||||
// TODO: per-thread cwds (apparently exist but I don't see them much)
|
// TODO: per-thread cwds (apparently exist but I don't see them much)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue