aboutsummaryrefslogtreecommitdiffstats
path: root/e-util/e-xml-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'e-util/e-xml-utils.c')
-rw-r--r--e-util/e-xml-utils.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/e-util/e-xml-utils.c b/e-util/e-xml-utils.c
index 7e3560fdfb..6483b4122c 100644
--- a/e-util/e-xml-utils.c
+++ b/e-util/e-xml-utils.c
@@ -26,8 +26,13 @@
#include <config.h>
#endif
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
#include "e-xml-utils.h"
+#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -690,19 +695,27 @@ xmlDocContentDump (xmlBufferPtr buf, xmlDocPtr cur)
int
e_xml_save_file (const char *filename, xmlDocPtr doc)
{
+ char *filesave, *slash;
size_t n, written = 0;
xmlBufferPtr buf;
int errnosave;
ssize_t w;
int fd;
- fd = open (filename, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ filesave = alloca (strlen (filename) + 5);
+ slash = strrchr (filename, '/');
+ if (slash)
+ sprintf (filesave, "%.*s.#%s", slash - filename + 1, filename, slash + 1);
+ else
+ sprintf (filesave, ".#%s", filename);
+
+ fd = open (filesave, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd == -1)
return -1;
if (!(buf = xmlBufferCreate ())) {
close (fd);
- unlink (filename);
+ unlink (filesave);
errno = ENOMEM;
return -1;
}
@@ -724,12 +737,22 @@ e_xml_save_file (const char *filename, xmlDocPtr doc)
if (written < n || fsync (fd) == -1) {
errnosave = errno;
close (fd);
- unlink (filename);
+ unlink (filesave);
errno = errnosave;
return -1;
}
close (fd);
+ if (errno != 0)
+ return -1;
+
+ if (rename (filesave, filename) == -1) {
+ errnosave = errno;
+ unlink (filesave);
+ errno = errnosave;
+ return -1;
+ }
+
return 0;
}