diff options
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r-- | src/libutil/util.cc | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 6bc64ae75a42..e12c4b258c25 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -167,7 +167,7 @@ Path dirOf(const Path & path) { Path::size_type pos = path.rfind('/'); if (pos == string::npos) - throw Error(format("invalid file name '%1%'") % path); + return "."; return pos == 0 ? "/" : Path(path, 0, pos); } @@ -468,7 +468,7 @@ static Lazy<Path> getHome2([]() { std::vector<char> buf(16384); struct passwd pwbuf; struct passwd * pw; - if (getpwuid_r(getuid(), &pwbuf, buf.data(), buf.size(), &pw) != 0 + if (getpwuid_r(geteuid(), &pwbuf, buf.data(), buf.size(), &pw) != 0 || !pw || !pw->pw_dir || !pw->pw_dir[0]) throw Error("cannot determine user's home directory"); homeDir = pw->pw_dir; @@ -496,6 +496,15 @@ Path getConfigDir() return configDir; } +std::vector<Path> getConfigDirs() +{ + Path configHome = getConfigDir(); + string configDirs = getEnv("XDG_CONFIG_DIRS"); + std::vector<Path> result = tokenizeString<std::vector<string>>(configDirs, ":"); + result.insert(result.begin(), configHome); + return result; +} + Path getDataDir() { @@ -927,6 +936,8 @@ pid_t startProcess(std::function<void()> fun, const ProcessOptions & options) throw SysError("setting death signal"); #endif restoreAffinity(); + if (options.restoreMountNamespace) + restoreMountNamespace(); fun(); } catch (std::exception & e) { try { @@ -1495,4 +1506,26 @@ std::unique_ptr<InterruptCallback> createInterruptCallback(std::function<void()> return std::unique_ptr<InterruptCallback>(res.release()); } +static AutoCloseFD fdSavedMountNamespace; + +void saveMountNamespace() +{ +#if __linux__ + std::once_flag done; + std::call_once(done, []() { + fdSavedMountNamespace = open("/proc/self/ns/mnt", O_RDONLY); + if (!fdSavedMountNamespace) + throw SysError("saving parent mount namespace"); + }); +#endif +} + +void restoreMountNamespace() +{ +#if __linux__ + if (fdSavedMountNamespace && setns(fdSavedMountNamespace.get(), CLONE_NEWNS) == -1) + throw SysError("restoring parent mount namespace"); +#endif +} + } |