summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (Treviño) <mail@3v1n0.net>2022-09-13 03:03:51 +0200
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2022-12-15 17:29:00 +0100
commitf52006656394387d5709e39a7f79facbc8ed89d4 (patch)
treecc38d8cdcf0fbdb783175a42a14e7bec781a9830
parentded3099afca49234f407f67d96b99e684a8ff336 (diff)
downloadglib-f52006656394387d5709e39a7f79facbc8ed89d4.tar.gz
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.
-rw-r--r--glib/gutils.c37
-rw-r--r--glib/gutilsprivate.h2
-rw-r--r--tools/glib.supp13
3 files changed, 46 insertions, 6 deletions
diff --git a/glib/gutils.c b/glib/gutils.c
index 186ef7d07..d73b6474b 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -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;
+ 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
- tmp = g_strdup (g_getenv ("TEMP"));
+ "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;
}
/**
diff --git a/glib/gutilsprivate.h b/glib/gutilsprivate.h
index f7d435d61..0d9b0df14 100644
--- a/glib/gutilsprivate.h
+++ b/glib/gutilsprivate.h
@@ -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__ */
diff --git a/tools/glib.supp b/tools/glib.supp
index 0609db44e..5b03557d9 100644
--- a/tools/glib.supp
+++ b/tools/glib.supp
@@ -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