glib r7388 - trunk/gio
- From: tml svn gnome org
- To: svn-commits-list gnome org
- Subject: glib r7388 - trunk/gio
- Date: Sat, 23 Aug 2008 01:09:08 +0000 (UTC)
Author: tml
Date: Sat Aug 23 01:09:08 2008
New Revision: 7388
URL: http://svn.gnome.org/viewvc/glib?rev=7388&view=rev
Log:
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.
Modified:
trunk/gio/ChangeLog
trunk/gio/glocalfileoutputstream.c
Modified: trunk/gio/glocalfileoutputstream.c
==============================================================================
--- trunk/gio/glocalfileoutputstream.c (original)
+++ trunk/gio/glocalfileoutputstream.c Sat Aug 23 01:09:08 2008
@@ -185,11 +185,33 @@
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,
@@ -264,6 +286,8 @@
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);
@@ -284,9 +308,18 @@
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;
}
@@ -615,10 +648,11 @@
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 */
@@ -657,7 +691,13 @@
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);
@@ -763,7 +803,9 @@
if (create_backup)
{
+#if defined(HAVE_FCHOWN) && defined(HAVE_FCHMOD)
struct stat tmp_statbuf;
+#endif
char *backup_filename;
int bfd;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]