SL-10153: Review and rationalize fetching paths from environment.

Use LLStringUtil::getenv() or getoptenv() whenever we fetch a string that will
be used as a pathname.

Use LLFile::tmpdir() instead of getenv("TEMP").

As an added extra-special bonus, finally clean up $TMP/llcontrol-test-zzzzzz
directories that have been accumulating every time we run a local build!
master
Nat Goodspeed 2018-12-14 15:38:13 -05:00
parent 132e708fec
commit c4096f670c
13 changed files with 115 additions and 148 deletions

View File

@ -30,6 +30,7 @@
#if LL_WINDOWS
#include "llwin32headerslean.h"
#include <stdlib.h> // Windows errno
#include <vector>
#else
#include <errno.h>
#endif
@ -134,8 +135,10 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc
{
// Only do any of this stuff (before LL_ENDL) if it will be logged.
LL_DEBUGS("LLFile") << empty;
const char* TEMP = getenv("TEMP");
if (! TEMP)
// would be nice to use LLDir for this, but dependency goes the
// wrong way
const char* TEMP = LLFile::tmpdir();
if (! (TEMP && *TEMP))
{
LL_CONT << "No $TEMP, not running 'handle'";
}
@ -341,17 +344,13 @@ const char *LLFile::tmpdir()
#if LL_WINDOWS
sep = '\\';
DWORD len = GetTempPathW(0, L"");
llutf16string utf16path;
utf16path.resize(len + 1);
len = GetTempPathW(static_cast<DWORD>(utf16path.size()), &utf16path[0]);
utf8path = utf16str_to_utf8str(utf16path);
std::vector<wchar_t> utf16path(MAX_PATH + 1);
GetTempPathW(utf16path.size(), &utf16path[0]);
utf8path = ll_convert_wide_to_string(&utf16path[0]);
#else
sep = '/';
char *env = getenv("TMPDIR");
utf8path = env ? env : "/tmp/";
utf8path = LLStringUtil::getenv("TMPDIR", "/tmp/");
#endif
if (utf8path[utf8path.size() - 1] != sep)
{

View File

@ -26,6 +26,7 @@
#include "wrapllerrs.h"
#include "llevents.h"
#include "llprocess.h"
#include "llstring.h"
#include "stringize.h"
#include "StringVec.h"
#include <functional>
@ -198,14 +199,12 @@ namespace tut
// basename.
reader_module(LLProcess::basename(
reader.getName().substr(0, reader.getName().length()-3))),
pPYTHON(getenv("PYTHON")),
PYTHON(pPYTHON? pPYTHON : "")
PYTHON(LLStringUtil::getenv("PYTHON"))
{
ensure("Set PYTHON to interpreter pathname", pPYTHON);
ensure("Set PYTHON to interpreter pathname", !PYTHON.empty());
}
NamedExtTempFile reader;
const std::string reader_module;
const char* pPYTHON;
const std::string PYTHON;
};
typedef test_group<llleap_data> llleap_group;

View File

@ -34,6 +34,7 @@
#include "stringize.h"
#include "llsdutil.h"
#include "llevents.h"
#include "llstring.h"
#include "wrapllerrs.h"
#if defined(LL_WINDOWS)
@ -142,8 +143,8 @@ struct PythonProcessLauncher
mDesc(desc),
mScript("py", script)
{
const char* PYTHON(getenv("PYTHON"));
tut::ensure("Set $PYTHON to the Python interpreter", PYTHON);
auto PYTHON(LLStringUtil::getenv("PYTHON"));
tut::ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty());
mParams.desc = desc + " script";
mParams.executable = PYTHON;

View File

@ -41,6 +41,7 @@ typedef U32 uint32_t;
#include <sys/stat.h>
#include <sys/wait.h>
#include "llprocess.h"
#include "llstring.h"
#endif
#include "boost/range.hpp"
@ -1705,8 +1706,8 @@ namespace tut
template <typename CONTENT>
void python(const std::string& desc, const CONTENT& script, int expect=0)
{
const char* PYTHON(getenv("PYTHON"));
ensure("Set $PYTHON to the Python interpreter", PYTHON);
auto PYTHON(LLStringUtil::getenv("PYTHON"));
ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty());
NamedTempFile scriptfile("py", script);
@ -1714,7 +1715,7 @@ namespace tut
std::string q("\"");
std::string qPYTHON(q + PYTHON + q);
std::string qscript(q + scriptfile.getName() + q);
int rc = _spawnl(_P_WAIT, PYTHON, qPYTHON.c_str(), qscript.c_str(), NULL);
int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(), NULL);
if (rc == -1)
{
char buffer[256];

View File

@ -34,6 +34,7 @@
#include "llsd.h"
#include "llhost.h"
#include "llexception.h"
#include "llstring.h"
#include "stringize.h"
#include <map>
#include <string>
@ -46,12 +47,7 @@ struct CommtestError: public LLException
static bool query_verbose()
{
const char* cbose = getenv("INTEGRATION_TEST_VERBOSE");
if (! cbose)
{
cbose = "1";
}
std::string strbose(cbose);
std::string strbose(LLStringUtil::getenv("INTEGRATION_TEST_VERBOSE", "1"));
return (! (strbose == "0" || strbose == "off" ||
strbose == "false" || strbose == "quiet"));
}

View File

@ -41,6 +41,7 @@
#include "llpumpio.h"
#include "lliosocket.h"
#include "llstring.h"
#include "stringize.h"
#include "llcleanup.h"
@ -50,13 +51,13 @@ namespace tut
{
public:
HTTPClientTestData():
PORT(getenv("PORT")),
PORT(LLStringUtil::getenv("PORT")),
// Turning NULL PORT into empty string doesn't make things work;
// that's just to keep this initializer from blowing up. We test
// PORT separately in the constructor body.
local_server(STRINGIZE("http://127.0.0.1:" << (PORT? PORT : "") << "/"))
local_server(STRINGIZE("http://127.0.0.1:" << PORT << "/"))
{
ensure("Set environment variable PORT to local test server port", PORT);
ensure("Set environment variable PORT to local test server port", !PORT.empty());
apr_pool_create(&mPool, NULL);
LLCurl::initClass(false);
mClientPump = new LLPumpIO(mPool);
@ -87,7 +88,7 @@ namespace tut
}
}
const char* const PORT;
const std::string PORT;
const std::string local_server;
private:

View File

@ -1063,33 +1063,24 @@ LLFontGL* LLFontGL::getFontDefault()
// static
std::string LLFontGL::getFontPathSystem()
{
std::string system_path;
#if LL_DARWIN
// HACK for Mac OS X
return "/System/Library/Fonts/";
// Try to figure out where the system's font files are stored.
char *system_root = NULL;
#if LL_WINDOWS
system_root = getenv("SystemRoot"); /* Flawfinder: ignore */
if (!system_root)
{
LL_WARNS() << "SystemRoot not found, attempting to load fonts from default path." << LL_ENDL;
}
#elif LL_WINDOWS
wchar_t *pwstr = NULL;
HRESULT okay = SHGetKnownFolderPath(FOLDERID_Fonts, 0, NULL, &pwstr);
if (SUCCEEDED(okay) && pwstr)
{
std::string fontpath(ll_convert_wide_to_string(pwstr));
// SHGetKnownFolderPath() contract requires us to free pwstr
CoTaskMemFree(pwstr);
return fontpath;
}
#endif
if (system_root)
{
system_path = llformat("%s/fonts/", system_root);
}
else
{
#if LL_WINDOWS
// HACK for windows 98/Me
system_path = "/WINDOWS/FONTS/";
#elif LL_DARWIN
// HACK for Mac OS X
system_path = "/System/Library/Fonts/";
#endif
}
return system_path;
LL_WARNS() << "Could not determine system fonts path" << LL_ENDL;
return {};
}

View File

@ -29,6 +29,7 @@
#include "lldir_linux.h"
#include "llerror.h"
#include "llrand.h"
#include "llstring.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@ -40,28 +41,24 @@ static std::string getCurrentUserHome(char* fallback)
{
const uid_t uid = getuid();
struct passwd *pw;
char *result_cstr = fallback;
pw = getpwuid(uid);
if ((pw != NULL) && (pw->pw_dir != NULL))
{
result_cstr = (char*) pw->pw_dir;
return pw->pw_dir;
}
LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
auto home_env = LLStringUtil::getoptenv("HOME");
if (home_env)
{
return *home_env;
}
else
{
LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */
if (home_env)
{
result_cstr = (char*) home_env;
}
else
{
LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL;
}
LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL;
return fallback;
}
return std::string(result_cstr);
}
@ -156,18 +153,18 @@ void LLDir_Linux::initAppDirs(const std::string &app_name,
if (!app_read_only_data_dir.empty())
{
mAppRODataDir = app_read_only_data_dir;
mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
mSkinBaseDir = add(mAppRODataDir, "skins");
}
mAppName = app_name;
std::string upper_app_name(app_name);
LLStringUtil::toUpper(upper_app_name);
char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */
auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR"));
if (app_home_env)
{
// user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
mOSUserAppDir = app_home_env;
mOSUserAppDir = *app_home_env;
}
else
{

View File

@ -29,6 +29,7 @@
#include "lldir_solaris.h"
#include "llerror.h"
#include "llrand.h"
#include "llstring.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@ -41,30 +42,28 @@
static std::string getCurrentUserHome(char* fallback)
{
// fwiw this exactly duplicates getCurrentUserHome() in lldir_linux.cpp...
// we should either derive both from LLDir_Posix or just axe Solaris.
const uid_t uid = getuid();
struct passwd *pw;
char *result_cstr = fallback;
pw = getpwuid(uid);
if ((pw != NULL) && (pw->pw_dir != NULL))
{
result_cstr = (char*) pw->pw_dir;
return pw->pw_dir;
}
LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
auto home_env = LLStringUtil::getoptenv("HOME");
if (home_env)
{
return *home_env;
}
else
{
LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */
if (home_env)
{
result_cstr = (char*) home_env;
}
else
{
LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL;
}
LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL;
return fallback;
}
return std::string(result_cstr);
}
@ -135,27 +134,15 @@ LLDir_Solaris::LLDir_Solaris()
//NOTE: Why force people to cd into the package directory?
// Look for SECONDLIFE env variable and use it, if set.
char *dcf = getenv("SECONDLIFE");
if(dcf != NULL){
(void)strcpy(path, dcf);
(void)strcat(path, "/bin"); //NOTE: make sure we point at the bin
mExecutableDir = strdup(path);
auto SECONDLIFE(LLDirUtil::getoptenv("SECONDLIFE"));
if(SECONDLIFE){
mExecutableDir = add(*SECONDLIFE, "bin"); //NOTE: make sure we point at the bin
}else{
// plunk a null at last '/' to get exec dir
char *s = execpath + strlen(execpath) -1;
while(*s != '/' && s != execpath){
--s;
}
if(s != execpath){
*s = (char)NULL;
mExecutableDir = strdup(execpath);
LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL;
}
mExecutableDir = getDirName(execpath);
LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL;
}
mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin";
mLLPluginDir = add(mExecutableDir, "llplugin");
// *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
mTempDir = "/tmp";
@ -175,17 +162,18 @@ void LLDir_Solaris::initAppDirs(const std::string &app_name,
if (!app_read_only_data_dir.empty())
{
mAppRODataDir = app_read_only_data_dir;
mSkinBaseDir = add(mAppRODataDir, "skins");
}
mAppName = app_name;
std::string upper_app_name(app_name);
LLStringUtil::toUpper(upper_app_name);
char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */
auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR"));
if (app_home_env)
{
// user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
mOSUserAppDir = app_home_env;
mOSUserAppDir = *app_home_env;
}
else
{

View File

@ -30,6 +30,7 @@
#include "lldir_win32.h"
#include "llerror.h"
#include "llstring.h"
#include "stringize.h"
#include "llfile.h"
#include <shlobj.h>
@ -55,17 +56,17 @@ namespace
{
switch (state)
{
boost::optional<std::string> prelog_name;
case prst::INIT:
// assume we failed, until we succeed
state = prst::SKIP;
// can't initialize within one case of a switch statement
const char* prelog_name;
prelog_name = getenv("PRELOG");
prelog_name = LLDirUtil::getoptenv("PRELOG");
if (! prelog_name)
// no PRELOG variable set, carry on
return;
prelogf = new std::ofstream(prelog_name, std::ios_base::app);
prelogf = new llofstream(*prelog_name, std::ios_base::app);
if (! (prelogf && prelogf->is_open()))
// can't complain to anybody; how?
return;
@ -95,13 +96,11 @@ LLDir_Win32::LLDir_Win32()
WCHAR w_str[MAX_PATH];
// Application Data is where user settings go. We rely on $APPDATA being
// correct; in fact the VMP makes a point of setting it properly, since
// Windows itself botches the job for non-ASCII usernames (MAINT-8087).
// Try using wide-character getenv()??
wchar_t *APPDATA = _wgetenv(L"APPDATA");
// correct.
auto APPDATA = LLStringUtil::getoptenv("APPDATA");
if (APPDATA)
{
mOSUserDir = ll_convert_wide_to_string(APPDATA, CP_UTF8);
mOSUserDir = *APPDATA;
}
PRELOG("APPDATA='" << mOSUserDir << "'");
// On Windows, we could have received a plain-ASCII pathname in which
@ -118,7 +117,7 @@ LLDir_Win32::LLDir_Win32()
if (SUCCEEDED(okay) && pwstr)
{
// But of course, only update mOSUserDir if SHGetKnownFolderPath() works.
mOSUserDir = ll_convert_wide_to_string(pwstr, CP_UTF8);
mOSUserDir = ll_convert_wide_to_string(pwstr);
// Not only that: update our environment so that child processes
// will see a reasonable value as well.
_wputenv_s(L"APPDATA", pwstr);
@ -136,11 +135,10 @@ LLDir_Win32::LLDir_Win32()
//
// We used to store the cache in AppData\Roaming, and the installer
// cleans up that version on upgrade. JC
// Again, try using wide-character getenv().
wchar_t *LOCALAPPDATA = _wgetenv(L"LOCALAPPDATA");
auto LOCALAPPDATA = LLStringUtil::getoptenv("LOCALAPPDATA");
if (LOCALAPPDATA)
{
mOSCacheDir = ll_convert_wide_to_string(LOCALAPPDATA, CP_UTF8);
mOSCacheDir = *LOCALAPPDATA;
}
PRELOG("LOCALAPPDATA='" << mOSCacheDir << "'");
// Windows really does not deal well with pathnames containing non-ASCII
@ -155,7 +153,7 @@ LLDir_Win32::LLDir_Win32()
if (SUCCEEDED(okay) && pwstr)
{
// But of course, only update mOSCacheDir if SHGetKnownFolderPath() works.
mOSCacheDir = ll_convert_wide_to_string(pwstr, CP_UTF8);
mOSCacheDir = ll_convert_wide_to_string(pwstr);
// Update our environment so that child processes will see a
// reasonable value as well.
_wputenv_s(L"LOCALAPPDATA", pwstr);

View File

@ -27,43 +27,31 @@
#include "linden_common.h"
#include "llsdserialize.h"
#include "llfile.h"
#include "stringize.h"
#include "../llcontrol.h"
#include "../test/lltut.h"
#include <memory>
#include <vector>
namespace tut
{
struct control_group
{
LLControlGroup* mCG;
std::unique_ptr<LLControlGroup> mCG;
std::string mTestConfigDir;
std::string mTestConfigFile;
std::vector<std::string> mCleanups;
static bool mListenerFired;
control_group()
{
mCG = new LLControlGroup("foo");
mCG.reset(new LLControlGroup("foo"));
LLUUID random;
random.generate();
// generate temp dir
std::ostringstream oStr;
#ifdef LL_WINDOWS
char* tmp_dir = getenv("TMP");
if(tmp_dir)
{
oStr << tmp_dir << "/llcontrol-test-" << random << "/";
}
else
{
oStr << "c:/tmp/llcontrol-test-" << random << "/";
}
#else
oStr << "/tmp/llcontrol-test-" << random << "/";
#endif
mTestConfigDir = oStr.str();
mTestConfigDir = STRINGIZE(LLFile::tmpdir() << "llcontrol-test-" << random << "/");
mTestConfigFile = mTestConfigDir + "settings.xml";
LLFile::mkdir(mTestConfigDir);
LLSD config;
@ -76,7 +64,12 @@ namespace tut
~control_group()
{
//Remove test files
delete mCG;
for (auto filename : mCleanups)
{
LLFile::remove(filename);
}
LLFile::remove(mTestConfigFile);
LLFile::rmdir(mTestConfigDir);
}
void writeSettingsFile(const LLSD& config)
{
@ -118,6 +111,7 @@ namespace tut
ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13);
LLControlGroup test_cg("foo2");
std::string temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml");
mCleanups.push_back(temp_test_file);
mCG->saveToFile(temp_test_file.c_str(), TRUE);
results = test_cg.loadFromFile(temp_test_file.c_str());
ensure("number of changed settings loaded", (results == 1));
@ -139,6 +133,7 @@ namespace tut
ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13);
LLControlGroup test_cg("foo3");
std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml");
mCleanups.push_back(temp_test_file);
mCG->saveToFile(temp_test_file.c_str(), TRUE);
results = test_cg.loadFromFile(temp_test_file.c_str());
//If we haven't changed any settings, then we shouldn't have any settings to load
@ -153,7 +148,7 @@ namespace tut
ensure("number of settings", (results == 1));
mCG->getControl("TestSetting")->getSignal()->connect(boost::bind(&this->handleListenerTest));
mCG->setU32("TestSetting", 13);
ensure("listener fired on changed setting", mListenerFired);
ensure("listener fired on changed setting", mListenerFired);
}
}

View File

@ -31,6 +31,7 @@
#include "llui.h"
#include "llprocess.h"
#include "llsdutil.h"
#include "llstring.h"
#include <boost/foreach.hpp>
// static
@ -188,12 +189,12 @@ std::string LLExternalEditor::findCommand(
cmd = LLUI::sSettingGroups["config"]->getString(sSetting);
LL_INFOS() << "Using setting" << LL_ENDL;
}
else // otherwise use the path specified by the environment variable
else // otherwise use the path specified by the environment variable
{
char* env_var_val = getenv(env_var.c_str());
auto env_var_val(LLStringUtil::getoptenv(env_var));
if (env_var_val)
{
cmd = env_var_val;
cmd = *env_var_val;
LL_INFOS() << "Using env var " << env_var << LL_ENDL;
}
}

View File

@ -33,6 +33,7 @@
#include "llimagepng.h"
#include "llsdserialize.h"
#include "llstring.h"
// newview
#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
@ -264,6 +265,5 @@ void LLWebProfile::reportImageUploadStatus(bool ok)
std::string LLWebProfile::getAuthCookie()
{
// This is needed to test image uploads on Linux viewer built with OpenSSL 1.0.0 (0.9.8 works fine).
const char* debug_cookie = getenv("LL_SNAPSHOT_COOKIE");
return debug_cookie ? debug_cookie : sAuthCookie;
return LLStringUtil::getenv("LL_SNAPSHOT_COOKIE", sAuthCookie);
}