[evince] libdocument: Clean up temp file handling



commit 0f1c723ad2fe48a0f22e32619985f93ebb2e02ef
Author: Christian Persch <chpe gnome org>
Date:   Sun Oct 25 16:04:20 2009 +0100

    libdocument: Clean up temp file handling
    t push origin HEAD:master
    Make sure we can cope with not being able to create our temp directory.
    Bug #595372.

 backend/comics/comics-document.c |   31 ++----
 libdocument/ev-attachment.c      |   18 ++--
 libdocument/ev-file-helpers.c    |  236 ++++++++++++++++++++++++++------------
 libdocument/ev-file-helpers.h    |   17 ++-
 libdocument/ev-image.c           |   24 +++-
 libview/ev-jobs.c                |   37 ++----
 shell/ev-application.c           |    2 +-
 shell/ev-sidebar-attachments.c   |   13 +-
 shell/ev-window.c                |   44 +++++---
 9 files changed, 261 insertions(+), 161 deletions(-)
---
diff --git a/backend/comics/comics-document.c b/backend/comics/comics-document.c
index fbe6ba0..b53d513 100644
--- a/backend/comics/comics-document.c
+++ b/backend/comics/comics-document.c
@@ -205,32 +205,20 @@ comics_generate_command_lines (ComicsDocument *comics_document,
 	comics_document->regex_arg = command_usage_def[type].regex_arg;
 	comics_document->offset = command_usage_def[type].offset;
 	if (command_usage_def[type].decompress_tmp) {
-		comics_document->dir = ev_tmp_directory (NULL); 
-		comics_document->decompress_tmp = 
+		comics_document->dir = ev_mkdtemp ("comics.XXXXXX", error);
+                if (comics_document->dir == NULL)
+                        return FALSE;
+
+		/* unrar-free can't create directories, but ev_mkdtemp already created the dir */
+
+		comics_document->decompress_tmp =
 			g_strdup_printf (command_usage_def[type].decompress_tmp, 
 					 comics_document->selected_command, 
 					 quoted_file, 
 					 comics_document->dir);
 		g_free (quoted_file);
-		/* unrar-free can't create directories so we do it on its 
-		 * behalf */
-		if (type == GNAUNRAR) {
-			if (g_mkdir_with_parents (comics_document->dir, 0700) != 
-			    0) {
-				int errsv = errno;
-				g_set_error (error,
-					     EV_DOCUMENT_ERROR,
-					     EV_DOCUMENT_ERROR_INVALID,
-					     _("Failed to create a temporary "
-					     "directory."));
-				g_warning ("Failed to create directory %s: %s", 
-					   comics_document->dir, 
-					   g_strerror (errsv));
-				
-				return FALSE;
-			}
-		}
-		if (!comics_decompress_temp_dir (comics_document->decompress_tmp, 
+
+		if (!comics_decompress_temp_dir (comics_document->decompress_tmp,
 		    comics_document->selected_command, error))
 			return FALSE;
 		else
@@ -713,7 +701,6 @@ comics_document_finalize (GObject *object)
 			g_warning (_("There was an error deleting â??%sâ??."),
 				   comics_document->dir);
 		g_free (comics_document->dir);
-		g_remove (ev_tmp_dir ());
 	}
 	
 	if (comics_document->page_names) {
diff --git a/libdocument/ev-attachment.c b/libdocument/ev-attachment.c
index c1d1333..c4dd38d 100644
--- a/libdocument/ev-attachment.c
+++ b/libdocument/ev-attachment.c
@@ -101,7 +101,7 @@ ev_attachment_finalize (GObject *object)
 		attachment->priv->tmp_file = NULL;
 	}
 
-	(* G_OBJECT_CLASS (ev_attachment_parent_class)->finalize) (object);
+	G_OBJECT_CLASS (ev_attachment_parent_class)->finalize (object);
 }
 
 static void
@@ -411,18 +411,19 @@ ev_attachment_open (EvAttachment *attachment,
 		return FALSE;
 	}
 
-	if (attachment->priv->tmp_file &&
-	    g_file_query_exists (attachment->priv->tmp_file, NULL)) {
+	if (attachment->priv->tmp_file) {
 		retval = ev_attachment_launch_app (attachment, screen,
 						   timestamp, error);
 	} else {
-		GFile *tmpdir;
+                char *template;
 		GFile *file;
-		
-		tmpdir = g_file_new_for_path (ev_tmp_dir ());
-		file = g_file_get_child (tmpdir, attachment->priv->name);
 
-		if (ev_attachment_save (attachment, file, error)) {
+                /* FIXMEchpe: convert to filename encoding first! */
+                template = g_strdup_printf ("%s.XXXXXX", ev_attachment_get_name (attachment));
+                file = ev_mkstemp_file (template, error);
+                g_free (template);
+
+		if (file != NULL && ev_attachment_save (attachment, file, error)) {
 			if (attachment->priv->tmp_file)
 				g_object_unref (attachment->priv->tmp_file);
 			attachment->priv->tmp_file = g_object_ref (file);
@@ -432,7 +433,6 @@ ev_attachment_open (EvAttachment *attachment,
 		}
 
 		g_object_unref (file);
-		g_object_unref (tmpdir);
 	}
 
 	return retval;
diff --git a/libdocument/ev-file-helpers.c b/libdocument/ev-file-helpers.c
index 3da4a59..4816db0 100644
--- a/libdocument/ev-file-helpers.c
+++ b/libdocument/ev-file-helpers.c
@@ -1,5 +1,6 @@
 /*
  *  Copyright (C) 2002 Jorn Baayen
+ *  Copyright © 2009 Christian Persch
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -14,58 +15,85 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *  $Id$
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include <config.h>
 
 #include <stdlib.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <string.h>
+#include <errno.h>
+
 #include <glib.h>
 #include <glib/gstdio.h>
-#include <errno.h>
+#include <glib/gi18n-lib.h>
 
 #include "ev-file-helpers.h"
 
 static gchar *tmp_dir = NULL;
-static gint   count = 0;
 
+/**
+ * ev_dir_ensure_exists:
+ * @dir: the directory name
+ * @mode: permissions to use when creating the directory
+ * @error: a location to store a #GError
+ *
+ * Create @dir recursively with permissions @mode.
+ *
+ * Returns: %TRUE on success, or %FALSE on error with @error filled in
+ */
 gboolean
 ev_dir_ensure_exists (const gchar *dir,
-                      int          mode)
+                      int          mode,
+                      GError     **error)
 {
+        int errsv;
+        char *display_name;
+
+        g_return_val_if_fail (dir != NULL, FALSE);
+
+        errno = 0;
 	if (g_mkdir_with_parents (dir, mode) == 0)
 		return TRUE;
 
-	if (errno == EEXIST)
-		return g_file_test (dir, G_FILE_TEST_IS_DIR);
-	
-	g_warning ("Failed to create directory %s: %s", dir, g_strerror (errno));
+        errsv = errno;
+	if (errsv == EEXIST && g_file_test (dir, G_FILE_TEST_IS_DIR))
+                return TRUE;
+
+        display_name = g_filename_display_name (dir);
+        g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+                     "Failed to create directory '%s': %s",
+                     display_name, g_strerror (errsv));
+        g_free (display_name);
+
 	return FALSE;
 }
 
-const gchar *
-ev_tmp_dir (void)
+/*
+ * _ev_tmp_dir:
+ * @error: a location to store a #GError
+ *
+ * Returns the tmp directory.
+ *
+ * Returns: the tmp directory, or %NULL with @error filled in if the
+ *   directory could not be created
+ */
+const char *
+_ev_tmp_dir (GError **error)
 {
-	if (tmp_dir == NULL) {
-		gboolean exists;
-		gchar   *dirname, *prgname;
+
+        if (tmp_dir == NULL) {
+                gchar *dirname, *prgname;
 
                 prgname = g_get_prgname ();
-		dirname = g_strdup_printf ("%s-%u", prgname ? prgname : "unknown", getpid ());
-		tmp_dir = g_build_filename (g_get_tmp_dir (),
-					    dirname,
-					    NULL);
-		g_free (dirname);
-
-		exists = ev_dir_ensure_exists (tmp_dir, 0700);
-		g_assert (exists);
-	}
+                dirname = g_strdup_printf ("%s-%u", prgname ? prgname : "unknown", getpid ());
+                tmp_dir = g_build_filename (g_get_tmp_dir (), dirname, NULL);
+                g_free (dirname);
+        }
+
+        if (!ev_dir_ensure_exists (tmp_dir, 0700, error))
+                return NULL;
 
 	return tmp_dir;
 }
@@ -85,47 +113,121 @@ _ev_file_helpers_shutdown (void)
 	tmp_dir = NULL;
 }
 
-GFile *
-ev_tmp_file_get (const gchar *prefix)
+/**
+ * ev_mkstemp:
+ * @template: a template string; must contain 'XXXXXX', but not necessarily as a suffix
+ * @file_name: a location to store the filename of the temp file
+ * @error: a location to store a #GError
+ *
+ * Creates a temp file in the evince temp directory.
+ *
+ * Returns: a file descriptor to the newly created temp file name, or %-1
+ *   on error with @error filled in
+ */
+int
+ev_mkstemp (const char  *template,
+            char       **file_name,
+            GError     **error)
 {
-	gchar *path;
-	GFile *file;
+        const char *tmp;
+        char *name;
+        int fd;
 
-	path = ev_tmp_filename (prefix);
-	file = g_file_new_for_path (path);
-	
-	g_free (path);
-	
-	return file;
+        if ((tmp = _ev_tmp_dir (error)) == NULL)
+              return -1;
+
+        name = g_build_filename (tmp, template, NULL);
+        fd = g_mkstemp (name);
+
+        if (fd == -1) {
+		int errsv = errno;
+
+                g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+                             _("Failed to create a temporary file: %s"),
+                             g_strerror (errsv));
+
+                g_free (name);
+                return -1;
+        }
+
+        if (file_name)
+                *file_name = name;
+
+        return fd;
 }
 
-gchar * 
-ev_tmp_filename (const gchar *prefix)
+static void
+close_fd_cb (gpointer fdptr)
 {
-	gchar *basename;
-	gchar *filename = NULL;
-
-	do {
-		if (filename != NULL)
-			g_free (filename);
-			
-		basename = g_strdup_printf ("%s-%d",
-					    prefix ? prefix : "document",
-					    count ++);
-		
-		filename = g_build_filename (ev_tmp_dir (),
-					     basename, NULL);
-		
-		g_free (basename);
-	} while (g_file_test (filename, G_FILE_TEST_EXISTS));
-			
-	return filename;
+        int fd = GPOINTER_TO_INT (fdptr);
+
+        close (fd);
+}
+
+/**
+ * ev_mkstemp_file:
+ * @template: a template string; must contain 'XXXXXX', but not necessarily as a suffix
+ * @error: a location to store a #GError
+ *
+ * Creates a temp #GFile in the evince temp directory. See ev_mkstemp() for more information.
+ *
+ * Returns: a newly allocated #GFile for the newly created temp file name, or %NULL
+ *   on error with @error filled in
+ */
+GFile *
+ev_mkstemp_file (const char        *template,
+                 GError           **error)
+{
+        char *file_name;
+        int fd;
+        GFile *file;
+
+        fd = ev_mkstemp (template, &file_name, error);
+        if (fd == -1)
+                return NULL;
+
+        file = g_file_new_for_path (file_name);
+        g_free (file_name);
+
+        g_object_set_data_full (G_OBJECT (file), "ev-mkstemp-fd",
+                                GINT_TO_POINTER (fd), (GDestroyNotify) close_fd_cb);
+
+        return file;
 }
 
-gchar * 
-ev_tmp_directory (const gchar *prefix) 
+/**
+ * ev_mkdtemp:
+ * @template: a template string; must end in 'XXXXXX'
+ * @error: a location to store a #GError
+ *
+ * Creates a temp directory in the evince temp directory.
+ *
+ * Returns: a newly allocated string with the temp directory name, or %NULL
+ *   on error with @error filled in
+ */
+gchar *
+ev_mkdtemp (const char        *template,
+            GError           **error)
 {
-	return ev_tmp_filename (prefix ? prefix : "directory");
+        const char *tmp;
+        char *name;
+
+        if ((tmp = _ev_tmp_dir (error)) == NULL)
+              return NULL;
+
+        name = g_build_filename (tmp, template, NULL);
+        if (mkdtemp (name) == NULL) {
+		int errsv = errno;
+
+                g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+                             _("Failed to create a temporary directory: %s"),
+                             g_strerror (errsv));
+
+                g_free (name);
+                return NULL;
+        }
+
+        return name;
 }
 
 /* Remove a local temp file created by evince */
@@ -138,7 +240,7 @@ ev_tmp_filename_unlink (const gchar *filename)
 		return;
 
 	tempdir = g_get_tmp_dir ();
-	if (g_ascii_strncasecmp (filename, tempdir, strlen (tempdir)) == 0) {
+	if (g_str_has_prefix (filename, tempdir) == 0) {
 		g_unlink (filename);
 	}
 }
@@ -326,7 +428,7 @@ compression_run (const gchar       *uri,
 {
 	gchar *argv[N_ARGS];
 	gchar *uri_dst = NULL;
-	gchar *filename, *filename_dst;
+	gchar *filename, *filename_dst = NULL;
 	gchar *cmd;
 	gint   fd, pout;
 	GError *err = NULL;
@@ -349,20 +451,12 @@ compression_run (const gchar       *uri,
 		g_free (cmd);
 		return NULL;
 	}
-	
-	filename_dst = g_build_filename (ev_tmp_dir (), "evinceXXXXXX", NULL);
-	fd = g_mkstemp (filename_dst);
-	if (fd < 0) {
-		int errsv = errno;
 
+        fd = ev_mkstemp ("comp.XXXXXX", &filename_dst, error);
+	if (fd == -1) {
 		g_free (cmd);
 		g_free (filename);
-		g_free (filename_dst);
 
-		g_set_error (error, G_IO_ERROR,
-			     g_io_error_from_errno (errsv),
-			     "Error creating a temporary file: %s",
-			     g_strerror (errsv));
 		return NULL;
 	}
 
diff --git a/libdocument/ev-file-helpers.h b/libdocument/ev-file-helpers.h
index 47a5417..99df4ed 100644
--- a/libdocument/ev-file-helpers.h
+++ b/libdocument/ev-file-helpers.h
@@ -36,18 +36,23 @@ typedef enum {
 	EV_COMPRESSION_GZIP
 } EvCompressionType;
 
-const gchar *ev_tmp_dir               (void);
+const char *_ev_tmp_dir               (GError **error);
 
 void        _ev_file_helpers_init     (void);
 
 void        _ev_file_helpers_shutdown (void);
 
 gboolean     ev_dir_ensure_exists     (const gchar       *dir,
-                                       int                mode);
-
-GFile       *ev_tmp_file_get          (const gchar       *prefix);
-gchar       *ev_tmp_filename          (const char        *prefix);
-gchar       *ev_tmp_directory         (const char        *prefix);
+                                       int                mode,
+                                       GError           **error);
+
+int          ev_mkstemp               (const char        *template,
+                                       char             **file_name,
+                                       GError           **error);
+GFile       *ev_mkstemp_file          (const char        *template,
+                                       GError           **error);
+gchar       *ev_mkdtemp               (const char        *template,
+                                       GError           **error);
 void         ev_tmp_filename_unlink   (const gchar       *filename);
 void         ev_tmp_file_unlink       (GFile             *file);
 void         ev_tmp_uri_unlink        (const gchar       *uri);
diff --git a/libdocument/ev-image.c b/libdocument/ev-image.c
index 4fa2225..572b119 100644
--- a/libdocument/ev-image.c
+++ b/libdocument/ev-image.c
@@ -18,7 +18,10 @@
  */
 
 #include <config.h>
+
 #include <glib/gstdio.h>
+#include <unistd.h>
+
 #include "ev-document-misc.h"
 #include "ev-file-helpers.h"
 #include "ev-image.h"
@@ -132,7 +135,8 @@ ev_image_save_tmp (EvImage   *image,
 		   GdkPixbuf *pixbuf)
 {
 	GError *error = NULL;
-	gchar  *filename;
+	gchar  *filename = NULL;
+        int fd;
 	
 	g_return_val_if_fail (EV_IS_IMAGE (image), NULL);
 	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
@@ -140,19 +144,28 @@ ev_image_save_tmp (EvImage   *image,
 	if (image->priv->tmp_uri)
 		return image->priv->tmp_uri;
 
-	filename = ev_tmp_filename ("image");
+        if ((fd = ev_mkstemp ("image.XXXXXX", &filename, &error)) == -1)
+                goto had_error;
+
 	gdk_pixbuf_save (pixbuf, filename,
 			 "png", &error,
 			 "compression", "3", NULL);
+        close (fd);
+
 	if (!error) {
-		image->priv->tmp_uri = g_filename_to_uri (filename, NULL, NULL);
+		image->priv->tmp_uri = g_filename_to_uri (filename, NULL, &error);
+                if (image->priv->tmp_uri == NULL)
+                        goto had_error;
+
 		g_free (filename);
 		
 		return image->priv->tmp_uri;
 	}
 
+    had_error:
+
 	/* Erro saving image */
-	g_warning ("%s", error->message);
+	g_warning ("Error saving image: %s", error->message);
 	g_error_free (error);
 	g_free (filename);
 
@@ -166,6 +179,3 @@ ev_image_get_tmp_uri (EvImage *image)
 
 	return image->priv->tmp_uri;
 }
-
-
-
diff --git a/libview/ev-jobs.c b/libview/ev-jobs.c
index c0aa0b4..a0866d5 100644
--- a/libview/ev-jobs.c
+++ b/libview/ev-jobs.c
@@ -936,31 +936,17 @@ ev_job_save_run (EvJob *job)
 {
 	EvJobSave *job_save = EV_JOB_SAVE (job);
 	gint       fd;
-	gchar     *filename;
-	gchar     *tmp_filename;
+	gchar     *tmp_filename = NULL;
 	gchar     *local_uri;
 	GError    *error = NULL;
 	
 	ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", job_save->uri, job_save->document_uri);
 	ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
-	
-	filename = ev_tmp_filename ("saveacopy");
-	tmp_filename = g_strdup_printf ("%s.XXXXXX", filename);
-	g_free (filename);
-
-	fd = g_mkstemp (tmp_filename);
-	if (fd == -1) {
-		gchar *display_name;
-		gint   save_errno = errno;
 
-		display_name = g_filename_display_name (tmp_filename);
-		ev_job_failed (job,
-			       G_FILE_ERROR,
-			       g_file_error_from_errno (save_errno),
-			       _("Failed to create file â??%sâ??: %s"),
-			       display_name, g_strerror (save_errno));
-		g_free (display_name);
-		g_free (tmp_filename);
+        fd = ev_mkstemp ("saveacopy.XXXXXX", &tmp_filename, &error);
+        if (fd == -1) {
+                ev_job_failed_from_error (job, error);
+                g_error_free (error);
 
 		return FALSE;
 	}
@@ -968,8 +954,11 @@ ev_job_save_run (EvJob *job)
 	ev_document_doc_mutex_lock ();
 
 	/* Save document to temp filename */
-	local_uri = g_filename_to_uri (tmp_filename, NULL, NULL);
-	ev_document_save (job->document, local_uri, &error);
+	local_uri = g_filename_to_uri (tmp_filename, NULL, &error);
+        if (local_uri != NULL) {
+                ev_document_save (job->document, local_uri, &error);
+        }
+
 	close (fd);
 
 	ev_document_doc_mutex_unlock ();
@@ -1000,7 +989,7 @@ ev_job_save_run (EvJob *job)
 
 		uri_comp = ev_file_compress (local_uri, ctype, &error);
 		g_free (local_uri);
-		ev_tmp_filename_unlink (tmp_filename);
+		g_unlink (tmp_filename);
 
 		if (!uri_comp || error) {
 			local_uri = NULL;
@@ -1010,7 +999,7 @@ ev_job_save_run (EvJob *job)
 	}
 
 	g_free (tmp_filename);
-	
+
 	if (error) {
 		g_free (local_uri);
 		ev_job_failed_from_error (job, error);
diff --git a/shell/ev-application.c b/shell/ev-application.c
index bbd5ec6..2c6b509 100644
--- a/shell/ev-application.c
+++ b/shell/ev-application.c
@@ -885,7 +885,7 @@ ev_application_init (EvApplication *ev_application)
                                                     NULL);
 
         /* FIXME: why make this fatal? */
-        if (!ev_dir_ensure_exists (ev_application->dot_dir, 0700))
+        if (!ev_dir_ensure_exists (ev_application->dot_dir, 0700, NULL))
                 exit (1);
 
 #ifdef G_OS_WIN32
diff --git a/shell/ev-sidebar-attachments.c b/shell/ev-sidebar-attachments.c
index d89617b..74e89c4 100644
--- a/shell/ev-sidebar-attachments.c
+++ b/shell/ev-sidebar-attachments.c
@@ -410,7 +410,7 @@ ev_sidebar_attachments_drag_data_get (GtkWidget        *widget,
 		GtkTreePath  *path;
 		GtkTreeIter   iter;
 		GFile        *file;
-		gchar        *filename;
+		gchar        *filename, *template, *name;
 		GError       *error = NULL;
 		
 		path = (GtkTreePath *) l->data;
@@ -421,13 +421,12 @@ ev_sidebar_attachments_drag_data_get (GtkWidget        *widget,
 				    COLUMN_ATTACHMENT, &attachment,
 				    -1);
 
-		filename = g_build_filename (ev_tmp_dir (),
-					     ev_attachment_get_name (attachment),
-					     NULL);
-		file = g_file_new_for_path (filename);
-		g_free (filename);
+                /* FIXMEchpe: convert to filename encoding first! */
+                template = g_strdup_printf ("%s.XXXXXX", ev_attachment_get_name (attachment));
+                file = ev_mkstemp_file (template, &error);
+                g_free (template);
 		
-		if (ev_attachment_save (attachment, file, &error)) {
+		if (file != NULL && ev_attachment_save (attachment, file, &error)) {
 			gchar *uri;
 
 			uri = g_file_get_uri (file);
diff --git a/shell/ev-window.c b/shell/ev-window.c
index c55c9f8..042b4f9 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -1708,19 +1708,30 @@ ev_window_load_file_remote (EvWindow *ev_window,
 	GFile *target_file;
 	
 	if (!ev_window->priv->local_uri) {
-		gchar *tmp_name;
-		gchar *base_name;
+		char *base_name, *template;
+                GFile *tmp_file;
+                GError *err = NULL;
 
 		/* We'd like to keep extension of source uri since
-		 * it helps to resolve some mime types, say cbz */
-		tmp_name = ev_tmp_filename (NULL);
+		 * it helps to resolve some mime types, say cbz.
+                 */
 		base_name = g_file_get_basename (source_file);
-		ev_window->priv->local_uri = g_strconcat ("file:", tmp_name, "-",
-							  base_name, NULL);
+                template = g_build_filename ("document.XXXXXX-%s", base_name, NULL);
+                g_free (base_name);
+
+                tmp_file = ev_mkstemp_file (template, &err);
+                if (tmp_file == NULL) {
+                        ev_window_error_message (ev_window, err,
+                                                 "%s", _("Failed to load remote file."));
+                        g_error_free (err);
+                        return;
+                }
+
+		ev_window->priv->local_uri = g_file_get_uri (tmp_file);
+		g_object_unref (tmp_file);
+
 		ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job),
 				     ev_window->priv->local_uri);
-		g_free (base_name);
-		g_free (tmp_name);
 	}
 
 	ev_window_reset_progress_cancellable (ev_window);
@@ -4648,13 +4659,13 @@ ev_window_drag_data_received (GtkWidget        *widget,
 static void
 ev_window_finalize (GObject *object)
 {
+	G_OBJECT_CLASS (ev_window_parent_class)->finalize (object);
+
 	if (ev_window_n_copies == 0) {
 		ev_application_shutdown (EV_APP);
 	} else {
 		ev_window_n_copies--;
 	}
-
-	G_OBJECT_CLASS (ev_window_parent_class)->finalize (object);
 }
 
 static void
@@ -5629,7 +5640,9 @@ image_save_dialog_response_cb (GtkWidget *fc,
 	if (is_native) {
 		filename = g_file_get_path (target_file);
 	} else {
-		filename = ev_tmp_filename ("saveimage");
+                /* Create a temporary local file to save to */
+                if (ev_mkstemp ("saveimage.XXXXXX", &filename, &error) == -1)
+                        goto has_error;
 	}
 
 	ev_document_doc_mutex_lock ();
@@ -5642,6 +5655,7 @@ image_save_dialog_response_cb (GtkWidget *fc,
 	g_free (file_format);
 	g_object_unref (pixbuf);
 	
+    has_error:
 	if (error) {
 		ev_window_error_message (ev_window, error, 
 					 "%s", _("The image could not be saved."));
@@ -5774,7 +5788,7 @@ attachment_save_dialog_response_cb (GtkWidget *fc,
 	
 	for (l = ev_window->priv->attach_list; l && l->data; l = g_list_next (l)) {
 		EvAttachment *attachment;
-		GFile        *save_to;
+		GFile        *save_to = NULL;
 		GError       *error = NULL;
 		
 		attachment = (EvAttachment *) l->data;
@@ -5782,15 +5796,17 @@ attachment_save_dialog_response_cb (GtkWidget *fc,
 		if (is_native) {
 			if (is_dir) {
 				save_to = g_file_get_child (target_file,
+                                    /* FIXMEchpe: file name encoding! */
 							    ev_attachment_get_name (attachment));
 			} else {
 				save_to = g_object_ref (target_file);
 			}
 		} else {
-			save_to = ev_tmp_file_get ("saveattachment");
+			save_to = ev_mkstemp_file ("saveattachment.XXXXXX", &error);
 		}
 
-		ev_attachment_save (attachment, save_to, &error);
+                if (save_to)
+                        ev_attachment_save (attachment, save_to, &error);
 		
 		if (error) {
 			ev_window_error_message (ev_window, error, 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]