Skip to content
Snippets Groups Projects
Commit 8a351b04 authored by Rye Mutt's avatar Rye Mutt :bread:
Browse files

Large cleanup of LLFileSystem to remove error-prone api and file path usage

parent 5fd09518
No related branches found
No related tags found
No related merge requests found
...@@ -173,6 +173,70 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc ...@@ -173,6 +173,70 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc
return rc; return rc;
} }
int warnif(const std::string& desc, const boost::filesystem::path& filename, int rc, int accept = 0)
{
if (rc < 0)
{
// Capture errno before we start emitting output
int errn = errno;
// For certain operations, a particular errno value might be
// acceptable -- e.g. stat() could permit ENOENT, mkdir() could permit
// EEXIST. Don't warn if caller explicitly says this errno is okay.
if (errn != accept)
{
#if LL_WINDOWS
LL_WARNS("LLFile") << "Couldn't " << desc << " '" << ll_convert_wide_to_string(filename.native())
<< "' (errno " << errn << "): " << strerr(errn) << LL_ENDL;
#else
LL_WARNS("LLFile") << "Couldn't " << desc << " '" << filename.native()
<< "' (errno " << errn << "): " << strerr(errn) << LL_ENDL;
#endif
}
#if 0 && LL_WINDOWS // turn on to debug file-locking problems
// If the problem is "Permission denied," maybe it's because another
// process has the file open. Try to find out.
if (errn == EACCES) // *not* EPERM
{
// Only do any of this stuff (before LL_ENDL) if it will be logged.
LL_DEBUGS("LLFile") << empty;
// 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'";
}
else
{
std::string tf(TEMP);
tf += "\\handle.tmp";
// http://technet.microsoft.com/en-us/sysinternals/bb896655
std::string cmd(STRINGIZE("handle \"" << filename
// "openfiles /query /v | fgrep -i \"" << filename
<< "\" > \"" << tf << '"'));
LL_CONT << cmd;
if (system(cmd.c_str()) != 0)
{
LL_CONT << "\nDownload 'handle.exe' from http://technet.microsoft.com/en-us/sysinternals/bb896655";
}
else
{
std::ifstream inf(tf);
std::string line;
while (std::getline(inf, line))
{
LL_CONT << '\n' << line;
}
}
LLFile::remove(tf);
}
LL_CONT << LL_ENDL;
}
#endif // LL_WINDOWS hack to identify processes holding file open
}
return rc;
}
// static // static
int LLFile::mkdir(const std::string& dirname, int perms) int LLFile::mkdir(const std::string& dirname, int perms)
{ {
...@@ -220,6 +284,16 @@ LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawfind ...@@ -220,6 +284,16 @@ LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawfind
#endif #endif
} }
// static
LLFILE* LLFile::fopen(const boost::filesystem::path& filename, MODE_T accessmode) /* Flawfinder: ignore */
{
#if LL_WINDOWS
return _wfopen(filename.c_str(), accessmode);
#else
return ::fopen(filename.c_str(), accessmode); /* Flawfinder: ignore */
#endif
}
LLFILE* LLFile::_fsopen(const std::string& filename, const char* mode, int sharingFlag) LLFILE* LLFile::_fsopen(const std::string& filename, const char* mode, int sharingFlag)
{ {
#if LL_WINDOWS #if LL_WINDOWS
...@@ -254,6 +328,16 @@ int LLFile::remove(const std::string& filename, int supress_error) ...@@ -254,6 +328,16 @@ int LLFile::remove(const std::string& filename, int supress_error)
return warnif("remove", filename, rc, supress_error); return warnif("remove", filename, rc, supress_error);
} }
int LLFile::remove(const boost::filesystem::path& filename, int supress_error)
{
#if LL_WINDOWS
int rc = _wremove(filename.c_str());
#else
int rc = ::remove(filename.c_str());
#endif
return warnif("remove", filename, rc, supress_error);
}
int LLFile::rename(const std::string& filename, const std::string& newname, int supress_error) int LLFile::rename(const std::string& filename, const std::string& newname, int supress_error)
{ {
#if LL_WINDOWS #if LL_WINDOWS
...@@ -297,6 +381,48 @@ int LLFile::rename(const std::string& filename, const std::string& newname, int ...@@ -297,6 +381,48 @@ int LLFile::rename(const std::string& filename, const std::string& newname, int
return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error); return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error);
} }
int LLFile::rename(const boost::filesystem::path& filename, const boost::filesystem::path& newname, int supress_error)
{
#if LL_WINDOWS
int rc = _wrename(filename.c_str(), newname.c_str());
return warnif(STRINGIZE("rename to '" << ll_convert_wide_to_string(newname.native()) << "' from"), filename, rc, supress_error);
#else
int rc = ::rename(filename.c_str(), newname.c_str());
// Note: This workaround generalises the solution previously applied in llxfer_file.
// In doing this we add more failure modes to the operation, the copy can fail, the unlink can fail, in fact the copy can fail for multiple reasons.
// "A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools." - Douglas Adams, Mostly harmless
if (rc)
{
S32 error_number = errno;
LL_INFOS("LLFile") << "Rename failure (" << error_number << ") - " << filename << " to " << newname << LL_ENDL;
if (EXDEV == error_number)
{
if (copy(filename, newname) == true) // sigh in their wisdom LL decided that copy returns bool true not 0 whjen no error. using == true to make that clear.
{
LL_INFOS("LLFile") << "Rename across mounts not supported; copying+unlinking the file instead." << LL_ENDL;
rc = LLFile::remove(filename);
if (rc)
{
LL_WARNS("LLFile") << "unlink failed during copy/unlink workaround. Please check for stray file: " << filename << LL_ENDL;
}
}
else
{
LL_WARNS("LLFile") << "Copy failure during rename workaround for rename " << filename << " to " << newname << " (check both filenames and maunally rectify)" << LL_ENDL;
}
rc = 0; // We need to reset rc here to avoid the higher level function taking corrective action on what could be bad files.
}
else
{
LL_WARNS("LLFile") << "Rename fatally failed, no workaround attempted for errno="
<< errno << "." << LL_ENDL;
// rc will propogate alllowing corrective action above. Not entirely happy with this but it is what already happens so we're not making it worse.
}
}
return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error);
#endif
}
bool LLFile::copy(const std::string& from, const std::string& to) bool LLFile::copy(const std::string& from, const std::string& to)
{ {
bool copied = false; bool copied = false;
...@@ -341,6 +467,18 @@ int LLFile::stat(const std::string& filename, llstat* filestatus) ...@@ -341,6 +467,18 @@ int LLFile::stat(const std::string& filename, llstat* filestatus)
return warnif("stat", filename, rc, ENOENT); return warnif("stat", filename, rc, ENOENT);
} }
int LLFile::stat(const boost::filesystem::path& filename, llstat* filestatus)
{
#if LL_WINDOWS
int rc = _wstat(filename.c_str(), filestatus);
#else
int rc = ::stat(filename.c_str(), filestatus);
#endif
// We use stat() to determine existence (see isfile(), isdir()).
// Don't spam the log if the subject pathname doesn't exist.
return warnif("stat", filename, rc, ENOENT);
}
bool LLFile::isdir(const std::string& filename) bool LLFile::isdir(const std::string& filename)
{ {
llstat st; llstat st;
......
...@@ -58,11 +58,20 @@ typedef struct stat llstat; ...@@ -58,11 +58,20 @@ typedef struct stat llstat;
#include "llstring.h" // safe char* -> std::string conversion #include "llstring.h" // safe char* -> std::string conversion
#include <boost/filesystem.hpp>
#if LL_WINDOWS
#define MODE_T const wchar_t*
#else
#define MODE_T const char*
#endif
class LL_COMMON_API LLFile class LL_COMMON_API LLFile
{ {
public: public:
// All these functions take UTF8 path/filenames. // All these functions take UTF8 path/filenames.
static LLFILE* fopen(const std::string& filename,const char* accessmode); /* Flawfinder: ignore */ static LLFILE* fopen(const std::string& filename,const char* accessmode); /* Flawfinder: ignore */
static LLFILE* fopen(const boost::filesystem::path& filename, MODE_T accessmode); /* Flawfinder: ignore */
static LLFILE* _fsopen(const std::string& filename,const char* accessmode,int sharingFlag); static LLFILE* _fsopen(const std::string& filename,const char* accessmode,int sharingFlag);
static int close(LLFILE * file); static int close(LLFILE * file);
...@@ -74,10 +83,13 @@ class LL_COMMON_API LLFile ...@@ -74,10 +83,13 @@ class LL_COMMON_API LLFile
static int rmdir(const std::string& filename); static int rmdir(const std::string& filename);
static int remove(const std::string& filename, int supress_error = 0); static int remove(const std::string& filename, int supress_error = 0);
static int remove(const boost::filesystem::path& filename, int supress_error = 0);
static int rename(const std::string& filename,const std::string& newname, int supress_error = 0); static int rename(const std::string& filename,const std::string& newname, int supress_error = 0);
static int rename(const boost::filesystem::path& filename, const boost::filesystem::path& newname, int supress_error = 0);
static bool copy(const std::string& from, const std::string& to); static bool copy(const std::string& from, const std::string& to);
static int stat(const std::string& filename,llstat* file_status); static int stat(const std::string& filename, llstat* file_status);
static int stat(const boost::filesystem::path& filename, llstat* file_status);
static bool isdir(const std::string& filename); static bool isdir(const std::string& filename);
static bool isfile(const std::string& filename); static bool isfile(const std::string& filename);
static LLFILE * _Fiopen(const std::string& filename, static LLFILE * _Fiopen(const std::string& filename,
......
...@@ -36,84 +36,52 @@ ...@@ -36,84 +36,52 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait"); #ifndef TEXT
#define TEXT(quote)
#endif
LLFileSystem::LLFileSystem(const LLUUID& file_id, const LLAssetType::EType file_type, S32 mode) LLFileSystem::LLFileSystem(const LLUUID& file_id, const LLAssetType::EType file_type, S32 mode)
: mFileID(file_id),
mFileType(file_type),
mPosition(0),
mMode(mode),
mBytesRead(0)
{ {
mFileType = file_type; const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type);
mFileID = file_id; #if LL_WINDOWS
mPosition = 0; mFilePath = ll_convert_string_to_wide(filename);
mBytesRead = 0; #else
mMode = mode; mFilePath = filename;
#endif
} }
// static // static
bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType file_type) bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType file_type)
{ {
const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type); LLFileSystem file(file_id, file_type, READ);
return file.exists();
llstat stat;
if (LLFile::stat(filename, &stat) == 0)
{
return S_ISREG(stat.st_mode) && stat.st_size > 0;
}
return false;
} }
// static // static
bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type) bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type)
{ {
const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type); LLFileSystem file(file_id, file_type, READ_WRITE);
return file.remove();
LLFile::remove(filename, ENOENT);
return true;
} }
// static // static
bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type, bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type,
const LLUUID& new_file_id, const LLAssetType::EType new_file_type) const LLUUID& new_file_id, const LLAssetType::EType new_file_type)
{ {
const std::string old_filename = LLDiskCache::metaDataToFilepath(old_file_id, old_file_type); LLFileSystem file(old_file_id, old_file_type, READ_WRITE);
const std::string new_filename = LLDiskCache::metaDataToFilepath(new_file_id, new_file_type); return file.rename(new_file_id, new_file_type);
// Rename needs the new file to not exist.
LLFile::remove(new_filename, ENOENT);
if (LLFile::rename(old_filename, new_filename) != 0)
{
// We would like to return FALSE here indicating the operation
// failed but the original code does not and doing so seems to
// break a lot of things so we go with the flow...
//return FALSE;
LL_WARNS() << "Failed to rename " << old_file_id << " to " << new_file_id << " reason: " << strerror(errno) << LL_ENDL;
}
return TRUE;
}
// static
S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type)
{
const std::string filename = LLDiskCache::metaDataToFilepath(file_id, file_type);
S32 file_size = 0;
llstat stat;
if (LLFile::stat(filename, &stat) == 0)
{
file_size = stat.st_size;
}
return file_size;
} }
BOOL LLFileSystem::read(U8* buffer, S32 bytes) BOOL LLFileSystem::read(U8* buffer, S32 bytes)
{ {
BOOL success = TRUE; BOOL success = TRUE;
const std::string filename = LLDiskCache::metaDataToFilepath(mFileID, mFileType); LLUniqueFile filep = LLFile::fopen(mFilePath, TEXT("rb"));
LLUniqueFile filep = LLFile::fopen(filename, "rb");
if (filep) if (filep)
{ {
fseek(filep, mPosition, SEEK_SET); fseek(filep, mPosition, SEEK_SET);
...@@ -158,7 +126,7 @@ BOOL LLFileSystem::read(U8* buffer, S32 bytes) ...@@ -158,7 +126,7 @@ BOOL LLFileSystem::read(U8* buffer, S32 bytes)
// even though we are reading and not writing because this is the // even though we are reading and not writing because this is the
// way the cache works - it relies on a valid "last accessed time" for // way the cache works - it relies on a valid "last accessed time" for
// each file so it knows how to remove the oldest, unused files // each file so it knows how to remove the oldest, unused files
updateFileAccessTime(filename); updateFileAccessTime();
return success; return success;
} }
...@@ -175,13 +143,11 @@ BOOL LLFileSystem::eof() ...@@ -175,13 +143,11 @@ BOOL LLFileSystem::eof()
BOOL LLFileSystem::write(const U8* buffer, S32 bytes) BOOL LLFileSystem::write(const U8* buffer, S32 bytes)
{ {
const std::string filename = LLDiskCache::metaDataToFilepath(mFileID, mFileType);
BOOL success = FALSE; BOOL success = FALSE;
if (mMode == APPEND) if (mMode == APPEND)
{ {
LLUniqueFile filep = LLFile::fopen(filename, "ab"); LLUniqueFile filep = LLFile::fopen(mFilePath, TEXT("ab"));
if (filep) if (filep)
{ {
fwrite((const void*)buffer, bytes, 1, filep); fwrite((const void*)buffer, bytes, 1, filep);
...@@ -191,7 +157,7 @@ BOOL LLFileSystem::write(const U8* buffer, S32 bytes) ...@@ -191,7 +157,7 @@ BOOL LLFileSystem::write(const U8* buffer, S32 bytes)
} }
else else
{ {
LLUniqueFile filep = LLFile::fopen(filename, "wb"); LLUniqueFile filep = LLFile::fopen(mFilePath, TEXT("wb"));
if (filep) if (filep)
{ {
fwrite((const void*)buffer, bytes, 1, filep); fwrite((const void*)buffer, bytes, 1, filep);
...@@ -242,7 +208,14 @@ S32 LLFileSystem::tell() const ...@@ -242,7 +208,14 @@ S32 LLFileSystem::tell() const
S32 LLFileSystem::getSize() S32 LLFileSystem::getSize()
{ {
return LLFileSystem::getFileSize(mFileID, mFileType); S32 file_size = 0;
llstat stat;
if (LLFile::stat(mFilePath.c_str(), &stat) == 0)
{
file_size = stat.st_size;
}
return file_size;
} }
S32 LLFileSystem::getMaxSize() S32 LLFileSystem::getMaxSize()
...@@ -253,22 +226,50 @@ S32 LLFileSystem::getMaxSize() ...@@ -253,22 +226,50 @@ S32 LLFileSystem::getMaxSize()
BOOL LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_type) BOOL LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_type)
{ {
LLFileSystem::renameFile(mFileID, mFileType, new_id, new_type); #if LL_WINDOWS
boost::filesystem::path new_filename = ll_convert_string_to_wide(LLDiskCache::metaDataToFilepath(new_id, new_type));
#else
boost::filesystem::path new_filename = LLDiskCache::metaDataToFilepath(new_id, new_type);
#endif
// Rename needs the new file to not exist.
LLFile::remove(new_filename, ENOENT);
if (LLFile::rename(mFilePath, new_filename) != 0)
{
// We would like to return FALSE here indicating the operation
// failed but the original code does not and doing so seems to
// break a lot of things so we go with the flow...
//return FALSE;
LL_WARNS() << "Failed to rename " << mFileID << " to " << new_id << " reason: " << strerror(errno) << LL_ENDL;
}
mFileID = new_id; mFileID = new_id;
mFileType = new_type; mFileType = new_type;
mFilePath = std::move(new_filename);
return TRUE; return TRUE;
} }
BOOL LLFileSystem::remove() BOOL LLFileSystem::remove()
{ {
LLFileSystem::removeFile(mFileID, mFileType); LLFile::remove(mFilePath, ENOENT);
return TRUE; return TRUE;
} }
void LLFileSystem::updateFileAccessTime(const std::string& file_path) BOOL LLFileSystem::exists()
{
llstat stat;
if (LLFile::stat(mFilePath, &stat) == 0)
{
return S_ISREG(stat.st_mode) && stat.st_size > 0;
}
return false;
}
void LLFileSystem::updateFileAccessTime()
{ {
/** /**
* Threshold in time_t units that is used to decide if the last access time * Threshold in time_t units that is used to decide if the last access time
...@@ -284,14 +285,8 @@ void LLFileSystem::updateFileAccessTime(const std::string& file_path) ...@@ -284,14 +285,8 @@ void LLFileSystem::updateFileAccessTime(const std::string& file_path)
// current time // current time
const std::time_t cur_time = std::time(nullptr); const std::time_t cur_time = std::time(nullptr);
#if LL_WINDOWS
boost::filesystem::path path(ll_convert_string_to_wide(file_path));
#else
boost::filesystem::path path(file_path);
#endif
// file last write time // file last write time
const std::time_t last_write_time = boost::filesystem::last_write_time(path); const std::time_t last_write_time = boost::filesystem::last_write_time(mFilePath);
// delta between cur time and last time the file was written // delta between cur time and last time the file was written
const std::time_t delta_time = cur_time - last_write_time; const std::time_t delta_time = cur_time - last_write_time;
...@@ -300,6 +295,6 @@ void LLFileSystem::updateFileAccessTime(const std::string& file_path) ...@@ -300,6 +295,6 @@ void LLFileSystem::updateFileAccessTime(const std::string& file_path)
// before the last one // before the last one
if (delta_time > time_threshold) if (delta_time > time_threshold)
{ {
boost::filesystem::last_write_time(path, cur_time); boost::filesystem::last_write_time(mFilePath, cur_time);
} }
} }
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include "llassettype.h" #include "llassettype.h"
#include "lldiskcache.h" #include "lldiskcache.h"
#include <boost/filesystem.hpp>
class LLFileSystem class LLFileSystem
{ {
public: public:
...@@ -52,19 +54,19 @@ class LLFileSystem ...@@ -52,19 +54,19 @@ class LLFileSystem
S32 getMaxSize(); S32 getMaxSize();
BOOL rename(const LLUUID& new_id, const LLAssetType::EType new_type); BOOL rename(const LLUUID& new_id, const LLAssetType::EType new_type);
BOOL remove(); BOOL remove();
BOOL exists();
/** /**
* Update the "last write time" of a file to "now". This must be called whenever a * Update the "last write time" of a file to "now". This must be called whenever a
* file in the cache is read (not written) so that the last time the file was * file in the cache is read (not written) so that the last time the file was
* accessed is up to date (This is used in the mechanism for purging the cache) * accessed is up to date (This is used in the mechanism for purging the cache)
*/ */
void updateFileAccessTime(const std::string& file_path); void updateFileAccessTime();
static bool getExists(const LLUUID& file_id, const LLAssetType::EType file_type); static bool getExists(const LLUUID& file_id, const LLAssetType::EType file_type);
static bool removeFile(const LLUUID& file_id, const LLAssetType::EType file_type); static bool removeFile(const LLUUID& file_id, const LLAssetType::EType file_type);
static bool renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type, static bool renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type,
const LLUUID& new_file_id, const LLAssetType::EType new_file_type); const LLUUID& new_file_id, const LLAssetType::EType new_file_type);
static S32 getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type);
public: public:
enum enum
...@@ -76,8 +78,9 @@ class LLFileSystem ...@@ -76,8 +78,9 @@ class LLFileSystem
}; };
protected: protected:
LLAssetType::EType mFileType; boost::filesystem::path mFilePath;
LLUUID mFileID; LLUUID mFileID;
LLAssetType::EType mFileType;
S32 mPosition; S32 mPosition;
S32 mMode; S32 mMode;
S32 mBytesRead; S32 mBytesRead;
......
...@@ -890,7 +890,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID) ...@@ -890,7 +890,7 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID)
std::string full_path = getLocalizedDirectory() + path; std::string full_path = getLocalizedDirectory() + path;
std::string floater_lang = "EN"; std::string floater_lang = "EN";
llstat dummy; llstat dummy;
if(!LLFile::stat(full_path.c_str(), &dummy)) // if the file does not exist if(!LLFile::stat(full_path, &dummy)) // if the file does not exist
{ {
floater_lang = getLocStr(ID); floater_lang = getLocStr(ID);
} }
...@@ -965,7 +965,7 @@ void LLFloaterUIPreview::onClickEditFloater() ...@@ -965,7 +965,7 @@ void LLFloaterUIPreview::onClickEditFloater()
// stat file to see if it exists (some localized versions may not have it there are no diffs, and then we try to open an nonexistent file) // stat file to see if it exists (some localized versions may not have it there are no diffs, and then we try to open an nonexistent file)
llstat dummy; llstat dummy;
if(LLFile::stat(file_path.c_str(), &dummy)) // if the file does not exist if(LLFile::stat(file_path, &dummy)) // if the file does not exist
{ {
popupAndPrintWarning("No file for this floater exists in the selected localization. Opening the EN version instead."); popupAndPrintWarning("No file for this floater exists in the selected localization. Opening the EN version instead.");
file_path = get_xui_dir() + mDelim + "en" + mDelim + file_name; // open the en version instead, by default file_path = get_xui_dir() + mDelim + "en" + mDelim + file_name; // open the en version instead, by default
...@@ -1119,7 +1119,7 @@ void LLFloaterUIPreview::onClickToggleDiffHighlighting() ...@@ -1119,7 +1119,7 @@ void LLFloaterUIPreview::onClickToggleDiffHighlighting()
} }
llstat dummy; llstat dummy;
if(LLFile::stat(path_in_textfield.c_str(), &dummy) && !error) // check if the file exists (empty check is reduntant but useful for the informative error message) if(LLFile::stat(path_in_textfield, &dummy) && !error) // check if the file exists (empty check is reduntant but useful for the informative error message)
{ {
std::string warning = std::string("Unable to highlight differences because an invalid path to a difference file was provided:\"") + path_in_textfield + "\""; std::string warning = std::string("Unable to highlight differences because an invalid path to a difference file was provided:\"") + path_in_textfield + "\"";
popupAndPrintWarning(warning); popupAndPrintWarning(warning);
......
...@@ -186,7 +186,7 @@ void LLViewerAssetStorage::storeAssetData( ...@@ -186,7 +186,7 @@ void LLViewerAssetStorage::storeAssetData(
else else
{ {
// LLAssetStorage metric: Successful Request // LLAssetStorage metric: Successful Request
S32 size = LLFileSystem::getFileSize(asset_id, asset_type); S32 size = vfile.getSize();
const char *message = "Added to upload queue"; const char *message = "Added to upload queue";
reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message ); reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment