mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-09-06 16:08:43 +02:00
Bug 575555 – Use fsync() when replacing files to avoid data loss on
2009-03-16 Alexander Larsson <alexl@redhat.com> Bug 575555 – Use fsync() when replacing files to avoid data loss on crash * configure.in: Look for fsync(). * glib/gfileutils.c: (write_to_temp_file): fsync temp file if destination file exists 2009-03-16 Alexander Larsson <alexl@redhat.com> Bug 575555 – Use fsync() when replacing files to avoid data loss on crash * glocalfileoutputstream.c: (g_local_file_output_stream_close): (_g_local_file_output_stream_replace): fsync temp file before closing if replacing target file svn path=/trunk/; revision=7991
This commit is contained in:
committed by
Alexander Larsson
parent
0b66e52e0b
commit
6cff88ba18
@@ -868,7 +868,7 @@ rename_file (const char *old_name,
|
||||
static gchar *
|
||||
write_to_temp_file (const gchar *contents,
|
||||
gssize length,
|
||||
const gchar *template,
|
||||
const gchar *dest_file,
|
||||
GError **err)
|
||||
{
|
||||
gchar *tmp_name;
|
||||
@@ -880,7 +880,7 @@ write_to_temp_file (const gchar *contents,
|
||||
|
||||
retval = NULL;
|
||||
|
||||
tmp_name = g_strdup_printf ("%s.XXXXXX", template);
|
||||
tmp_name = g_strdup_printf ("%s.XXXXXX", dest_file);
|
||||
|
||||
errno = 0;
|
||||
fd = create_temp_file (tmp_name, 0666);
|
||||
@@ -942,11 +942,54 @@ write_to_temp_file (const gchar *contents,
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
errno = 0;
|
||||
if (fflush (file) != 0)
|
||||
{
|
||||
save_errno = errno;
|
||||
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
_("Failed to write file '%s': fflush() failed: %s"),
|
||||
display_name,
|
||||
g_strerror (save_errno));
|
||||
|
||||
g_unlink (tmp_name);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FSYNC
|
||||
errno = 0;
|
||||
/* If the final destination exists, we want to sync the newly written
|
||||
* file to ensure the data is on disk when we rename over the destination.
|
||||
* otherwise if we get a system crash we can lose both the new and the
|
||||
* old file on some filesystems. (I.E. those that don't guarantee the
|
||||
* data is written to the disk before the metadata.)
|
||||
*/
|
||||
if (g_file_test (dest_file, G_FILE_TEST_EXISTS) &&
|
||||
fsync (fileno (file)) != 0)
|
||||
{
|
||||
save_errno = errno;
|
||||
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
g_file_error_from_errno (save_errno),
|
||||
_("Failed to write file '%s': fsync() failed: %s"),
|
||||
display_name,
|
||||
g_strerror (save_errno));
|
||||
|
||||
g_unlink (tmp_name);
|
||||
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
errno = 0;
|
||||
if (fclose (file) == EOF)
|
||||
{
|
||||
save_errno = 0;
|
||||
save_errno = errno;
|
||||
|
||||
g_set_error (err,
|
||||
G_FILE_ERROR,
|
||||
|
Reference in New Issue
Block a user