Revision: 1893
http://geeqie.svn.sourceforge.net/geeqie/?rev=1893&view=rev
Author: zas_
Date: 2010-01-10 14:23:29 +0000 (Sun, 10 Jan 2010)
Log Message:
-----------
copy_file(): remove incomplete file on error (bug 2890715)
The behavior changed, data is first written to a temporary file,
which is unlinked in case of error, then the tempfile is renamed
to the final name.
Size of buffer was increased from 4k to 16k.
Modified Paths:
--------------
trunk/src/ui_fileops.c
Modified: trunk/src/ui_fileops.c
===================================================================
--- trunk/src/ui_fileops.c 2010-01-09 11:44:27 UTC (rev 1892)
+++ trunk/src/ui_fileops.c 2010-01-10 14:23:29 UTC (rev 1893)
@@ -520,52 +520,66 @@
{
FILE *fi = NULL;
FILE *fo = NULL;
- gchar *sl, *tl;
- gchar buf[4096];
+ gchar *sl = NULL;
+ gchar *tl = NULL;
+ gchar *randname = NULL;
+ gchar buf[16384];
size_t b;
+ gint ret = FALSE;
+ gint fd = -1;
sl = path_from_utf8(s);
tl = path_from_utf8(t);
if (hard_linked(sl, tl))
{
- g_free(sl);
- g_free(tl);
- return TRUE;
+ ret = TRUE;
+ goto end;
}
fi = fopen(sl, "rb");
- if (fi)
- {
- fo = fopen(tl, "wb");
- if (!fo)
- {
- fclose(fi);
- fi = NULL;
- }
- }
+ if (!fi) goto end;
+
+ /* First we write to a temporary file, then we rename it on success,
+ and attributes from original file are copied */
+ randname = g_strconcat(tl, ".tmp_XXXXXX", NULL);
+ if (!randname) goto end;
+
+ fd = g_mkstemp(randname);
+ if (fd == -1) goto end;
+
+ fo = fdopen(fd, "wb");
+ if (!fo) {
+ close(fd);
+ goto end;
+ }
- g_free(sl);
- g_free(tl);
-
- if (!fi || !fo) return FALSE;
-
while ((b = fread(buf, sizeof(gchar), sizeof(buf), fi)) && b != 0)
{
if (fwrite(buf, sizeof(gchar), b, fo) != b)
{
- fclose(fi);
- fclose(fo);
- return FALSE;
+ unlink(randname);
+ goto end;
}
}
- fclose(fi);
- fclose(fo);
+ fclose(fi); fi = NULL;
+ fclose(fo); fo = NULL;
- copy_file_attributes(s, t, TRUE, TRUE);
+ if (rename(randname, tl) < 0) {
+ unlink(randname);
+ goto end;
+ }
- return TRUE;
+ ret = copy_file_attributes(s, t, TRUE, TRUE);
+
+end:
+ if (fi) fclose(fi);
+ if (fo) fclose(fo);
+ if (sl) g_free(sl);
+ if (tl) g_free(tl);
+ if (randname) g_free(randname);
+ return ret;
}
gboolean move_file(const gchar *s, const gchar *t)
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn