From 5002bf5660f41685fc0549880994f4b35440d535 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 20 Dec 2017 22:51:26 -0500 Subject: MAINT-8087: Use env vars from VMP for AppData\Roaming and Local. On Windows, when logged in with a non-ASCII username, every one of the three documented APIs -- SHGetSpecialFolderPath(), SHGetFolderPath() and SHGetKnownFolderPath() -- fails to retrieve any pathname at all. We cannot account for the fact that the oldest of these continues to work with the release viewer and within a Python script (though not, curiously, from a Python interactive session). With a non-ASCII username, they consistently fail when called from an Alex Ivy viewer build: "The filename, directory name, or volume label syntax is incorrect." Empirically, with a non-ASCII username, the preset APPDATA and LOCALAPPDATA environment variables are also useless, e.g. c:\Users\??????\AppData\Roaming where those are, yup, actual question marks. Empirically, the VMP is able to successfully call SHGetFolderPath() to retrieve both AppData\Roaming and AppData\Local. Therefore, we make the VMP set the APPDATA and LOCALAPPDATA environment variables to the UTF-8 encoded correct pathnames. Instead of calling SHGetSomethingFolderPath() at all, make LLDir_Win32 retrieve those environment variables. Make LLFile::mkdir() treat "directory already exists" as a success case. Every single call fell into one of two categories: either it didn't check success at all, or it tested specially to exempt errno == EEXIST. Migrate that test into mkdir(); eliminate it from call sites. Make LLDir::append() and add() convenience functions accept variadic arguments. Replace add(add()...) constructs, as well as clumsy concatenations of directory names and getDirDelimiter(), with simple variadic add() calls. --- indra/llcommon/llfile.cpp | 9 ++++++++- indra/llcommon/llfile.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 7b559861bb..8aa41035b9 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -182,7 +182,14 @@ int LLFile::mkdir(const std::string& dirname, int perms) int rc = ::mkdir(dirname.c_str(), (mode_t)perms); #endif // We often use mkdir() to ensure the existence of a directory that might - // already exist. Don't spam the log if it does. + // already exist. There is no known case in which we want to call out as + // an error the requested directory already existing. + if (rc < 0 && errno == EEXIST) + { + // this is not the error you want, move along + return 0; + } + // anything else might be a problem return warnif("mkdir", dirname, rc, EEXIST); } diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 37eb75881c..ba935b8714 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -69,6 +69,7 @@ public: // perms is a permissions mask like 0777 or 0700. In most cases it will // be overridden by the user's umask. It is ignored on Windows. + // mkdir() considers "directory already exists" to be SUCCESS. static int mkdir(const std::string& filename, int perms = 0700); static int rmdir(const std::string& filename); -- cgit v1.2.3