g_get_user_runtime_dir(): ensure directory exists

If the XDG_RUNTIME_DIR environment variable is set, we are being told by
the OS that this directory exists and is appropriately configured
already.  In the fallback case of ~/.cache/, however, the directory may
not yet exist.

Rework the logic of this function a little so that we only check for the
environment variable once.  If it is not set, we will fall back to the
cache directory, and mkdir() it to make sure that it exists.

Meanwhile, remove a statement from the reference documentation that
promises a warning in this case (which has never been true) and replace
it with a statement that applications can rely on the directory
existing.

This change prevents each user of this API from having to check for the
directory for themselves; an example of that can be seen in bug 763274.

https://bugzilla.gnome.org/show_bug.cgi?id=763344
This commit is contained in:
Allison Ryan Lortie 2016-03-08 15:34:26 -05:00
parent 37756a06c9
commit 7c6141a546

View File

@ -1314,8 +1314,8 @@ g_get_user_cache_dir (void)
* [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec). * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
* This is the directory * This is the directory
* specified in the `XDG_RUNTIME_DIR` environment variable. * specified in the `XDG_RUNTIME_DIR` environment variable.
* In the case that this variable is not set, GLib will issue a warning * In the case that this variable is not set, we return the value of
* message to stderr and return the value of g_get_user_cache_dir(). * g_get_user_cache_dir(), after verifying that it exists.
* *
* On Windows this is the folder to use for local (as opposed to * On Windows this is the folder to use for local (as opposed to
* roaming) application data. See documentation for * roaming) application data. See documentation for
@ -1331,24 +1331,40 @@ g_get_user_runtime_dir (void)
{ {
#ifndef G_OS_WIN32 #ifndef G_OS_WIN32
static const gchar *runtime_dir; static const gchar *runtime_dir;
static gsize initialised;
if (g_once_init_enter (&initialised)) if (g_once_init_enter (&runtime_dir))
{ {
runtime_dir = g_strdup (getenv ("XDG_RUNTIME_DIR")); const gchar *dir;
g_once_init_leave (&initialised, 1); dir = g_strdup (getenv ("XDG_RUNTIME_DIR"));
if (dir == NULL)
{
/* No need to strdup this one since it is valid forever. */
dir = g_get_user_cache_dir ();
/* The user should be able to rely on the directory existing
* when the function returns. Probably it already does, but
* let's make sure. Just do mkdir() directly since it will be
* no more expensive than a stat() in the case that the
* directory already exists and is a lot easier.
*
* $XDG_CACHE_HOME is probably ~/.cache/ so as long as $HOME
* exists this will work. If the user changed $XDG_CACHE_HOME
* then they can make sure that it exists...
*/
(void) mkdir (dir, 0700);
}
g_assert (dir != NULL);
g_once_init_leave (&runtime_dir, dir);
} }
if (runtime_dir) return runtime_dir;
return runtime_dir; #else /* Windows */
/* Both fallback for UNIX and the default
* in Windows: use the user cache directory.
*/
#endif
return g_get_user_cache_dir (); return g_get_user_cache_dir ();
#endif
} }
#ifdef HAVE_CARBON #ifdef HAVE_CARBON