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__
|
||||
#include <sys/proc_info.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <libproc.h>
|
||||
#endif
|
||||
|
||||
|
@ -427,6 +428,8 @@ static void readProcfsRoots(const Path & storeDir, UncheckedRoots & unchecked)
|
|||
#ifdef __APPLE__
|
||||
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);
|
||||
if (pidBufSize <= 0 || pidBufSize % sizeof(int) != 0)
|
||||
throw SysError("Listing PIDs");
|
||||
|
@ -497,12 +500,40 @@ static void readLibprocRoots(const Path & storeDir, UncheckedRoots & unchecked)
|
|||
if ((errno == ESRCH) || (errno == EINVAL) || (errno == EPERM)) break;
|
||||
throw SysError("Getting pid %1% region path", pid);
|
||||
}
|
||||
|
||||
unchecked[std::string(regionInfo.prp_vip.vip_path)].emplace("{libproc/region}");
|
||||
|
||||
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)
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue