gutils: Add a private API to unset the cached temporary directory

We may need to avoid using a cached temp directory for testing purposes,
so let's provide an internal API to perform such task.

This implies removing GOnce and going with mutex-based version, but
that's still using atomic logic in most unix implementations anyways.
This commit is contained in:
Marco Trevisan (Treviño) 2022-09-13 03:03:51 +02:00
parent ded3099afc
commit f520066563
3 changed files with 47 additions and 7 deletions

View File

@ -598,6 +598,7 @@ static gchar *g_user_state_dir = NULL;
static gchar *g_user_runtime_dir = NULL;
static gchar **g_system_config_dirs = NULL;
static gchar **g_user_special_dirs = NULL;
static gchar *g_tmp_dir = NULL;
/* fifteen minutes of fame for everybody */
#define G_USER_DIRS_EXPIRE 15 * 60
@ -941,6 +942,17 @@ g_get_home_dir (void)
return home_dir;
}
void
_g_unset_cached_tmp_dir (void)
{
G_LOCK (g_utils_global);
/* We have to leak the old value, as user code could be retaining pointers
* to it. */
g_ignore_leak (g_tmp_dir);
g_tmp_dir = NULL;
G_UNLOCK (g_utils_global);
}
/**
* g_get_tmp_dir:
*
@ -964,22 +976,33 @@ g_get_home_dir (void)
const gchar *
g_get_tmp_dir (void)
{
static gchar *tmp_dir;
G_LOCK (g_utils_global);
if (g_once_init_enter (&tmp_dir))
if (g_tmp_dir == NULL)
{
gchar *tmp;
#ifdef G_OS_WIN32
tmp = g_strdup (g_getenv ("TEMP"));
tmp = g_strdup (g_getenv ("G_TEST_TMPDIR"));
if (tmp == NULL || *tmp == '\0')
{
g_free (tmp);
tmp = g_strdup (g_getenv (
#ifdef G_OS_WIN32
"TEMP"
#else /* G_OS_WIN32 */
"TMPDIR"
#endif /* G_OS_WIN32 */
));
}
#ifdef G_OS_WIN32
if (tmp == NULL || *tmp == '\0')
{
g_free (tmp);
tmp = get_windows_directory_root ();
}
#else /* G_OS_WIN32 */
tmp = g_strdup (g_getenv ("TMPDIR"));
#ifdef P_tmpdir
if (tmp == NULL || *tmp == '\0')
@ -1000,10 +1023,12 @@ g_get_tmp_dir (void)
}
#endif /* !G_OS_WIN32 */
g_once_init_leave (&tmp_dir, tmp);
g_tmp_dir = g_steal_pointer (&tmp);
}
return tmp_dir;
G_UNLOCK (g_utils_global);
return g_tmp_dir;
}
/**

View File

@ -59,6 +59,8 @@ g_nearest_pow (gsize num)
return n + 1;
}
void _g_unset_cached_tmp_dir (void);
G_END_DECLS
#endif /* __G_UTILS_PRIVATE_H__ */

View File

@ -840,6 +840,19 @@
fun:g_set_user_dirs
}
# _g_unset_cached_tmp_dir() deliberately leaks the previous cached g_get_tmp_dir() values.
# These will not all be reachable on exit.
{
g_get_tmp_dir
Memcheck:Leak
match-leak-kinds:definite,reachable
fun:malloc
...
fun:g_get_tmp_dir
...
fun:g_test_init
}
# g_get_system_data_dirs() caches a one-time allocation
{
g_get_system_data_dirs