Issue #14681: Permission denied opening image - /tmp/gimp/3.0/ cannot be shared.

Let's create the folder returned by gimp_temp_directory() ourselves, the
first time this function is called, using a randomized name. This will
ensure that we won't conflict with another user running GIMP on the same
machine if using the base /tmp/ (which is usually the case on Linux).

Furthermore, since we create the temp folder at this level, we will also
delete it when quitting (but only if it's empty, as it should). Also I
use a single-level folder above the generic temporary directory, this
way, it's easier to track and we don't have to delete 2 levels of
directories anymore.

When the environment variable GIMP3_TEMPDIR is set though, we do not
create the folder, nor do we try and delete it.
This commit is contained in:
Jehan 2026-04-06 16:09:09 +02:00
parent 7dc8fefbfd
commit a85e5286fd
5 changed files with 48 additions and 15 deletions

View file

@ -909,6 +909,8 @@ main (int argc,
pdb_compat_mode,
backtrace_file);
gimp_env_exit (FALSE);
g_free (backtrace_file);
g_clear_object (&system_gimprc_file);

View file

@ -576,6 +576,7 @@ gimp_main (GType plug_in_type,
_gimp_plug_in_query (PLUG_IN);
gimp_close ();
gimp_env_exit (TRUE);
return EXIT_SUCCESS;
}
@ -588,6 +589,7 @@ gimp_main (GType plug_in_type,
_gimp_plug_in_init (PLUG_IN);
gimp_close ();
gimp_env_exit (TRUE);
return EXIT_SUCCESS;
}
@ -605,6 +607,8 @@ gimp_main (GType plug_in_type,
g_clear_object (&_check_custom_color1);
g_clear_object (&_check_custom_color2);
gimp_env_exit (TRUE);
return EXIT_SUCCESS;
}

View file

@ -58,6 +58,7 @@ EXPORTS
gimp_enum_value_get_abbrev
gimp_enum_value_get_desc
gimp_enum_value_get_help
gimp_env_exit
gimp_env_init
gimp_escape_uline
gimp_export_capabilities_get_type

View file

@ -26,7 +26,8 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
void gimp_env_init (gboolean plug_in);
void gimp_env_init (gboolean plug_in);
void gimp_env_exit (gboolean plug_in);
G_END_DECLS

View file

@ -98,6 +98,9 @@ static gchar * gimp_env_get_dir (const gchar *gimp_env_name,
const gchar *relative_subdir);
static gchar *gimp_temp_dir = NULL;
static gboolean gimp_temp_dir_generated = FALSE;
const guint gimp_major_version = GIMP_MAJOR_VERSION;
const guint gimp_minor_version = GIMP_MINOR_VERSION;
const guint gimp_micro_version = GIMP_MICRO_VERSION;
@ -171,6 +174,19 @@ gimp_env_init (gboolean plug_in)
}
}
void
gimp_env_exit (gboolean plug_in)
{
if (gimp_temp_dir_generated)
{
if (g_rmdir (gimp_temp_dir) == -1)
g_printerr ("%s: failed to delete the temporary folder `%s`: %s\n",
G_STRFUNC, gimp_temp_dir, g_strerror (errno));
}
g_clear_pointer (&gimp_temp_dir, g_free);
}
#ifdef G_OS_WIN32
static char *
@ -755,9 +771,9 @@ gimp_cache_directory (void)
* gimp_temp_directory:
*
* Returns the default top directory for GIMP temporary files. If the
* environment variable GIMP3_TEMPDIR exists, that is used. It
* should be an absolute pathname. Otherwise, a subdirectory of the
* directory returned by g_get_tmp_dir() is used.
* environment variable `GIMP3_TEMPDIR` exists, that is used. It
* should be an absolute pathname. Otherwise, a subdirectory of the
* directory returned by [func@GLib.get_tmp_dir] is used.
*
* In config files such as gimprc, the string ${gimp_temp_dir} expands
* to this directory.
@ -767,8 +783,10 @@ gimp_cache_directory (void)
*
* The returned string is owned by GIMP and must not be modified or
* freed. The returned string is in the encoding used for filenames by
* GLib, which isn't necessarily UTF-8. (On Windows it always is
* UTF-8.).
* GLib, which isn't necessarily UTF-8 (On Windows it always is UTF-8.).
*
* The returned directory path might already exists, or it might not. It
* is your responsibility to make sure it does before using it.
*
* Since: 2.10.10
*
@ -777,17 +795,24 @@ gimp_cache_directory (void)
const gchar *
gimp_temp_directory (void)
{
static gchar *gimp_temp_dir = NULL;
if (! gimp_temp_dir)
{
gchar *tmp = g_build_filename (g_get_tmp_dir (),
GIMP_PACKAGE,
GIMP_USER_VERSION,
NULL);
GError *error = NULL;
gimp_temp_dir = gimp_env_get_dir ("GIMP3_TEMPDIR", NULL, tmp);
g_free (tmp);
gimp_temp_dir = gimp_env_get_dir ("GIMP3_TEMPDIR", NULL, NULL);
if (gimp_temp_dir)
return gimp_temp_dir;
gimp_temp_dir = g_dir_make_tmp (GIMP_PACKAGE "-" GIMP_USER_VERSION "-XXXXXXX", &error);
gimp_temp_dir_generated = TRUE;
if (gimp_temp_dir == NULL)
{
g_critical ("%s: failed to create temporary directory: %s\n",
G_STRFUNC, error->message);
g_clear_error (&error);
gimp_temp_dir_generated = FALSE;
}
}
return gimp_temp_dir;
@ -1286,7 +1311,7 @@ gimp_env_get_dir (const gchar *gimp_env_name,
return retval;
}
else if (! g_path_is_absolute (relative_subdir))
else if (relative_subdir && ! g_path_is_absolute (relative_subdir))
{
return g_build_filename (gimp_installation_directory (),
relative_subdir,