Fix recursive attempts to open the log file in the GameLauncher (#1114)

* Fix recursive attempts to open the log file in the GameLauncher

The AzFramework Application has been updated to default the @user@ and
@log@ aliases to the <engine-root>/user and <engine-root>/user/log
folder respectively if a project isn't set.

Fixed the SystemFile class to support negative offsets if Seek() as per
standard seek function such as fseek

Updated the CrySystem CLog class to use SystemFile instead of FileIOBase
to avoid any asserts that would cause CLog::OpenFile to be recursively
called infinitely

* Removing unused Force Closed variable

* AZ::IO::SystemFile build fixes for Unix platforms. Added a copy constructor for LUAEditorContextInterface.h to fix the LuaEditor build

* Adding missing includes to the WindowsAPI and Android SystemFile headers
This commit is contained in:
lumberyard-employee-dm
2021-06-03 22:36:34 -05:00
committed by GitHub
parent 30eedc1c55
commit 4a1d713227
15 changed files with 200 additions and 115 deletions
+51 -55
View File
@@ -26,6 +26,7 @@
#include <AzFramework/IO/FileOperations.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/Path/Path.h>
#ifdef WIN32
#include <time.h>
@@ -88,7 +89,6 @@ CLog::CLog(ISystem* pSystem)
m_nMainThreadId = CryGetCurrentThreadId();
m_logFileHandle = AZ::IO::InvalidHandle;
#if defined(KEEP_LOG_FILE_OPEN)
m_bFirstLine = true;
#endif
@@ -162,35 +162,6 @@ void CLog::RegisterConsoleVariables()
REGISTER_COMMAND("log_flush", &LogFlushFile, 0, "Flush the log file");
#endif
}
/*
//testbed
{
int iSave0 = m_pLogVerbosity->GetIVal();
int iSave1 = m_pLogFileVerbosity->GetIVal();
for(int i=0;i<=4;++i)
{
m_pLogVerbosity->Set(i);
m_pLogFileVerbosity->Set(i);
LogWithType(eAlways,"CLog selftest: Verbosity=%d FileVerbosity=%d",m_pLogVerbosity->GetIVal(),m_pLogFileVerbosity->GetIVal());
LogWithType(eAlways,"--------------");
LogWithType(eError,"eError");
LogWithType(eWarning,"eWarning");
LogWithType(eMessage,"eMessage");
LogWithType(eInput,"eInput");
LogWithType(eInputResponse,"eInputResponse");
LogWarning("LogWarning()");
LogError("LogError()");
LogWithType(eAlways,"--------------");
}
m_pLogVerbosity->Set(iSave0);
m_pLogFileVerbosity->Set(iSave1);
}
*/
#undef DEFAULT_VERBOSITY
}
@@ -210,7 +181,7 @@ CLog::~CLog()
UnregisterConsoleVariables();
CloseLogFile(true);
CloseLogFile();
}
void CLog::UnregisterConsoleVariables()
@@ -224,31 +195,36 @@ void CLog::UnregisterConsoleVariables()
}
//////////////////////////////////////////////////////////////////////////
void CLog::CloseLogFile([[maybe_unused]] bool forceClose)
void CLog::CloseLogFile()
{
if (m_logFileHandle != AZ::IO::InvalidHandle)
{
AZ::IO::FileIOBase::GetDirectInstance()->Close(m_logFileHandle);
m_logFileHandle = AZ::IO::InvalidHandle;
}
m_logFileHandle.Close();
}
//////////////////////////////////////////////////////////////////////////
AZ::IO::HandleType CLog::OpenLogFile(const char* filename, const char* mode)
bool CLog::OpenLogFile(const char* filename, int mode)
{
using namespace AZ::IO;
AZ_Assert(m_logFileHandle == AZ::IO::InvalidHandle, "Attempt to open log file when one is already open. This would lead to a handle leak.");
if ((!filename) || (filename[0] == 0))
if (m_logFileHandle.IsOpen())
{
return m_logFileHandle;
// Can only AZ_Assert if a file is open, otherwise the AZ_Assert
// would eventually lead to OpenLogFile being opened up again
AZ_Assert(false, "Attempt to open log file when one is already open. This would lead to a handle leak.");
return false;
}
if (filename == nullptr || filename[0] == '\0')
{
return false;
}
// it is assumed that @log@ points at the appropriate place (so for apple, to the user profile dir)
AZ::IO::FileIOBase::GetDirectInstance()->Open(filename, AZ::IO::GetOpenModeFromStringMode(mode), m_logFileHandle);
AZ::IO::FileIOBase* fileSystem = AZ::IO::FileIOBase::GetDirectInstance();
if (AZ::IO::FixedMaxPath logFilePath; fileSystem->ReplaceAlias(logFilePath, filename))
{
logFilePath = logFilePath.LexicallyNormal();
m_logFileHandle.Open(logFilePath.c_str(), mode);
}
if (m_logFileHandle != AZ::IO::InvalidHandle)
if (m_logFileHandle.IsOpen())
{
#if defined(KEEP_LOG_FILE_OPEN)
m_bFirstLine = true;
@@ -257,11 +233,11 @@ AZ::IO::HandleType CLog::OpenLogFile(const char* filename, const char* mode)
else
{
#if defined(LINUX) || defined(APPLE)
syslog(LOG_NOTICE, "Failed to open log file [%s], mode [%s]", filename, mode);
syslog(LOG_NOTICE, "Failed to open log file [%s], mode [%d]", filename, mode);
#endif
}
return m_logFileHandle;
return m_logFileHandle.IsOpen();
}
//////////////////////////////////////////////////////////////////////////
@@ -1114,12 +1090,15 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
if (logToFile)
{
if (m_logFileHandle == AZ::IO::InvalidHandle)
if (!m_logFileHandle.IsOpen())
{
OpenLogFile(m_szFilename, "w+t");
constexpr auto openMode = AZ::IO::SystemFile::OpenMode::SF_OPEN_APPEND
| AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE
| AZ::IO::SystemFile::OpenMode::SF_OPEN_WRITE_ONLY;
OpenLogFile(m_szFilename, openMode);
}
if (m_logFileHandle != AZ::IO::InvalidHandle)
if (m_logFileHandle.IsOpen())
{
#if defined(KEEP_LOG_FILE_OPEN)
if (m_bFirstLine)
@@ -1130,9 +1109,9 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
if (bAdd)
{
// if adding to a prior line erase the \n at the end.
AZ::IO::FileIOBase::GetDirectInstance()->Seek(m_logFileHandle, -2, AZ::IO::SeekType::SeekFromEnd);
m_logFileHandle.Seek(-2, AZ::IO::SystemFile::SeekMode::SF_SEEK_END);
}
AZ::IO::FPutS(tempString.c_str(), m_logFileHandle);
m_logFileHandle.Write(tempString.c_str(), tempString.size());
#if !defined(KEEP_LOG_FILE_OPEN)
CloseLogFile();
#endif
@@ -1383,6 +1362,23 @@ bool CLog::SetFileName(const char* fileNameOrAbsolutePath, bool backupLogs)
CreateBackupFile();
AZ::IO::FileIOBase* fileSystem = AZ::IO::FileIOBase::GetDirectInstance();
AZ::IO::FixedMaxPath newLogFilePath;
if (fileSystem->ReplaceAlias(newLogFilePath, m_szFilename))
{
newLogFilePath = newLogFilePath.LexicallyNormal();
}
if (m_logFileHandle.IsOpen() && newLogFilePath != m_logFileHandle.Name())
{
constexpr auto openMode = AZ::IO::SystemFile::OpenMode::SF_OPEN_APPEND
| AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE
| AZ::IO::SystemFile::OpenMode::SF_OPEN_WRITE_ONLY;
if(AZ::IO::SystemFile newLogFile; newLogFile.Open(m_szFilename, openMode))
{
m_logFileHandle = AZStd::move(newLogFile);
}
}
return true;
}
@@ -1537,9 +1533,9 @@ const char* CLog::GetModuleFilter()
void CLog::FlushAndClose()
{
#if defined(KEEP_LOG_FILE_OPEN)
if (m_logFileHandle)
if (m_logFileHandle.IsOpen())
{
CloseLogFile(true);
CloseLogFile();
}
#endif
}
+7 -11
View File
@@ -137,8 +137,8 @@ private: // -------------------------------------------------------------------
void LogStringToConsole(const char* szString, ELogType logType, bool bAdd) {}
#endif // !defined(EXCLUDE_NORMAL_LOG)
AZ::IO::HandleType OpenLogFile(const char* filename, const char* mode);
void CloseLogFile(bool force = false);
bool OpenLogFile(const char* filename, int mode);
void CloseLogFile();
// will format the message into m_szTemp
void FormatMessage(const char* szCommand, ...) PRINTF_PARAMS(2, 3);
@@ -152,15 +152,11 @@ private: // -------------------------------------------------------------------
virtual const char* GetAssetScopeString();
#endif
ISystem* m_pSystem; //
float m_fLastLoadingUpdateTime; // for non-frequent streamingEngine update
//char m_szTemp[MAX_TEMP_LENGTH_SIZE]; //
char m_szFilename[MAX_FILENAME_SIZE]; // can be with path
mutable char m_sBackupFilename[MAX_FILENAME_SIZE]; // can be with path
AZ::IO::HandleType m_logFileHandle;
CryStackStringT<char, 32> m_LogMode; //mode m_pLogFile has been opened with
AZ::IO::HandleType m_errFileHandle;
int m_nErrCount;
ISystem* m_pSystem; //
float m_fLastLoadingUpdateTime; // for non-frequent streamingEngine update
char m_szFilename[MAX_FILENAME_SIZE]; // can be with path
mutable char m_sBackupFilename[MAX_FILENAME_SIZE]; // can be with path
AZ::IO::SystemFile m_logFileHandle;
bool m_backupLogs;
+1 -1
View File
@@ -1208,7 +1208,7 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
{
assetPlatform = AzFramework::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, R"(A valid asset platform is missing in "%s/assets" key in the SettingsRegistry.)""\n"
R"(This typically done by setting he "assets" field in the bootstrap.cfg for within a .setreg file)""\n"
R"(This typically done by setting the "assets" field within a .setreg file)""\n"
R"(A fallback of %s will be used.)",
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
assetPlatform.c_str());
+39 -21
View File
@@ -30,7 +30,7 @@ namespace Platform
using FileHandleType = SystemFile::FileHandleType;
void Seek(FileHandleType handle, const SystemFile* systemFile, SizeType offset, SystemFile::SeekMode mode);
void Seek(FileHandleType handle, const SystemFile* systemFile, SystemFile::SeekSizeType offset, SystemFile::SeekMode mode);
SystemFile::SizeType Tell(FileHandleType handle, const SystemFile* systemFile);
bool Eof(FileHandleType handle, const SystemFile* systemFile);
AZ::u64 ModificationTime(FileHandleType handle, const SystemFile* systemFile);
@@ -68,9 +68,8 @@ void SystemFile::CreatePath(const char* fileName)
}
SystemFile::SystemFile()
: m_handle{ AZ_TRAIT_SYSTEMFILE_INVALID_HANDLE }
{
m_fileName[0] = '\0';
m_handle = AZ_TRAIT_SYSTEMFILE_INVALID_HANDLE;
}
SystemFile::~SystemFile()
@@ -81,6 +80,25 @@ SystemFile::~SystemFile()
}
}
SystemFile::SystemFile(SystemFile&& other)
: SystemFile{}
{
AZStd::swap(m_fileName, other.m_fileName);
AZStd::swap(m_handle, other.m_handle);
}
SystemFile& SystemFile::operator=(SystemFile&& other)
{
// Close the current file and take over the SystemFile handle and filename
Close();
m_fileName = AZStd::move(other.m_fileName);
m_handle = AZStd::move(other.m_handle);
other.m_fileName = {};
other.m_handle = AZ_TRAIT_SYSTEMFILE_INVALID_HANDLE;
return *this;
}
bool SystemFile::Open(const char* fileName, int mode, int platformFlags)
{
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Open - %s", fileName);
@@ -88,42 +106,42 @@ bool SystemFile::Open(const char* fileName, int mode, int platformFlags)
if (fileName) // If we reopen the file we are allowed to have NULL file name
{
if (strlen(fileName) > AZ_ARRAY_SIZE(m_fileName) - 1)
if (strlen(fileName) > m_fileName.max_size())
{
EBUS_EVENT(FileIOEventBus, OnError, this, nullptr, 0);
return false;
}
// store the filename
azsnprintf(m_fileName, AZ_ARRAY_SIZE(m_fileName), "%s", fileName);
m_fileName = fileName;
}
if (FileIOBus::HasHandlers())
{
bool isOpen = false;
bool isHandled = false;
EBUS_EVENT_RESULT(isHandled, FileIOBus, OnOpen, *this, m_fileName, mode, platformFlags, isOpen);
EBUS_EVENT_RESULT(isHandled, FileIOBus, OnOpen, *this, m_fileName.c_str(), mode, platformFlags, isOpen);
if (isHandled)
{
return isOpen;
}
}
AZ_Assert(!IsOpen(), "This file (%s) is already open!", m_fileName);
AZ_Assert(!IsOpen(), "This file (%s) is already open!", m_fileName.c_str());
return PlatformOpen(mode, platformFlags);
}
bool SystemFile::ReOpen(int mode, int platformFlags)
{
AZ_Assert(strlen(m_fileName) > 0, "Missing filename. You must call open first!");
AZ_Assert(!m_fileName.empty(), "Missing filename. You must call open first!");
return Open(0, mode, platformFlags);
}
void SystemFile::Close()
{
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Close - %s", m_fileName);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Close - %s", m_fileName);
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Close - %s", m_fileName.c_str());
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Close - %s", m_fileName.c_str());
if (FileIOBus::HasHandlers())
{
@@ -138,9 +156,9 @@ void SystemFile::Close()
PlatformClose();
}
void SystemFile::Seek(SizeType offset, SeekMode mode)
void SystemFile::Seek(SeekSizeType offset, SeekMode mode)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Seek - %s:%i", m_fileName, offset);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Seek - %s:%i", m_fileName.c_str(), offset);
if (FileIOBus::HasHandlers())
{
@@ -167,15 +185,15 @@ bool SystemFile::Eof()
AZ::u64 SystemFile::ModificationTime()
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::ModTime - %s", m_fileName);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::ModTime - %s", m_fileName.c_str());
return Platform::ModificationTime(m_handle, this);
}
SystemFile::SizeType SystemFile::Read(SizeType byteSize, void* buffer)
{
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Read - %s:%i", m_fileName, byteSize);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Read - %s:%i", m_fileName, byteSize);
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Read - %s:%i", m_fileName.c_str(), byteSize);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Read - %s:%i", m_fileName.c_str(), byteSize);
if (FileIOBus::HasHandlers())
{
@@ -193,8 +211,8 @@ SystemFile::SizeType SystemFile::Read(SizeType byteSize, void* buffer)
SystemFile::SizeType SystemFile::Write(const void* buffer, SizeType byteSize)
{
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Write - %s:%i", m_fileName, byteSize);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Write - %s:%i", m_fileName, byteSize);
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Write - %s:%i", m_fileName.c_str(), byteSize);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Write - %s:%i", m_fileName.c_str(), byteSize);
if (FileIOBus::HasHandlers())
{
@@ -212,14 +230,14 @@ SystemFile::SizeType SystemFile::Write(const void* buffer, SizeType byteSize)
void SystemFile::Flush()
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Flush - %s", m_fileName);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Flush - %s", m_fileName.c_str());
Platform::Flush(m_handle, this);
}
SystemFile::SizeType SystemFile::Length() const
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Length - %s", m_fileName);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Length - %s", m_fileName.c_str());
return Platform::Length(m_handle, this);
}
@@ -379,9 +397,9 @@ namespace
HasPosixEnumOption(PermissionModeFlags::Write);
#undef HasPosixEnumOption
}
}
FileDescriptorRedirector::FileDescriptorRedirector(int sourceFileDescriptor)
: m_sourceFileDescriptor(sourceFileDescriptor)
{
+13 -8
View File
@@ -12,10 +12,11 @@
#pragma once
#include <AzCore/base.h>
#include <AzCore/std/function/function_fwd.h>
#include <AzCore/std/string/string.h>
#include <AzCore/IO/Path/Path_fwd.h>
#include <AzCore/IO/SystemFile_Platform.h>
#include <AzCore/std/function/function_fwd.h>
#include <AzCore/std/string/fixed_string.h>
// Establish a consistent size that works across platforms. It's actually larger than this
// on platforms we support, but this is a good least common denominator
@@ -51,11 +52,15 @@ namespace AZ
};
using SizeType = AZ::IO::Internal::SizeType;
using SeekSizeType = AZ::IO::Internal::SeekSizeType;
using FileHandleType = AZ::IO::Internal::FileHandleType;
SystemFile();
~SystemFile();
SystemFile(SystemFile&&);
SystemFile& operator=(SystemFile&&);
/**
* Opens a file.
* \param fileName full file name including path
@@ -69,7 +74,7 @@ namespace AZ
/// Closes a file, if file already close it has no effect.
void Close();
/// Seek in current file.
void Seek(SizeType offset, SeekMode mode);
void Seek(SeekSizeType offset, SeekMode mode);
/// Get the cursor position in the current file.
SizeType Tell();
/// Is the cursor at the end of the file?
@@ -87,7 +92,7 @@ namespace AZ
/// Return disc offset if possible, otherwise 0
SizeType DiskOffset() const;
/// Return file name or NULL if file is not open.
AZ_FORCE_INLINE const char* Name() const { return m_fileName; }
AZ_FORCE_INLINE const char* Name() const { return m_fileName.c_str(); }
bool IsOpen() const;
/// Return native handle to the file.
@@ -124,12 +129,12 @@ namespace AZ
private:
static void CreatePath(const char * fileName);
bool PlatformOpen(int mode, int platformFlags);
void PlatformClose();
FileHandleType m_handle;
char m_fileName[AZ_MAX_PATH_LEN];
FileHandleType m_handle;
AZ::IO::FixedMaxPathString m_fileName;
};
/**
@@ -641,6 +641,8 @@ namespace AZ::SettingsRegistryMergeUtils
}
else
{
// Set the default ProjectUserPath to the <engine-root>/user directory
registry.Set(FilePathKey_ProjectUserPath, (engineRoot / "user").LexicallyNormal().Native());
AZ_TracePrintf("SettingsRegistryMergeUtils",
R"(Project path isn't set in the Settings Registry at "%.*s". Project-related filepaths will not be set)" "\n",
aznumeric_cast<int>(projectPathKey.size()), projectPathKey.data());
@@ -101,7 +101,7 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags)
createPath = (mode & SF_OPEN_CREATE_PATH) == SF_OPEN_CREATE_PATH;
}
bool isApkFile = AZ::Android::Utils::IsApkPath(m_fileName);
bool isApkFile = AZ::Android::Utils::IsApkPath(m_fileName.c_str());
if (createPath)
{
@@ -111,19 +111,19 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags)
return false;
}
CreatePath(m_fileName);
CreatePath(m_fileName.c_str());
}
int errorCode = 0;
if (isApkFile)
{
AZ::u64 size = 0;
m_handle = AZ::Android::APKFileHandler::Open(m_fileName, openMode, size);
m_handle = AZ::Android::APKFileHandler::Open(m_fileName.c_str(), openMode, size);
errorCode = EACCES; // general error when a file can't be opened from inside the APK
}
else
{
m_handle = fopen(m_fileName, openMode);
m_handle = fopen(m_fileName.c_str(), openMode);
errorCode = errno;
}
@@ -233,7 +233,7 @@ namespace Platform
}
}
void Seek(FileHandleType handle, const SystemFile* systemFile, SizeType offset, SystemFile::SeekMode mode)
void Seek(FileHandleType handle, const SystemFile* systemFile, SystemFile::SeekSizeType offset, SystemFile::SeekMode mode)
{
if (handle != PlatformSpecificInvalidHandle)
{
@@ -15,6 +15,9 @@
#include <cstdio>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <AzCore/std/typetraits/underlying_type.h>
namespace AZ
{
@@ -23,6 +26,7 @@ namespace AZ
namespace Internal
{
using SizeType = AZ::u64;
using SeekSizeType = AZ::s64;
using FileHandleType = FILE*;
}
@@ -37,7 +41,7 @@ namespace AZ
#else
Temporary = 0, // (Not applicable for this platform) Applies only when used with CREAT. Creates a file as temporary; the file is deleted when the last file descriptor is closed. PermissionMode equired when CREAT is specified.
#endif
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
Truncate = O_TRUNC, // Opens a file and truncates it to zero length; the file must have write permission. Cannot be specified with RDONLY.
// Note: The TRUNC flag destroys the contents of the specified file.
@@ -22,9 +22,10 @@ namespace AZ
namespace Internal
{
using SizeType = AZ::u64;
using SeekSizeType = AZ::s64;
using FileHandleType = int;
}
namespace PosixInternal
{
enum class OpenFlags : int
@@ -36,7 +37,7 @@ namespace AZ
#else
Temporary = 0, // (Not applicable for this platform) Applies only when used with CREAT. Creates a file as temporary; the file is deleted when the last file descriptor is closed. PermissionMode equired when CREAT is specified.
#endif
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
Truncate = O_TRUNC, // Opens a file and truncates it to zero length; the file must have write permission. Cannot be specified with RDONLY.
// Note: The TRUNC flag destroys the contents of the specified file.
@@ -13,6 +13,9 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <AzCore/std/typetraits/underlying_type.h>
namespace AZ
{
@@ -21,6 +24,7 @@ namespace AZ
namespace Internal
{
using SizeType = AZ::u64;
using SeekSizeType = AZ::s64;
using FileHandleType = int;
}
@@ -35,7 +39,7 @@ namespace AZ
#else
Temporary = 0, // (Not applicable for this platform) Applies only when used with CREAT. Creates a file as temporary; the file is deleted when the last file descriptor is closed. PermissionMode equired when CREAT is specified.
#endif
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
Exclusive = O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
Truncate = O_TRUNC, // Opens a file and truncates it to zero length; the file must have write permission. Cannot be specified with RDONLY.
// Note: The TRUNC flag destroys the contents of the specified file.
@@ -86,9 +86,9 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags)
if (createPath)
{
CreatePath(m_fileName);
CreatePath(m_fileName.c_str());
}
m_handle = open(m_fileName, desiredAccess, permissions);
m_handle = open(m_fileName.c_str(), desiredAccess, permissions);
if (m_handle == PlatformSpecificInvalidHandle)
{
@@ -119,7 +119,7 @@ namespace Platform
{
using FileHandleType = AZ::IO::SystemFile::FileHandleType;
void Seek(FileHandleType handle, const SystemFile* systemFile, SizeType offset, SystemFile::SeekMode mode)
void Seek(FileHandleType handle, const SystemFile* systemFile, SystemFile::SeekSizeType offset, SystemFile::SeekMode mode)
{
if (handle != PlatformSpecificInvalidHandle)
{
@@ -209,19 +209,19 @@ bool SystemFile::PlatformOpen(int mode, int platformFlags)
if (createPath)
{
CreatePath(m_fileName);
CreatePath(m_fileName.c_str());
}
# ifdef _UNICODE
wchar_t fileNameW[AZ_MAX_PATH_LEN];
size_t numCharsConverted;
m_handle = INVALID_HANDLE_VALUE;
if (mbstowcs_s(&numCharsConverted, fileNameW, m_fileName, AZ_ARRAY_SIZE(fileNameW) - 1) == 0)
if (mbstowcs_s(&numCharsConverted, fileNameW, m_fileName.c_str(), AZ_ARRAY_SIZE(fileNameW) - 1) == 0)
{
m_handle = CreateFileW(fileNameW, dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
}
# else //!_UNICODE
m_handle = CreateFile(m_fileName, dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
m_handle = CreateFile(m_fileName.c_str(), dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
# endif // !_UNICODE
if (m_handle == INVALID_HANDLE_VALUE)
@@ -261,7 +261,7 @@ namespace Platform
{
using FileHandleType = AZ::IO::SystemFile::FileHandleType;
void Seek(FileHandleType handle, const SystemFile* systemFile, SizeType offset, SystemFile::SeekMode mode)
void Seek(FileHandleType handle, const SystemFile* systemFile, SystemFile::SeekSizeType offset, SystemFile::SeekMode mode)
{
if (handle != PlatformSpecificInvalidHandle)
{
@@ -13,6 +13,9 @@
#include <fcntl.h>
#include <corecrt_io.h>
#include <sys/stat.h>
#include <AzCore/std/typetraits/underlying_type.h>
namespace AZ
{
@@ -21,6 +24,7 @@ namespace AZ
namespace Internal
{
using SizeType = AZ::u64;
using SeekSizeType = AZ::s64;
using FileHandleType = void*;
}
@@ -31,7 +35,7 @@ namespace AZ
Append = _O_APPEND, // Moves the file pointer to the end of the file before every write operation.
Create = _O_CREAT, // Creates a file and opens it for writing. Has no effect if the file specified by filename exists. PermissionMode is required.
Temporary = _O_TEMPORARY, // Applies only when used with CREAT. Creates a file as temporary; the file is deleted when the last file descriptor is closed. PermissionMode equired when CREAT is specified.
Exclusive = _O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
Exclusive = _O_EXCL, // Applies only when used with CREAT. Returns an error value if a file specified by filename exists.
Truncate = _O_TRUNC, // Opens a file and truncates it to zero length; the file must have write permission. Cannot be specified with RDONLY.
// Note: The TRUNC flag destroys the contents of the specified file.
@@ -711,8 +711,8 @@ namespace AzFramework
}
}
AZ::IO::FixedMaxPath projectUserPath;
if (m_settingsRegistry->Get(projectUserPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectUserPath))
if (AZ::IO::FixedMaxPath projectUserPath;
m_settingsRegistry->Get(projectUserPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectUserPath))
{
fileIoBase->SetAlias("@user@", projectUserPath.c_str());
AZ::IO::FixedMaxPath projectLogPath = projectUserPath / "log";
@@ -721,6 +721,15 @@ namespace AzFramework
CreateUserCache(projectUserPath, *fileIoBase);
}
else
{
AZ::IO::FixedMaxPath fallbackLogPath = GetEngineRoot();
fallbackLogPath /= "user";
fileIoBase->SetAlias("@user@", fallbackLogPath.c_str());
fallbackLogPath /= "log";
fileIoBase->SetAlias("@log@", fallbackLogPath.c_str());
fileIoBase->CreatePath(fallbackLogPath.c_str());
}
}
}
@@ -70,6 +70,52 @@ namespace LUAEditor
, m_bIsModified(false)
, m_bIsBeingSaved(false)
, m_PresetLineAtOpen(1){}
// Copy constructor does not copy over open file handle
DocumentInfo(const DocumentInfo& other)
: m_assetId(other.m_assetId)
, m_scriptAsset(other.m_scriptAsset)
, m_assetName(other.m_assetName)
, m_displayName(other.m_displayName)
, m_lastKnownModTime(other.m_lastKnownModTime)
, m_sourceControlInfo(other.m_sourceControlInfo)
, m_bSourceControl_Ready(other.m_bSourceControl_Ready)
, m_bSourceControl_BusyGettingStats(other.m_bSourceControl_BusyGettingStats)
, m_bSourceControl_BusyRequestingEdit(other.m_bSourceControl_BusyRequestingEdit)
, m_bSourceControl_CanWrite(other.m_bSourceControl_CanWrite)
, m_bSourceControl_CanCheckOut(other.m_bSourceControl_CanCheckOut)
, m_bDataIsLoaded(other.m_bDataIsLoaded)
, m_bDataIsWritten(other.m_bDataIsWritten)
, m_bCloseAfterSave(other.m_bCloseAfterSave)
, m_bUntitledDocument(other.m_bUntitledDocument)
, m_bIsModified(other.m_bIsModified)
, m_bIsBeingSaved(other.m_bIsBeingSaved)
, m_PresetLineAtOpen(other.m_PresetLineAtOpen)
{}
DocumentInfo& operator=(const DocumentInfo& other)
{
m_assetId = other.m_assetId;
m_scriptAsset = other.m_scriptAsset;
m_assetName = other.m_assetName;
m_displayName = other.m_displayName;
m_lastKnownModTime = other.m_lastKnownModTime;
m_sourceControlInfo = other.m_sourceControlInfo;
m_bSourceControl_Ready = other.m_bSourceControl_Ready;
m_bSourceControl_BusyGettingStats = other.m_bSourceControl_BusyGettingStats;
m_bSourceControl_BusyRequestingEdit = other.m_bSourceControl_BusyRequestingEdit;
m_bSourceControl_CanWrite = other.m_bSourceControl_CanWrite;
m_bSourceControl_CanCheckOut = other.m_bSourceControl_CanCheckOut;
m_bDataIsLoaded = other.m_bDataIsLoaded;
m_bDataIsWritten = other.m_bDataIsWritten;
m_bCloseAfterSave = other.m_bCloseAfterSave;
m_bUntitledDocument = other.m_bUntitledDocument;
m_bIsModified = other.m_bIsModified;
m_bIsBeingSaved = other.m_bIsBeingSaved;
m_PresetLineAtOpen = other.m_PresetLineAtOpen;
return *this;
}
};
class ContextInterface