diff options
author | Carlos Garcia Campos <carlosgc@gnome.org> | 2006-11-16 14:41:38 (GMT) |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@src.gnome.org> | 2006-11-16 14:41:38 (GMT) |
commit | f444faebb607e14ba75193545a98c5cd00a2da2d (patch) | |
tree | f8d58bfed7167f628f9c2f153f12dcc70969caeb | |
parent | 67654fe8c933af2932e2c87ec2a4560cb064c545 (diff) |
Fix a race condition when creating symlink. Increase the counter avoiding
2006-11-16 Carlos Garcia Campos <carlosgc@gnome.org>
* 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).
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | shell/ev-window.c | 48 |
2 files changed, 39 insertions, 18 deletions
@@ -1,3 +1,12 @@ +2006-11-16 Carlos Garcia Campos <carlosgc@gnome.org> + + * 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 <carlosgc@gnome.org> * 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); |