From dcb0fec2ef0be7cdce6e5002d28ea5c87d0b67f3 Mon Sep 17 00:00:00 2001 From: sago007 Date: Mon, 21 Sep 2015 19:50:22 +0200 Subject: [PATCH] Updated the home lookup in Linux to fallback to pwd if HOME is not set and ignore HOME if root --- sago/platform_folders.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/sago/platform_folders.cpp b/sago/platform_folders.cpp index c3024d8..b7d5779 100644 --- a/sago/platform_folders.cpp +++ b/sago/platform_folders.cpp @@ -61,6 +61,9 @@ static std::string GetAppDataLocal() { #else #include #include +#include +#include +#include //Typically Linux. For easy reading the comments will just say Linux but should work with most *nixes static void throwOnRelative(const char* envName, const char* envValue) { @@ -71,11 +74,28 @@ static void throwOnRelative(const char* envName, const char* envValue) { } } +/** + * Retrives the effective user's home dir. + * If the user is running as root we ignore the HOME environment. It works badly with sudo. + * Writing to $HOME as root implies security concerns that a multiplatform program cannot be assumed to handle. + * @return The home directory. HOME environment is respected for non-root users if it exists. + */ static std::string getHome() { std::string res; - const char* tempRes = getenv("HOME"); + int uid = getuid(); + const char* homeEnv = getenv("HOME"); + if ( uid != 0 && homeEnv) { + //We only acknowlegde HOME if not root. + res = homeEnv; + return res; + } + struct passwd *pw = getpwuid(uid); + if (!pw) { + throw std::runtime_error("Unable to get passwd struct."); + } + const char* tempRes = pw->pw_dir; if (!tempRes) { - throw std::runtime_error("The environment HOME is not defined"); + throw std::runtime_error("User has no home directory"); } res = tempRes; return res;