diff --git a/Aurora.json b/Aurora.json index c1ed4a30..b803ebda 100644 --- a/Aurora.json +++ b/Aurora.json @@ -13,7 +13,8 @@ "linkSources": "Source/Alloc.cpp", "actions": [ { - "if": "win32", + "if_": "win32", + "filter": { "platforms": "win32"} , "then": { "links": ["Bcrypt.lib", "UxTheme.lib"] } diff --git a/Include/Aurora/Debug/Debug.hpp b/Include/Aurora/Debug/Debug.hpp index 5186f0e9..3c529506 100644 --- a/Include/Aurora/Debug/Debug.hpp +++ b/Include/Aurora/Debug/Debug.hpp @@ -14,6 +14,8 @@ namespace Aurora::Debug { + using OSError_t = AuPair; + /** Retrieves a print-friendly callstack of the last trap (either innocent exception or fatal mem access)
On Win32, this information is always available
@@ -34,7 +36,7 @@ namespace Aurora::Debug /** Retrieve the last system error (IE: Win32, GetLastError()) */ - AUKN_SYM AuString GetLastSystemMessage(); + AUKN_SYM OSError_t GetLastSystemMessage(); /** Prints the current error state of the thread including:
diff --git a/Include/Aurora/IO/FS/Resources.hpp b/Include/Aurora/IO/FS/Resources.hpp index da28af7c..65dc1979 100644 --- a/Include/Aurora/IO/FS/Resources.hpp +++ b/Include/Aurora/IO/FS/Resources.hpp @@ -10,16 +10,35 @@ namespace Aurora::IO::FS { /** - Suffixes a global read/writable path with nameSpace and a splitter - */ - AUKN_SYM bool GetSystemDomain(AuString& path); + * @brief Provides an application specific storage path for sharing data amongst Aurora applications sharing the same branding info (defer to the init structure) + */ + AUKN_SYM bool GetSystemDomain(AuString &path); /** - Suffixes a global read/writable path with within a home/sandbox directory + * @brief Provides an application specific storage path for local application data, isolated for your Aurora application brand info (defer to the init structure) */ - AUKN_SYM bool GetProfileDomain(AuString& path); + AUKN_SYM bool GetProfileDomain(AuString &path); - AUKN_SYM bool GetSystemResourcePath(const AuString& fileName, AuString& path); + AUKN_SYM bool GetSystemResourcePath(const AuString &fileName, AuString &path); + /** + * @brief Pulls the application directory as defined by the operating system standard file system hierarchy + */ + AUKN_SYM bool GetAppData(AuString &path); + + /** + * @brief Pulls the users home directory, untouched + */ + AUKN_SYM bool GetUserHome(AuString &path); + + /** + * @brief Global application data that requires no special permissions to access + */ + AUKN_SYM bool GetWritableAppdata(AuString &path); + + /** + * @brief Global application data that requires special permissions to access, usually configured by a system account during installation + */ + AUKN_SYM bool GetRootAppdata(AuString &path); } \ No newline at end of file diff --git a/Include/Aurora/Locale/Locale.hpp b/Include/Aurora/Locale/Locale.hpp index 1bc6eb8c..8d1dd1e4 100644 --- a/Include/Aurora/Locale/Locale.hpp +++ b/Include/Aurora/Locale/Locale.hpp @@ -16,10 +16,10 @@ namespace Aurora::Locale { LocalizationInfo(const AuString& language, const AuString& country, const AuString& codeset, const ECodePage codePage) : language(language), country(country), codeset(codeset), codepage(codePage) {} - const AuString& language; - const AuString& country; - const AuString& codeset; - const ECodePage codepage; + const AuString& language; /// ISO 639 + const AuString& country; /// ISO 3166 + const AuString& codeset; /// + const ECodePage codepage; /// Potentially eSysUnk; noting that eSysUnk is valid and handlable by the internal backend }; /* diff --git a/Include/AuroraMacros.hpp b/Include/AuroraMacros.hpp index 75f9f790..028ffc52 100644 --- a/Include/AuroraMacros.hpp +++ b/Include/AuroraMacros.hpp @@ -121,6 +121,12 @@ #endif #endif +#if !defined(NO__INLINE) + #if !defined(auline) + #define auline AU_INLINE + #endif +#endif + #if !defined(AU_FWD) #define AU_FWD(var) std::forward(var) #endif diff --git a/Source/Debug/Debug.cpp b/Source/Debug/Debug.cpp index 294fb7c2..4f197318 100644 --- a/Source/Debug/Debug.cpp +++ b/Source/Debug/Debug.cpp @@ -15,7 +15,13 @@ namespace Aurora::Debug { + static StackTrace gLastStackTrace; + static AuUInt32 gStackTraceFence; + static AuUInt32 gFenceId; + static AuThreadPrimitives::SpinLock gLock; + static AuString gLastExceptionMessage; static AuUInt32 gFenceOSError = -1; + AuUInt32 GetOSErrorFence() { return gFenceOSError; @@ -28,6 +34,7 @@ namespace Aurora::Debug AuString ret; #if defined(AURORA_PLATFORM_WIN32) char *err = nullptr; + if (!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, @@ -66,6 +73,7 @@ namespace Aurora::Debug ret.second = GetOSErrorStringWin32(lastError.first); gFenceOSError++; + gFenceId++; return lastError = ret; } @@ -116,9 +124,9 @@ namespace Aurora::Debug return gFenceCError; } - AuOptional TryFetchCError() + AuOptional TryFetchCError() { - static int lastError = 0; + static AuUInt32 lastError = 0; auto errorNumber = errno; if (!errorNumber) @@ -132,15 +140,16 @@ namespace Aurora::Debug } gFenceCError++; + gFenceId++; return lastError = errorNumber; } - AuOptional TryGetOrFetchCError() + AuOptional TryGetOrFetchCError() { - static AuOptional lastErrorError; + static AuOptional lastErrorError; static AuOptional lastErrorFence; - AuOptional tempError = TryFetchCError(); + AuOptional tempError = TryFetchCError(); if (!tempError) { @@ -161,9 +170,40 @@ namespace Aurora::Debug return tempError; } + void ReportStackTrace(const StackTrace& trace, const AuString& message) + { + AU_LOCK_GUARD(gLock); + gLastStackTrace = trace; + gLastExceptionMessage = message; + gStackTraceFence++; + gFenceId++; + } + AuUInt32 GetFenceId() { - return GetCErrorFence() << 8 ^ GetOSErrorFence(); // preserve lowest 8 bits, or in new additional bits, overlapping bits can get fucked + return gFenceId; + } + + AUKN_SYM AuString GetLastErrorStack() + { + return StringifyStackTrace(GetLastStackTrace()); + } + + AUKN_SYM StackTrace GetLastStackTrace() + { + AU_LOCK_GUARD(gLock); + return gLastStackTrace; + } + + AUKN_SYM AuString GetLastException() + { + AU_LOCK_GUARD(gLock); + return gLastExceptionMessage; + } + + AUKN_SYM OSError_t GetLastSystemMessage() + { + return TryGetOrFetchOSError().value_or(OSError_t{}); } AUKN_SYM void PrintError() @@ -204,7 +244,7 @@ namespace Aurora::Debug AUKN_SYM void _PushError(AuUInt address, EFailureCategory category, const char *msg) { - LastError error{ address, category, msg ? msg : "" }; + LastError error {address, category, msg ? msg : ""}; // Oi, developer #if defined(DEBUG) diff --git a/Source/Debug/Debug.hpp b/Source/Debug/Debug.hpp index b6aa0af1..6792a22a 100644 --- a/Source/Debug/Debug.hpp +++ b/Source/Debug/Debug.hpp @@ -16,20 +16,19 @@ namespace Aurora::Debug AuString dbg; }; - using OSError_t = AuPair; AuUInt32 GetOSErrorFence(); AuOptional TryGetOrFetchOSError(); AuUInt32 GetCErrorFence(); - AuOptional TryGetOrFetchCError(); + AuOptional TryGetOrFetchCError(); - void ReportStackTrace(const StackTrace &trace); + void ReportStackTrace(const StackTrace &trace, const AuString &message); AuOptional TryFetchOSError(); - AuOptional TryFetchCError(); + AuOptional TryFetchCError(); void CheckErrors(); diff --git a/Source/Debug/ExceptionWatcher.Win32.cpp b/Source/Debug/ExceptionWatcher.Win32.cpp index b45c803f..a8890fc0 100644 --- a/Source/Debug/ExceptionWatcher.Win32.cpp +++ b/Source/Debug/ExceptionWatcher.Win32.cpp @@ -328,6 +328,8 @@ namespace Aurora::Debug } + ReportStackTrace(entry.wincxx.stack.backtrace, entry.wincxx.str); + #if defined(STAGING) || defined(DEBUG) bool isInternal = true; #else diff --git a/Source/Debug/Panic.cpp b/Source/Debug/Panic.cpp index eec377b5..707fa4c2 100644 --- a/Source/Debug/Panic.cpp +++ b/Source/Debug/Panic.cpp @@ -88,7 +88,7 @@ namespace Aurora::Debug #if defined(AURORA_COMPILER_GCC) || defined(AURORA_COMPILER_CLANG) __builtin_trap(); #else - std::exit(0xDEAD); + std::terminate(); #endif #endif } diff --git a/Source/IO/FS/Resources.cpp b/Source/IO/FS/Resources.cpp index 3b62e38d..bd4c45ed 100644 --- a/Source/IO/FS/Resources.cpp +++ b/Source/IO/FS/Resources.cpp @@ -24,8 +24,12 @@ namespace Aurora::IO::FS #if defined(AURORA_PLATFORM_WIN32) static void Win32FixGlobalAppDataAcl(const std::string &path); #endif - + static AuString gHomeDirectory; + static AuString gUserHomeDirectory; + static AuString gUserWritableAppData; + static AuString gGlobalWritableAppDirectory; + static AuString gAdminWritableAppDirectory; static AuString gApplicationData; static AuOptional gSystemLibPath; static AuOptional gSystemLibPath2; @@ -120,12 +124,15 @@ namespace Aurora::IO::FS } return Locale::ConvertFromWChar(directory); } - + static void SetNamespaceDirectories() { gHomeDirectory = GetSpecialDir(FOLDERID_RoamingAppData); gApplicationData = GetSpecialDir(FOLDERID_ProgramData); gSystemLibPath = GetSpecialDir(FOLDERID_System); + gUserHomeDirectory = GetSpecialDir(FOLDERID_Profile); + gAdminWritableAppDirectory = gApplicationData; + gUserWritableAppData = gHomeDirectory; } #elif defined(AURORA_PLATFORM_LINUX) || defined(AURORA_PLATFORM_BSD) @@ -186,6 +193,8 @@ namespace Aurora::IO::FS homedir = getpwuid(getuid())->pw_dir; } + gUserHomeDirectory = homedir; + // XDG Base Directory Specification // $XDG_CONFIG_HOME defines the base directory relative to which user-specific configuration files should be stored. If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used. // $XDG_DATA_HOME defines the base directory relative to which user-specific data files should be stored @@ -198,6 +207,10 @@ namespace Aurora::IO::FS // Fedora (2011?): https://fedoraproject.org/wiki/Features/UsrMove SetUnixPaths(gUserLibPath, gUserLibPath2, "/usr/local/lib"); SetUnixPaths(gSystemLibPath, gSystemLibPath2, "/usr/lib"); + + gGlobalWritableAppDirectory = "/opt"; + gAdminWritableAppDirectory = kUnixAppData; + gUserWritableAppData = gApplicationData; } #else @@ -279,6 +292,50 @@ namespace Aurora::IO::FS ChangeDir(); } + AUKN_SYM bool GetAppData(AuString &path) + { + path.clear(); + if (gUserWritableAppData.empty()) + { + return false; + } + path = gUserWritableAppData; + return true; + } + + AUKN_SYM bool GetUserHome(AuString &path) + { + path.clear(); + if (gUserHomeDirectory.empty()) + { + return false; + } + path = gUserHomeDirectory; + return true; + } + + AUKN_SYM bool GetWritableAppdata(AuString &path) + { + path.clear(); + if (gGlobalWritableAppDirectory.empty()) + { + return false; + } + path = gGlobalWritableAppDirectory; + return true; + } + + AUKN_SYM bool GetRootAppdata(AuString &path) + { + path.clear(); + if (gAdminWritableAppDirectory.empty()) + { + return false; + } + path = gAdminWritableAppDirectory; + return true; + } + #if defined(AURORA_PLATFORM_WIN32) static void Win32FixGlobalAppDataAcl(const std::string &path) { diff --git a/Source/Memory/Heap.cpp b/Source/Memory/Heap.cpp index 2f7a2536..8652d253 100644 --- a/Source/Memory/Heap.cpp +++ b/Source/Memory/Heap.cpp @@ -127,12 +127,12 @@ namespace Aurora::Memory heap_ = o1heapInit(base_, length, [this](const O1HeapInstance *const handle) -> void { - SysAssertDbg(this->mutex_ ? true : false, "missing mutex"); + SysAssertDbg(this->mutex_, "missing mutex"); this->mutex_->Lock(); }, [this](const O1HeapInstance *const handle) -> void { - SysAssertDbg(this->mutex_ ? true : false, "missing mutex"); + SysAssertDbg(this->mutex_, "missing mutex"); this->mutex_->Unlock(); } ); diff --git a/Source/RNG/RNG.cpp b/Source/RNG/RNG.cpp index fd6d7b34..4902da62 100644 --- a/Source/RNG/RNG.cpp +++ b/Source/RNG/RNG.cpp @@ -45,8 +45,10 @@ namespace Aurora::RNG if (setvbuf(gDevURand, NULL, _IONBF, 0) != 0) { + #if 0 fclose(gDevURand); gDevURand = NULL; + #endif } } @@ -271,6 +273,7 @@ namespace Aurora::RNG void Release() { #if defined(AURORA_IS_POSIX_DERIVED) + if (gDevURand != NULL) fclose(gDevURand); #elif defined(AURORA_IS_MODERNNT_DERIVED) && defined(USE_OLD_NTCRYPT) CryptReleaseContext(gCryptoProv, 0); diff --git a/Source/Time/Clock.cpp b/Source/Time/Clock.cpp index e563c0bd..a70fb2c4 100644 --- a/Source/Time/Clock.cpp +++ b/Source/Time/Clock.cpp @@ -220,24 +220,14 @@ namespace Aurora::Time #endif { LogWarn("Couldn't convert local civil time"); - #if defined(AURORA_COMPILER_MSVC) - auto tm = gmtime_s(&ret, &timet); - #else - auto tm = gmtime_r(&timet, &ret); - #endif - - #if defined(AURORA_COMPILER_MSVC) - SysAssert(!tm, "couldn't convert civil time"); - #else - SysAssert(tm, "couldn't convert civil time"); - #endif + ret = ToCivilTime(time, true); } } - ret.tm_isdst = 0; + //ret.tm_isdst = 0; return ret; } - AUKN_SYM AuInt64 FromCivilTime(const std::tm &time, bool UTC) + AUKN_SYM AuInt64 FromCivilTime(const std::tm &time, bool UTC) { auto tm = time; time_t timet; @@ -249,7 +239,7 @@ namespace Aurora::Time } else { - tm.tm_isdst = -1; + tm.tm_isdst = -1; // out of the 2 crts i've bothered checked, out of 3, this is legal timet = mktime(&tm); }