From f444faebb607e14ba75193545a98c5cd00a2da2d Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Thu, 16 Nov 2006 14:41:38 +0000 Subject: Fix a race condition when creating symlink. Increase the counter avoiding 2006-11-16 Carlos Garcia Campos * shell/ev-window.c: (ev_window_create_tmp_symlink), (ev_window_cmd_file_open_copy_at_dest): Fix a race condition when creating symlink. Increase the counter avoiding an infinite loop. Really fixes bug #357472. (Based on patch by Mathias Hasselmann). --- diff --git a/ChangeLog b/ChangeLog index 1afc00e..998dd12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-11-16 Carlos Garcia Campos + + * shell/ev-window.c: (ev_window_create_tmp_symlink), + (ev_window_cmd_file_open_copy_at_dest): + + Fix a race condition when creating symlink. Increase the counter + avoiding an infinite loop. Really fixes bug #357472. (Based on patch by + Mathias Hasselmann). + 2006-11-15 Carlos Garcia Campos * backend/Makefile.am: diff --git a/shell/ev-window.c b/shell/ev-window.c index 436096c..493e28f 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -1221,10 +1221,11 @@ ev_window_cmd_file_open (GtkAction *action, EvWindow *window) } static gchar * -ev_window_get_copy_tmp_name (const gchar *filename) +ev_window_create_tmp_symlink (const gchar *filename, GError **error) { gchar *tmp_filename = NULL; gchar *name; + gint res; guint i = 0; name = g_path_get_basename (filename); @@ -1232,40 +1233,51 @@ ev_window_get_copy_tmp_name (const gchar *filename) do { gchar *basename; - basename = g_strdup_printf ("%s-%d", name, i); - tmp_filename = g_build_filename (g_get_tmp_dir (), + if (tmp_filename) + g_free (tmp_filename); + + basename = g_strdup_printf ("%s-%d", name, i++); + tmp_filename = g_build_filename (ev_tmp_dir (), basename, NULL); + g_free (basename); - } while (g_file_test (tmp_filename, G_FILE_TEST_EXISTS)); + } while ((res = symlink (filename, tmp_filename)) != 0 && errno == EEXIST); g_free (name); + if (res != 0 && errno != EEXIST) { + if (error) { + *error = g_error_new (G_FILE_ERROR, + g_file_error_from_errno (errno), + _("Couldn't create symlink ā€œ%sā€: %s"), + tmp_filename, strerror (errno)); + } + + g_free (tmp_filename); + + return NULL; + } + return tmp_filename; } static void ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest) { + GError *error = NULL; gchar *symlink_uri; gchar *old_filename; gchar *new_filename; old_filename = g_filename_from_uri (window->priv->uri, NULL, NULL); - new_filename = ev_window_get_copy_tmp_name (old_filename); - - if (symlink (old_filename, new_filename) != 0) { - gchar *msg; - GError *error; - - msg = g_strdup_printf (_("Cannot open a copy.")); - error = g_error_new (G_FILE_ERROR, - g_file_error_from_errno (errno), - _("Couldn't create symlink ā€œ%sā€: %s"), - new_filename, strerror (errno)); - ev_window_error_dialog (GTK_WINDOW (window), msg, error); - g_free (msg); - g_error_free (error); + new_filename = ev_window_create_tmp_symlink (old_filename, &error); + if (error) { + ev_window_error_dialog (GTK_WINDOW (window), + _("Cannot open a copy."), + error); + + g_error_free (error); g_free (old_filename); g_free (new_filename); -- cgit v0.9.1