[+] Added GetUserHome, GetAppData, GetRootAppdata, GetWritableAppdata

[*] Dont fail on non-blocking /dev/urand
[+] Added if not initialized check under RNG/unix fclose
[+] Add missing debug apis ready for report to linux
[*] Update build script for WIP branch
This commit is contained in:
Reece Wilson 2022-01-18 14:26:38 +00:00
parent 235225ec9d
commit 4dddcb108e
13 changed files with 161 additions and 42 deletions

View File

@ -13,7 +13,8 @@
"linkSources": "Source/Alloc.cpp", "linkSources": "Source/Alloc.cpp",
"actions": [ "actions": [
{ {
"if": "win32", "if_": "win32",
"filter": { "platforms": "win32"} ,
"then": { "then": {
"links": ["Bcrypt.lib", "UxTheme.lib"] "links": ["Bcrypt.lib", "UxTheme.lib"]
} }

View File

@ -14,6 +14,8 @@
namespace Aurora::Debug namespace Aurora::Debug
{ {
using OSError_t = AuPair<AuUInt64, AuString>;
/** /**
Retrieves a print-friendly callstack of the last trap (either innocent exception or fatal mem access) <br> Retrieves a print-friendly callstack of the last trap (either innocent exception or fatal mem access) <br>
On Win32, this information is always available <br> On Win32, this information is always available <br>
@ -34,7 +36,7 @@ namespace Aurora::Debug
/** /**
Retrieve the last system error (IE: Win32, GetLastError()) 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: <br> Prints the current error state of the thread including: <br>

View File

@ -10,16 +10,35 @@
namespace Aurora::IO::FS namespace Aurora::IO::FS
{ {
/** /**
Suffixes a global read/writable path with nameSpace and a splitter * @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); 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);
} }

View File

@ -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) {} 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& language; /// ISO 639
const AuString& country; const AuString& country; /// ISO 3166
const AuString& codeset; const AuString& codeset; ///
const ECodePage codepage; const ECodePage codepage; /// Potentially eSysUnk; noting that eSysUnk is valid and handlable by the internal backend
}; };
/* /*

View File

@ -121,6 +121,12 @@
#endif #endif
#endif #endif
#if !defined(NO__INLINE)
#if !defined(auline)
#define auline AU_INLINE
#endif
#endif
#if !defined(AU_FWD) #if !defined(AU_FWD)
#define AU_FWD(var) std::forward<decltype(var)>(var) #define AU_FWD(var) std::forward<decltype(var)>(var)
#endif #endif

View File

@ -15,7 +15,13 @@
namespace Aurora::Debug namespace Aurora::Debug
{ {
static StackTrace gLastStackTrace;
static AuUInt32 gStackTraceFence;
static AuUInt32 gFenceId;
static AuThreadPrimitives::SpinLock gLock;
static AuString gLastExceptionMessage;
static AuUInt32 gFenceOSError = -1; static AuUInt32 gFenceOSError = -1;
AuUInt32 GetOSErrorFence() AuUInt32 GetOSErrorFence()
{ {
return gFenceOSError; return gFenceOSError;
@ -28,6 +34,7 @@ namespace Aurora::Debug
AuString ret; AuString ret;
#if defined(AURORA_PLATFORM_WIN32) #if defined(AURORA_PLATFORM_WIN32)
char *err = nullptr; char *err = nullptr;
if (!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, if (!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, NULL,
error, error,
@ -66,6 +73,7 @@ namespace Aurora::Debug
ret.second = GetOSErrorStringWin32(lastError.first); ret.second = GetOSErrorStringWin32(lastError.first);
gFenceOSError++; gFenceOSError++;
gFenceId++;
return lastError = ret; return lastError = ret;
} }
@ -116,9 +124,9 @@ namespace Aurora::Debug
return gFenceCError; return gFenceCError;
} }
AuOptional<int> TryFetchCError() AuOptional<AuUInt32> TryFetchCError()
{ {
static int lastError = 0; static AuUInt32 lastError = 0;
auto errorNumber = errno; auto errorNumber = errno;
if (!errorNumber) if (!errorNumber)
@ -132,15 +140,16 @@ namespace Aurora::Debug
} }
gFenceCError++; gFenceCError++;
gFenceId++;
return lastError = errorNumber; return lastError = errorNumber;
} }
AuOptional<int> TryGetOrFetchCError() AuOptional<AuUInt32> TryGetOrFetchCError()
{ {
static AuOptional<int> lastErrorError; static AuOptional<AuUInt32> lastErrorError;
static AuOptional<AuUInt32> lastErrorFence; static AuOptional<AuUInt32> lastErrorFence;
AuOptional<int> tempError = TryFetchCError(); AuOptional<AuUInt32> tempError = TryFetchCError();
if (!tempError) if (!tempError)
{ {
@ -161,9 +170,40 @@ namespace Aurora::Debug
return tempError; return tempError;
} }
void ReportStackTrace(const StackTrace& trace, const AuString& message)
{
AU_LOCK_GUARD(gLock);
gLastStackTrace = trace;
gLastExceptionMessage = message;
gStackTraceFence++;
gFenceId++;
}
AuUInt32 GetFenceId() 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() AUKN_SYM void PrintError()
@ -204,7 +244,7 @@ namespace Aurora::Debug
AUKN_SYM void _PushError(AuUInt address, EFailureCategory category, const char *msg) 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 // Oi, developer
#if defined(DEBUG) #if defined(DEBUG)

View File

@ -16,20 +16,19 @@ namespace Aurora::Debug
AuString dbg; AuString dbg;
}; };
using OSError_t = AuPair<AuUInt64, AuString>;
AuUInt32 GetOSErrorFence(); AuUInt32 GetOSErrorFence();
AuOptional<OSError_t> TryGetOrFetchOSError(); AuOptional<OSError_t> TryGetOrFetchOSError();
AuUInt32 GetCErrorFence(); AuUInt32 GetCErrorFence();
AuOptional<int> TryGetOrFetchCError(); AuOptional<AuUInt32> TryGetOrFetchCError();
void ReportStackTrace(const StackTrace &trace); void ReportStackTrace(const StackTrace &trace, const AuString &message);
AuOptional<OSError_t> TryFetchOSError(); AuOptional<OSError_t> TryFetchOSError();
AuOptional<int> TryFetchCError(); AuOptional<AuUInt32> TryFetchCError();
void CheckErrors(); void CheckErrors();

View File

@ -328,6 +328,8 @@ namespace Aurora::Debug
} }
ReportStackTrace(entry.wincxx.stack.backtrace, entry.wincxx.str);
#if defined(STAGING) || defined(DEBUG) #if defined(STAGING) || defined(DEBUG)
bool isInternal = true; bool isInternal = true;
#else #else

View File

@ -88,7 +88,7 @@ namespace Aurora::Debug
#if defined(AURORA_COMPILER_GCC) || defined(AURORA_COMPILER_CLANG) #if defined(AURORA_COMPILER_GCC) || defined(AURORA_COMPILER_CLANG)
__builtin_trap(); __builtin_trap();
#else #else
std::exit(0xDEAD); std::terminate();
#endif #endif
#endif #endif
} }

View File

@ -26,6 +26,10 @@ namespace Aurora::IO::FS
#endif #endif
static AuString gHomeDirectory; static AuString gHomeDirectory;
static AuString gUserHomeDirectory;
static AuString gUserWritableAppData;
static AuString gGlobalWritableAppDirectory;
static AuString gAdminWritableAppDirectory;
static AuString gApplicationData; static AuString gApplicationData;
static AuOptional<AuString> gSystemLibPath; static AuOptional<AuString> gSystemLibPath;
static AuOptional<AuString> gSystemLibPath2; static AuOptional<AuString> gSystemLibPath2;
@ -126,6 +130,9 @@ namespace Aurora::IO::FS
gHomeDirectory = GetSpecialDir(FOLDERID_RoamingAppData); gHomeDirectory = GetSpecialDir(FOLDERID_RoamingAppData);
gApplicationData = GetSpecialDir(FOLDERID_ProgramData); gApplicationData = GetSpecialDir(FOLDERID_ProgramData);
gSystemLibPath = GetSpecialDir(FOLDERID_System); gSystemLibPath = GetSpecialDir(FOLDERID_System);
gUserHomeDirectory = GetSpecialDir(FOLDERID_Profile);
gAdminWritableAppDirectory = gApplicationData;
gUserWritableAppData = gHomeDirectory;
} }
#elif defined(AURORA_PLATFORM_LINUX) || defined(AURORA_PLATFORM_BSD) #elif defined(AURORA_PLATFORM_LINUX) || defined(AURORA_PLATFORM_BSD)
@ -186,6 +193,8 @@ namespace Aurora::IO::FS
homedir = getpwuid(getuid())->pw_dir; homedir = getpwuid(getuid())->pw_dir;
} }
gUserHomeDirectory = homedir;
// XDG Base Directory Specification // 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_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 // $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 // Fedora (2011?): https://fedoraproject.org/wiki/Features/UsrMove
SetUnixPaths(gUserLibPath, gUserLibPath2, "/usr/local/lib"); SetUnixPaths(gUserLibPath, gUserLibPath2, "/usr/local/lib");
SetUnixPaths(gSystemLibPath, gSystemLibPath2, "/usr/lib"); SetUnixPaths(gSystemLibPath, gSystemLibPath2, "/usr/lib");
gGlobalWritableAppDirectory = "/opt";
gAdminWritableAppDirectory = kUnixAppData;
gUserWritableAppData = gApplicationData;
} }
#else #else
@ -279,6 +292,50 @@ namespace Aurora::IO::FS
ChangeDir(); 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) #if defined(AURORA_PLATFORM_WIN32)
static void Win32FixGlobalAppDataAcl(const std::string &path) static void Win32FixGlobalAppDataAcl(const std::string &path)
{ {

View File

@ -127,12 +127,12 @@ namespace Aurora::Memory
heap_ = o1heapInit(base_, length, heap_ = o1heapInit(base_, length,
[this](const O1HeapInstance *const handle) -> void [this](const O1HeapInstance *const handle) -> void
{ {
SysAssertDbg(this->mutex_ ? true : false, "missing mutex"); SysAssertDbg(this->mutex_, "missing mutex");
this->mutex_->Lock(); this->mutex_->Lock();
}, },
[this](const O1HeapInstance *const handle) -> void [this](const O1HeapInstance *const handle) -> void
{ {
SysAssertDbg(this->mutex_ ? true : false, "missing mutex"); SysAssertDbg(this->mutex_, "missing mutex");
this->mutex_->Unlock(); this->mutex_->Unlock();
} }
); );

View File

@ -45,8 +45,10 @@ namespace Aurora::RNG
if (setvbuf(gDevURand, NULL, _IONBF, 0) != 0) if (setvbuf(gDevURand, NULL, _IONBF, 0) != 0)
{ {
#if 0
fclose(gDevURand); fclose(gDevURand);
gDevURand = NULL; gDevURand = NULL;
#endif
} }
} }
@ -271,6 +273,7 @@ namespace Aurora::RNG
void Release() void Release()
{ {
#if defined(AURORA_IS_POSIX_DERIVED) #if defined(AURORA_IS_POSIX_DERIVED)
if (gDevURand != NULL)
fclose(gDevURand); fclose(gDevURand);
#elif defined(AURORA_IS_MODERNNT_DERIVED) && defined(USE_OLD_NTCRYPT) #elif defined(AURORA_IS_MODERNNT_DERIVED) && defined(USE_OLD_NTCRYPT)
CryptReleaseContext(gCryptoProv, 0); CryptReleaseContext(gCryptoProv, 0);

View File

@ -220,20 +220,10 @@ namespace Aurora::Time
#endif #endif
{ {
LogWarn("Couldn't convert local civil time"); LogWarn("Couldn't convert local civil time");
#if defined(AURORA_COMPILER_MSVC) ret = ToCivilTime(time, true);
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.tm_isdst = 0; //ret.tm_isdst = 0;
return ret; return ret;
} }
@ -249,7 +239,7 @@ namespace Aurora::Time
} }
else 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); timet = mktime(&tm);
} }