@@ -345,6 +345,39 @@ GetAppCacheDir() noexcept
345345#endif
346346}
347347
348+ AllocatedPath
349+ GetUserDataDir () noexcept
350+ {
351+ #ifdef USE_XDG
352+ // Check for $XDG_DATA_HOME
353+ if (const auto path = GetExistingEnvDirectory (" XDG_DATA_HOME" );
354+ path != nullptr )
355+ return AllocatedPath{path};
356+
357+ // Check for $HOME/.local/share
358+ if (const auto home = GetHomeDir (); !home.IsNull ())
359+ if (auto fallback = home / Path::FromFS (" .local/share" );
360+ IsValidDir (fallback))
361+ return fallback;
362+
363+ #endif
364+ return nullptr ;
365+ }
366+
367+ AllocatedPath
368+ GetAppDataDir () noexcept
369+ {
370+ #if defined(USE_XDG)
371+ if (const auto user_dir = GetUserDataDir (); !user_dir.IsNull ()) {
372+ auto dir = user_dir / app_filename;
373+ CreateDirectoryNoThrow (dir);
374+ return dir;
375+ }
376+
377+ #endif
378+ return nullptr ;
379+ }
380+
348381AllocatedPath
349382GetUserRuntimeDir () noexcept
350383{
@@ -386,6 +419,47 @@ GetAppRuntimeDir() noexcept
386419 return nullptr ;
387420}
388421
422+ AllocatedPath
423+ GetUserStateDir () noexcept
424+ {
425+ #ifdef USE_XDG
426+ // Check for $XDG_STATE_HOME
427+ if (const auto path = GetExistingEnvDirectory (" XDG_STATE_HOME" );
428+ path != nullptr )
429+ return AllocatedPath{path};
430+
431+ // Check for $HOME/.local/state
432+ if (const auto home = GetHomeDir (); !home.IsNull ())
433+ if (auto fallback = home / Path::FromFS (" .local/state" );
434+ IsValidDir (fallback))
435+ return fallback;
436+ #endif
437+
438+ return nullptr ;
439+ }
440+
441+ AllocatedPath
442+ GetAppStateDir () noexcept
443+ {
444+ #if defined(__linux__) && !defined(ANDROID)
445+ /* systemd specific; see systemd.exec(5) */
446+ if (const char *state_directory = getenv (" STATE_DIRECTORY" ))
447+ if (auto dir = Split (std::string_view{state_directory}, ' :' ).first ;
448+ !dir.empty ())
449+ return AllocatedPath::FromFS (dir);
450+ #endif
451+
452+ #if defined(USE_XDG)
453+ if (const auto user_dir = GetUserStateDir (); !user_dir.IsNull ()) {
454+ auto dir = user_dir / app_filename;
455+ CreateDirectoryNoThrow (dir);
456+ return dir;
457+ }
458+ #endif
459+
460+ return nullptr ;
461+ }
462+
389463#ifdef _WIN32
390464
391465AllocatedPath
0 commit comments