From 1ab94ead7eed4110e6e3caf56aa354a54aa22d4e Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Mon, 13 May 2002 21:39:59 +0000 Subject: [PATCH] serialize to a temporary file and rename it to the target filename when it 2002-05-13 Sven Neumann * app/config/gimpconfig.c (gimp_config_serialize): serialize to a temporary file and rename it to the target filename when it is completely written. --- ChangeLog | 6 ++++++ app/config/gimpconfig.c | 33 ++++++++++++++++++++------------ libgimpconfig/gimpconfig-iface.c | 33 ++++++++++++++++++++------------ 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5afec91157..9aacd2685d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2002-05-13 Sven Neumann + + * app/config/gimpconfig.c (gimp_config_serialize): serialize to a + temporary file and rename it to the target filename when it is + completely written. + 2002-05-13 Michael Natterer * app/core/gimpparasite.c: parse parasiterc using GScanner instead diff --git a/app/config/gimpconfig.c b/app/config/gimpconfig.c index 2c8eea52ad..a87cf1846c 100644 --- a/app/config/gimpconfig.c +++ b/app/config/gimpconfig.c @@ -23,6 +23,7 @@ #include #include +#include #include #ifdef HAVE_UNISTD_H #include @@ -32,10 +33,6 @@ #include -#ifdef G_OS_WIN32 -#include -#endif - #include "gimpconfig.h" #include "gimpconfig-serialize.h" #include "gimpconfig-deserialize.h" @@ -181,6 +178,7 @@ gimp_config_serialize (GObject *object, GError **error) { GimpConfigInterface *gimp_config_iface; + gchar *tmpname; gint fd; g_return_val_if_fail (G_IS_OBJECT (object), FALSE); @@ -191,20 +189,17 @@ gimp_config_serialize (GObject *object, g_return_val_if_fail (gimp_config_iface != NULL, FALSE); - fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, -#ifndef G_OS_WIN32 - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH -#else - _S_IREAD | _S_IWRITE -#endif - ); + tmpname = g_strconcat (filename, "XXXXXX", NULL); + + fd = g_mkstemp (tmpname); if (fd == -1) { g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_FILE, - _("Failed to open file: '%s': %s"), + _("Failed to generate temporary file for '%s': %s"), filename, g_strerror (errno)); + g_free (tmpname); return FALSE; } @@ -212,6 +207,20 @@ gimp_config_serialize (GObject *object, close (fd); + if (rename (tmpname, filename) == -1) + { + g_set_error (error, + GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_FILE, + _("Failed to open file '%s' to '%s': %s"), + tmpname, filename, g_strerror (errno)); + + unlink (tmpname); + g_free (tmpname); + return FALSE; + } + + g_free (tmpname); + return TRUE; } diff --git a/libgimpconfig/gimpconfig-iface.c b/libgimpconfig/gimpconfig-iface.c index 2c8eea52ad..a87cf1846c 100644 --- a/libgimpconfig/gimpconfig-iface.c +++ b/libgimpconfig/gimpconfig-iface.c @@ -23,6 +23,7 @@ #include #include +#include #include #ifdef HAVE_UNISTD_H #include @@ -32,10 +33,6 @@ #include -#ifdef G_OS_WIN32 -#include -#endif - #include "gimpconfig.h" #include "gimpconfig-serialize.h" #include "gimpconfig-deserialize.h" @@ -181,6 +178,7 @@ gimp_config_serialize (GObject *object, GError **error) { GimpConfigInterface *gimp_config_iface; + gchar *tmpname; gint fd; g_return_val_if_fail (G_IS_OBJECT (object), FALSE); @@ -191,20 +189,17 @@ gimp_config_serialize (GObject *object, g_return_val_if_fail (gimp_config_iface != NULL, FALSE); - fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC, -#ifndef G_OS_WIN32 - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH -#else - _S_IREAD | _S_IWRITE -#endif - ); + tmpname = g_strconcat (filename, "XXXXXX", NULL); + + fd = g_mkstemp (tmpname); if (fd == -1) { g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_FILE, - _("Failed to open file: '%s': %s"), + _("Failed to generate temporary file for '%s': %s"), filename, g_strerror (errno)); + g_free (tmpname); return FALSE; } @@ -212,6 +207,20 @@ gimp_config_serialize (GObject *object, close (fd); + if (rename (tmpname, filename) == -1) + { + g_set_error (error, + GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_FILE, + _("Failed to open file '%s' to '%s': %s"), + tmpname, filename, g_strerror (errno)); + + unlink (tmpname); + g_free (tmpname); + return FALSE; + } + + g_free (tmpname); + return TRUE; }