mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
Bug 548988 - g_file_replace fails on Windows when the target file exists
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. svn path=/trunk/; revision=7388
This commit is contained in:
parent
886c0e0d81
commit
02d9af3562
@ -1,3 +1,17 @@
|
||||
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 ===
|
||||
|
@ -185,11 +185,33 @@ g_local_file_output_stream_close (GOutputStream *stream,
|
||||
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 @@ g_local_file_output_stream_close (GOutputStream *stream,
|
||||
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 @@ g_local_file_output_stream_close (GOutputStream *stream,
|
||||
|
||||
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 @@ handle_overwrite_open (const char *filename,
|
||||
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 @@ handle_overwrite_open (const char *filename,
|
||||
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 @@ handle_overwrite_open (const char *filename,
|
||||
|
||||
if (create_backup)
|
||||
{
|
||||
#if defined(HAVE_FCHOWN) && defined(HAVE_FCHMOD)
|
||||
struct stat tmp_statbuf;
|
||||
#endif
|
||||
char *backup_filename;
|
||||
int bfd;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user