diff options
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r-- | src/libutil/util.cc | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 1c19938a8..28df30fef 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -29,6 +29,7 @@ #ifdef __APPLE__ #include <sys/syscall.h> +#include <mach-o/dyld.h> #endif #ifdef __linux__ @@ -574,6 +575,20 @@ Path getHome() static Path homeDir = []() { auto homeDir = getEnv("HOME"); + if (homeDir) { + // Only use $HOME if doesn't exist or is owned by the current user. + struct stat st; + int result = stat(homeDir->c_str(), &st); + if (result != 0) { + if (errno != ENOENT) { + warn("couldn't stat $HOME ('%s') for reason other than not existing ('%d'), falling back to the one defined in the 'passwd' file", *homeDir, errno); + homeDir.reset(); + } + } else if (st.st_uid != geteuid()) { + warn("$HOME ('%s') is not owned by you, falling back to the one defined in the 'passwd' file", *homeDir); + homeDir.reset(); + } + } if (!homeDir) { std::vector<char> buf(16384); struct passwd pwbuf; @@ -619,6 +634,27 @@ Path getDataDir() } +std::optional<Path> getSelfExe() +{ + static auto cached = []() -> std::optional<Path> + { + #if __linux__ + return readLink("/proc/self/exe"); + #elif __APPLE__ + char buf[1024]; + uint32_t size = sizeof(buf); + if (_NSGetExecutablePath(buf, &size) == 0) + return buf; + else + return std::nullopt; + #else + return std::nullopt; + #endif + }(); + return cached; +} + + Paths createDirs(const Path & path) { Paths created; |