The library has both a C and C++ API, which map 100% 1:1 in features.

C++ API

The C++ API is part of the UXDGBaseDir.hpp header. It looks like this:

namespace UXDG
{
    MLS_PUBLIC_API uxdgstring XDG_DATA_HOME() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_CONFIG_HOME() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_STATE_HOME() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_CACHE_HOME() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_RUNTIME_DIR() noexcept;

    MLS_PUBLIC_API uxdgstring HOME() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_BIN_PATH_HOME() noexcept;

    MLS_PUBLIC_API std::vector<uxdgstring> XDG_DATA_DIRS() noexcept;
    MLS_PUBLIC_API std::vector<uxdgstring> XDG_CONFIG_DIRS() noexcept;

    MLS_PUBLIC_API uxdgstring getEnv(const char* name, const char* val) noexcept;
    MLS_PUBLIC_API std::vector<uxdgstring> splitEnv(const uxdgstring& str) noexcept;

    MLS_PUBLIC_API void setStickyBit(const uxdgstring& location) noexcept;

    MLS_PUBLIC_API uxdgstring XDG_DESKTOP_DIR() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_DOWNLOAD_DIR() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_TEMPLATES_DIR() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_PUBLICSHARE_DIR() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_DOCUMENTS_DIR() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_MUSIC_DIR() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_PICTURES_DIR() noexcept;
    MLS_PUBLIC_API uxdgstring XDG_VIDEOS_DIR() noexcept;

    MLS_PUBLIC_API uxdgstring getXDGUserDir(const char* dir, UXDG_XDG_USER_DIR_STANDARD_TYPE type = XDG_USER_DIR_STANDARD_TYPE_CUSTOM) noexcept;

    MLS_PUBLIC_API uxdgstring legacyUserIconsDir() noexcept;
    MLS_PUBLIC_API uxdgstring legacyUserThemesDir() noexcept;
    MLS_PUBLIC_API uxdgstring legacyUserFontsDir() noexcept;
}

In source code, all functions are annotated with their respective extracts from the XDG Basedir specification.

XDG_DATA_HOME

XDG Basedir spec: $XDG_DATA_HOME defines the base directory relative to which user-specific data files should be stored. If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.

XDG_CONFIG_HOME

XDG Basedir spec: $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_STATE_HOME

XDG Basedir spec: The $XDG_STATE_HOME contains state data that should persist between (application) restarts, but that is not important or portable enough to the user that it should be stored in $XDG_DATA_HOME. It may contain:

XDG_CACHE_HOME

XDG Basedir spec: $XDG_CACHE_HOME defines the base directory relative to which user-specific non-essential data files should be stored. If $XDG_CACHE_HOME is either not set or empty, a default equal to $HOME/.cache should be used.

XDG_RUNTIME_DIR

XDG Basedir spec: $XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential runtime files and other file objects (such as sockets, named pipes, ...) should be stored. The directory MUST be owned by the user, and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700.

The lifetime of the directory MUST be bound to the user being logged in. It MUST be created when the user first logs in and if the user fully logs out the directory MUST be removed. If the user logs in more than once he should get pointed to the same directory, and it is mandatory that the directory continues to exist from his first login to his last logout on the system, and not removed in between. Files in the directory MUST not survive reboot or a full logout/login cycle.

The directory MUST be on a local file system and not shared with any other system. The directory MUST be fully-featured by the standards of the operating system. More specifically, on Unix-like operating systems AF_UNIX sockets, symbolic links, hard links, proper permissions, file locking, sparse files, memory mapping, file change notifications, a reliable hard link count must be supported, and no restrictions on the file name character set should be imposed. Files in this directory MAY be subjected to periodic clean-up. To ensure that your files are not removed, they should have their access time timestamp modified at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.

If $XDG_RUNTIME_DIR is not set applications should fall back to a replacement directory with similar capabilities and print a warning message. Applications should use this directory for communication and synchronization purposes and should not place larger files in it, since it might reside in runtime memory and cannot necessarily be swapped out to disk.

This directory is never created by the library, even when UXDG_CREATE_DIRS is set, since the specification delegates its creation to the login manager. The value is verified to be an absolute path to a directory owned by the current user whose access mode is exactly 0700 (on Windows, only the existence check applies). If $XDG_RUNTIME_DIR is unset, missing, or fails this validation, an empty string (or nullptr in C) is returned.

HOME

Returns the absolute path to the home directory of the user running the application. If the $HOME environment variable is unset or empty, on Unix systems it falls back to querying the user entry in the system password database. If that also fails or is unavailable, an empty string (or nullptr in C) is returned.

XDG_BIN_PATH_HOME

XDG Basedir spec: User-specific executable files may be stored in $HOME/.local/bin. Distributions should ensure this directory shows up in the UNIX $PATH environment variable, at an appropriate place.

Since $HOME might be shared between systems of different architectures, installing compiled binaries to $HOME/.local/bin could cause problems when used on systems of differing architectures. This is often not a problem, but the fact that $HOME becomes partially architecture-specific if compiled binaries are placed in it should be kept in mind.

XDG_DATA_DIRS

XDG Basedir spec: $XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS should be separated with a colon ':'.

If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.

The order of base directories denotes their importance; the first directory listed is the most important.

XDG_CONFIG_DIRS

XDG Basedir spec: $XDG_CONFIG_DIRS defines the preference-ordered set of base directories to search for configuration files in addition to the $XDG_CONFIG_HOME base directory. The directories in $XDG_CONFIG_DIRS should be separated with a colon ':'.

If $XDG_CONFIG_DIRS is either not set or empty, a value equal to /etc/xdg should be used.

The order of base directories denotes their importance; the first directory listed is the most important.

getEnv

Given 2 string arguments, the name of an environment variable and a default string, returns the value of the environment variable or the default string if the variable does not exist.

splitEnv

Given a string argument, splits the string and returns an array of strings, split from the original string. The string is formatted in environment variable list format like this: a:b:c:d:e:f.

setStickyBit

Given a path to a file or directory, sets the sticky bit of it. This is useful for files or directories in XDG_RUNTIME_DIR that you don't want to be automatically cleaned up.

XDG Basedir spec: ...Files in this directory MAY be subjected to periodic clean-up. To ensure that your files are not removed, they should have their access time timestamp modified at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.

XDG User directories

While not documented anywhere, the so-called "XDG User dirs" are used by most distributions. They are defined in the following file: $XDG_CONFIG_HOME/user-dirs.dirs, and are used by many desktops and applications to provide convenient folders for pictures, videos, downloads, etc. Here is a normal user-dirs.dirs file:

XDG_DESKTOP_DIR="$HOME/Desktop"
XDG_DOWNLOAD_DIR="$HOME/Downloads"
XDG_TEMPLATES_DIR="$HOME/Templates"
XDG_PUBLICSHARE_DIR="$HOME/Public"
XDG_DOCUMENTS_DIR="$HOME/Documents"
XDG_MUSIC_DIR="$HOME/Music"
XDG_PICTURES_DIR="$HOME/Pictures"
XDG_VIDEOS_DIR="$HOME/Videos"

Fortunately, we have added functions for fetching these directories, and they correspond directly to their names. Please note that the file is read only once: when one of these functions is called. This should not be an issue in most cases, but may complicate things a bit for applications that want to both create and consume the directories.

Non-standard user directories

While the directories above are "standard" (referring to general desktop environment usage, since they are not standardized in any way), other directory variables can also be added to the file.

To fetch them, use the getXDGUserDir function. The first argument is the name of the variable; the second is an enum of type UXDG_XDG_USER_DIR_STANDARD_TYPE which defaults to XDG_USER_DIR_STANDARD_TYPE_CUSTOM. If not set to XDG_USER_DIR_STANDARD_TYPE_CUSTOM, it will simply try to fetch standard types, except when the value is larger than or equal to XDG_USER_DIR_STANDARD_TYPE_SIZE, in which case it will default to custom variable behavior.

Legacy User Directories

C API

The C API is the same, except that all functions are prefixed with UXDG_ to compensate for namespaces not existing. Additionally, instead of std::string or std::vector<std::string>, functions return char* and char** respectively. The return value of functions that return char* should be deallocated using UXDG_FreeResult_Str. For char**, UXDG_FreeResult_Arr.

All functions that return arrays also take a size_t* whose value will be set to the size of the array.

Error handling

Most functions don't report errors, as they have fallback defaults. The following ones do not have defaults and should be checked to see if they exist.

XDG_RUNTIME_DIR

XDG_RUNTIME_DIR returns an empty string (or nullptr in C) if the XDG_RUNTIME_DIR environment variable is unset, missing, or fails ownership and permission checks (must be an absolute path to a directory owned by the current user with access mode 0700).

HOME

HOME() returns an empty string (or nullptr in C) if neither the $HOME environment variable nor the user password database entry is available.

XDG_DATA_DIRS, XDG_CONFIG_DIRS, splitEnv

In the C++ API, the arrays may be empty if the given string or environment variable is empty.

In the C API, the following functions return char**. This pointer may be equal to nullptr if the environment variables are empty. Check against it for maximum safety when using the C API. UXDG_splitEnv returns nullptr and sets *size = 0 if str is nullptr.

String functions

If a function returns a string, the string may be empty if the environment variable is empty. In the C API, this is represented by a nullptr.