summaryrefslogtreecommitdiff
path: root/src/dged
diff options
context:
space:
mode:
Diffstat (limited to 'src/dged')
-rw-r--r--src/dged/buffer.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/src/dged/buffer.c b/src/dged/buffer.c
index dcaa42c..a45f982 100644
--- a/src/dged/buffer.c
+++ b/src/dged/buffer.c
@@ -396,11 +396,17 @@ void buffer_to_file(struct buffer *buffer) {
}
char *fullname = expanduser(buffer->filename);
- FILE *file = fopen(fullname, "w");
- free(fullname);
+ size_t namelen = strlen(fullname);
+ char *backupname = malloc(namelen + 6);
+ memcpy(backupname, fullname, namelen);
+ memcpy(backupname + namelen, ".save", 5);
+ backupname[namelen + 5] = '\0';
+ FILE *file = fopen(backupname, "w+");
if (file == NULL) {
- minibuffer_echo("failed to open file %s for writing: %s", buffer->filename,
- strerror(errno));
+ minibuffer_echo("failed to open file \"%s\" (\"%s\") for writing: %s",
+ buffer->filename, backupname, strerror(errno));
+ free(fullname);
+ free(backupname);
return;
}
@@ -417,6 +423,16 @@ void buffer_to_file(struct buffer *buffer) {
minibuffer_echo_timeout(4, "wrote %d lines to %s", nlines_to_write,
buffer->filename);
fclose(file);
+ if (rename(backupname, fullname) == -1) {
+ minibuffer_echo("failed to rename backup \"%s\" to \"%s\": %s", backupname,
+ fullname, strerror(errno));
+ free(fullname);
+ free(backupname);
+ return;
+ }
+
+ free(fullname);
+ free(backupname);
buffer->modified = false;
undo_push_boundary(&buffer->undo, (struct undo_boundary){.save_point = true});