From 5cc8e92ad9fb04792682b474a670aaa803666f78 Mon Sep 17 00:00:00 2001 From: Nickolay V. Shmyrev Date: Wed, 03 Aug 2005 05:49:48 +0000 Subject: Copy-paste g_file_set_contents to keep compatibility with gtk 2.6 Fix for bug 312228 --- diff --git a/ChangeLog b/ChangeLog index 1bbd6fd..b802221 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-08-03 Nickolay V. Shmyrev + + * configure.ac: + * shell/ev-utils.c: (rename_file), (set_umask_permissions), + (write_to_temp_file), (ev_file_set_contents): + * shell/ev-utils.h: + * shell/ev-window.c: (save_print_config_to_file): + + Copy-paste g_file_set_contents to keep compatibility with gtk 2.6 + Fix for bug 312228 + 2005-07-31 Christian Persch * shell/ev-window.c: (load_print_config_from_file), diff --git a/configure.ac b/configure.ac index 2bf02ff..2027403 100644 --- a/configure.ac +++ b/configure.ac @@ -114,10 +114,11 @@ if test x$HAVE_NAUTILUS = "xyes"; then fi AM_CONDITIONAL(HAVE_NAUTILUS, test x$HAVE_NAUTILUS = "xyes") -dnl Check for gtk_icon_view_get_visible_range +dnl Check for functions not present in gtk 2.6 evince_save_LIBS=$LIBS LIBS="$LIBS $FRONTEND_CORE_LIBS" AC_CHECK_FUNCS(gtk_icon_view_get_visible_range) +AC_CHECK_FUNCS(g_file_set_contents) LIBS=$evince_save_LIBS dnl GConf configuration diff --git a/shell/ev-utils.c b/shell/ev-utils.c index cf8a67c..587dd73 100644 --- a/shell/ev-utils.c +++ b/shell/ev-utils.c @@ -177,3 +177,216 @@ ev_pixbuf_add_shadow (GdkPixbuf *src, int size, } +#ifndef HAVE_G_FILE_SET_CONTENTS + +#include +#include +#include +#include +#include + +static gboolean +rename_file (const char *old_name, + const char *new_name, + GError **err) +{ + errno = 0; + if (g_rename (old_name, new_name) == -1) + { + return FALSE; + } + + return TRUE; +} + +static gboolean +set_umask_permissions (int fd, + GError **err) +{ + /* All of this function is just to work around the fact that + * there is no way to get the umask without changing it. + * + * We can't just change-and-reset the umask because that would + * lead to a race condition if another thread tried to change + * the umask in between the getting and the setting of the umask. + * So we have to do the whole thing in a child process. + */ + + int save_errno; + pid_t pid; + + pid = fork (); + + if (pid == -1) + { + return FALSE; + } + else if (pid == 0) + { + /* child */ + mode_t mask = umask (0666); + + errno = 0; + if (fchmod (fd, 0666 & ~mask) == -1) + _exit (errno); + else + _exit (0); + + return TRUE; /* To quiet gcc */ + } + else + { + /* parent */ + int status; + + errno = 0; + if (waitpid (pid, &status, 0) == -1) + { + return FALSE; + } + + if (WIFEXITED (status)) + { + save_errno = WEXITSTATUS (status); + + if (save_errno == 0) + { + return TRUE; + } + else + { + return FALSE; + } + } + else if (WIFSIGNALED (status)) + { + return FALSE; + } + else + { + return FALSE; + } + } +} + +static gchar * +write_to_temp_file (const gchar *contents, + gssize length, + const gchar *template, + GError **err) +{ + gchar *tmp_name; + gchar *display_name; + gchar *retval; + FILE *file; + gint fd; + int save_errno; + + retval = NULL; + + tmp_name = g_strdup_printf ("%s.XXXXXX", template); + + errno = 0; + fd = g_mkstemp (tmp_name); + display_name = g_filename_display_name (tmp_name); + + if (fd == -1) + { + goto out; + } + + if (!set_umask_permissions (fd, err)) + { + close (fd); + g_unlink (tmp_name); + + goto out; + } + + errno = 0; + file = fdopen (fd, "wb"); + if (!file) + { + close (fd); + g_unlink (tmp_name); + + goto out; + } + + if (length > 0) + { + size_t n_written; + + errno = 0; + + n_written = fwrite (contents, 1, length, file); + + if (n_written < length) + { + fclose (file); + g_unlink (tmp_name); + + goto out; + } + } + + errno = 0; + if (fclose (file) == EOF) + { + g_unlink (tmp_name); + + goto out; + } + + retval = g_strdup (tmp_name); + + out: + g_free (tmp_name); + g_free (display_name); + + return retval; +} + +gboolean +ev_file_set_contents (const gchar *filename, + const gchar *contents, + gssize length, + GError **error) +{ + gchar *tmp_filename; + gboolean retval; + GError *rename_error = NULL; + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (contents != NULL || length == 0, FALSE); + g_return_val_if_fail (length >= -1, FALSE); + + if (length == -1) + length = strlen (contents); + + tmp_filename = write_to_temp_file (contents, length, filename, error); + + if (!tmp_filename) + { + retval = FALSE; + goto out; + } + + if (!rename_file (tmp_filename, filename, &rename_error)) + { + g_unlink (tmp_filename); + g_propagate_error (error, rename_error); + retval = FALSE; + goto out; + } + + retval = TRUE; + + out: + g_free (tmp_filename); + return retval; +} + +#endif /* HAVE_G_FILE_SET_CONTENTS */ + diff --git a/shell/ev-utils.h b/shell/ev-utils.h index 084a285..9875a95 100644 --- a/shell/ev-utils.h +++ b/shell/ev-utils.h @@ -28,6 +28,14 @@ G_BEGIN_DECLS GdkPixbuf *ev_pixbuf_add_shadow (GdkPixbuf *src, int size, int x_offset, int y_offset, double opacity); +#ifndef HAVE_G_FILE_SET_CONTENTS + +gboolean ev_file_set_contents (const gchar *filename, + const gchar *contents, + gssize length, + GError **error); +#endif /* HAVE_G_FILE_SET_CONTENTS */ + G_END_DECLS #endif /* __EV_VIEW_H__ */ diff --git a/shell/ev-window.c b/shell/ev-window.c index cef9c24..e039781 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -61,6 +61,7 @@ #include "ev-application.h" #include "ev-stock-icons.h" #include "ev-metadata-manager.h" +#include "ev-file-helpers.h" #include @@ -1334,8 +1335,12 @@ save_print_config_to_file (GnomePrintConfig *config) file_name = g_build_filename (ev_dot_dir (), PRINT_CONFIG_FILENAME, NULL); - + +#ifdef HAVE_G_FILE_SET_CONTENTS g_file_set_contents (file_name, str, -1, NULL); +#else + ev_file_set_contents (file_name, str, -1, NULL); +#endif g_free (file_name); g_free (str); -- cgit v0.9.1