]> www.fi.muni.cz Git - evince.git/commitdiff
Fix a race condition when creating symlink. Increase the counter avoiding
authorCarlos Garcia Campos <carlosgc@gnome.org>
Thu, 16 Nov 2006 14:41:38 +0000 (14:41 +0000)
committerCarlos Garcia Campos <carlosgc@src.gnome.org>
Thu, 16 Nov 2006 14:41:38 +0000 (14:41 +0000)
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).

ChangeLog
shell/ev-window.c

index 1afc00ea98413445c36f3d71c73d349f5220e5d0..998dd12ec4542665a30c66c868487f8567d94d65 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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:
index 436096ce66deb37de6f8397e980beeddc1a958f0..493e28f84bbb53194089c716c4e591e334b4f1f3 100644 (file)
@@ -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);