+2008-08-23 Tor Lillqvist <tml@novell.com>
+
+ Bug 548988 - g_file_replace fails on Windows when the target file
+ exists already
+
+ * glocalfileoutputstream.c (g_local_file_output_stream_close): On
+ Windows, close the file before renaming it (in case we have been
+ writing to a file with a temporary name).
+
+ (g_local_file_output_stream_close, handle_overwrite_open): Use
+ GLocalFileStat instead of plain struct stat, for passing to
+ _g_local_file_info_create_etag(). Thus also use _fstati64()
+ instead of plain fstat() on Windows.
+
2008-08-18 Matthias Clasen <mclasen@redhat.com>
* === Released 2.17.7 ===
GError **error)
{
GLocalFileOutputStream *file;
- struct stat final_stat;
+ GLocalFileStat final_stat;
int res;
file = G_LOCAL_FILE_OUTPUT_STREAM (stream);
+#ifdef G_OS_WIN32
+
+ /* Must close before renaming on Windows, so just do the close first
+ * in all cases for now.
+ */
+ if (_fstati64 (file->priv->fd, &final_stat) == 0)
+ file->priv->etag = _g_local_file_info_create_etag (&final_stat);
+
+ res = close (file->priv->fd);
+ if (res == -1)
+ {
+ int errsv = errno;
+
+ g_set_error (error, G_IO_ERROR,
+ g_io_error_from_errno (errsv),
+ _("Error closing file: %s"),
+ g_strerror (errsv));
+ return FALSE;
+ }
+
+#endif
+
if (file->priv->tmp_filename)
{
/* We need to move the temp file to its final place,
if (g_cancellable_set_error_if_cancelled (cancellable, error))
goto err_out;
+#ifndef G_OS_WIN32 /* Already did the fstat() and close() above on Win32 */
+
if (fstat (file->priv->fd, &final_stat) == 0)
file->priv->etag = _g_local_file_info_create_etag (&final_stat);
return res != -1;
+#else
+
+ return TRUE;
+
+#endif
+
err_out:
+
+#ifndef G_OS_WIN32
/* A simple try to close the fd in case we fail before the actual close */
close (file->priv->fd);
+#endif
return FALSE;
}
GError **error)
{
int fd = -1;
- struct stat original_stat;
+ GLocalFileStat original_stat;
char *current_etag;
gboolean is_symlink;
int open_flags;
+ int res;
/* We only need read access to the original file if we are creating a backup.
* We also add O_CREATE to avoid a race if the file was just removed */
return -1;
}
- if (fstat (fd, &original_stat) != 0)
+#ifdef G_OS_WIN32
+ res = _fstati64 (fd, &original_stat);
+#else
+ res = fstat (fd, &original_stat);
+#endif
+
+ if (res != 0)
{
int errsv = errno;
char *display_name = g_filename_display_name (filename);
if (create_backup)
{
+#if defined(HAVE_FCHOWN) && defined(HAVE_FCHMOD)
struct stat tmp_statbuf;
+#endif
char *backup_filename;
int bfd;