g_file_set_contents(): use unistd instead of stdio

Use a normal write() system call instead of fdopen() and fwrite().

This will definitely work on UNIX system and should work on Windows as
well...

As an added bonus, we can use g_close() now as well.

https://bugzilla.gnome.org/show_bug.cgi?id=701560
This commit is contained in:
Ryan Lortie 2013-06-03 17:49:06 -04:00
parent c152ceba09
commit e40435e834

View File

@ -1033,7 +1033,6 @@ write_to_temp_file (const gchar *contents,
{ {
gchar *tmp_name; gchar *tmp_name;
gchar *retval; gchar *retval;
FILE *file;
gint fd; gint fd;
retval = NULL; retval = NULL;
@ -1049,49 +1048,37 @@ write_to_temp_file (const gchar *contents,
goto out; goto out;
} }
errno = 0; #ifdef HAVE_POSIX_FALLOCATE
file = fdopen (fd, "wb");
if (!file)
{
format_error_message (err, tmp_name, _("Failed to open file '%s' for writing: fdopen() failed: %s"));
close (fd);
g_unlink (tmp_name);
goto out;
}
if (length > 0) if (length > 0)
{ {
gsize n_written;
#ifdef HAVE_POSIX_FALLOCATE
/* We do this on a 'best effort' basis... It may not be supported /* We do this on a 'best effort' basis... It may not be supported
* on the underlying filesystem. * on the underlying filesystem.
*/ */
(void) posix_fallocate (fd, 0, length); (void) posix_fallocate (fd, 0, length);
}
#endif #endif
while (length > 0)
{
gssize s;
errno = 0; s = write (fd, contents, length);
n_written = fwrite (contents, 1, length, file); if (s < 0)
if (n_written < length)
{ {
format_error_message (err, tmp_name, _("Failed to write file '%s': fwrite() failed: %s")); if (errno == EINTR)
fclose (file); continue;
format_error_message (err, tmp_name, _("Failed to write file '%s': write() failed: %s"));
close (fd);
g_unlink (tmp_name); g_unlink (tmp_name);
goto out; goto out;
} }
}
errno = 0; g_assert (s <= length);
if (fflush (file) != 0)
{
format_error_message (err, tmp_name, _("Failed to write file '%s': fflush() failed: %s"));
fclose (file);
g_unlink (tmp_name);
goto out; contents += s;
length -= s;
} }
#ifdef BTRFS_SUPER_MAGIC #ifdef BTRFS_SUPER_MAGIC
@ -1119,10 +1106,10 @@ write_to_temp_file (const gchar *contents,
* the new and the old file on some filesystems. (I.E. those that don't * 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.) * guarantee the data is written to the disk before the metadata.)
*/ */
if (g_lstat (dest_file, &statbuf) == 0 && statbuf.st_size > 0 && fsync (fileno (file)) != 0) if (g_lstat (dest_file, &statbuf) == 0 && statbuf.st_size > 0 && fsync (fd) != 0)
{ {
format_error_message (err, tmp_name, _("Failed to write file '%s': fsync() failed: %s")); format_error_message (err, tmp_name, _("Failed to write file '%s': fsync() failed: %s"));
fclose (file); close (fd);
g_unlink (tmp_name); g_unlink (tmp_name);
goto out; goto out;
@ -1135,9 +1122,8 @@ write_to_temp_file (const gchar *contents,
#endif #endif
errno = 0; errno = 0;
if (fclose (file) == EOF) if (g_close (fd, err))
{ {
format_error_message (err, tmp_name, _("Failed to close file '%s': fclose() failed: %s"));
g_unlink (tmp_name); g_unlink (tmp_name);
goto out; goto out;