aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sam.c2
-rw-r--r--text.c14
-rw-r--r--text.h8
3 files changed, 13 insertions, 11 deletions
diff --git a/sam.c b/sam.c
index 337f8a4..960c670 100644
--- a/sam.c
+++ b/sam.c
@@ -1349,7 +1349,7 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Curs
return false;
}
- TextSave *ctx = text_save_begin(text, *name);
+ TextSave *ctx = text_save_begin(text, *name, TEXT_SAVE_AUTO);
if (!ctx) {
vis_info_show(vis, "Can't write `%s': %s", *name, strerror(errno));
return false;
diff --git a/text.c b/text.c
index 2163deb..55957c0 100644
--- a/text.c
+++ b/text.c
@@ -129,11 +129,7 @@ struct TextSave { /* used to hold context between text_save_{be
char *filename; /* filename to save to as given to text_save_begin */
char *tmpname; /* temporary name used for atomic rename(2) */
int fd; /* file descriptor to write data to using text_save_write */
- enum {
- TEXT_SAVE_UNKNOWN,
- TEXT_SAVE_ATOMIC, /* create a new file, write content, atomically rename(2) over old file */
- TEXT_SAVE_INPLACE, /* truncate file, overwrite content (any error will result in data loss) */
- } type;
+ enum TextSaveMethod type; /* method used to save file */
};
/* block management */
@@ -997,7 +993,7 @@ static bool text_save_commit_inplace(TextSave *ctx) {
return true;
}
-TextSave *text_save_begin(Text *txt, const char *filename) {
+TextSave *text_save_begin(Text *txt, const char *filename, enum TextSaveMethod type) {
if (!filename)
return NULL;
TextSave *ctx = calloc(1, sizeof *ctx);
@@ -1008,11 +1004,11 @@ TextSave *text_save_begin(Text *txt, const char *filename) {
if (!(ctx->filename = strdup(filename)))
goto err;
errno = 0;
- if (text_save_begin_atomic(ctx))
+ if ((type == TEXT_SAVE_AUTO || type == TEXT_SAVE_ATOMIC) && text_save_begin_atomic(ctx))
return ctx;
if (errno == ENOSPC)
goto err;
- if (text_save_begin_inplace(ctx))
+ if ((type == TEXT_SAVE_AUTO || type == TEXT_SAVE_INPLACE) && text_save_begin_inplace(ctx))
return ctx;
err:
text_save_cancel(ctx);
@@ -1073,7 +1069,7 @@ bool text_save_range(Text *txt, Filerange *range, const char *filename) {
text_snapshot(txt);
return true;
}
- TextSave *ctx = text_save_begin(txt, filename);
+ TextSave *ctx = text_save_begin(txt, filename, TEXT_SAVE_AUTO);
if (!ctx)
return false;
ssize_t written = text_write_range(txt, range, ctx->fd);
diff --git a/text.h b/text.h
index ee7dd6b..0306a4c 100644
--- a/text.h
+++ b/text.h
@@ -128,6 +128,12 @@ enum TextNewLine {
enum TextNewLine text_newline_type(Text*);
const char *text_newline_char(Text*);
+enum TextSaveMethod {
+ TEXT_SAVE_AUTO, /* first try atomic, then fall back to inplace */
+ TEXT_SAVE_ATOMIC, /* create a new file, write content, atomically rename(2) over old file */
+ TEXT_SAVE_INPLACE, /* truncate file, overwrite content (any error will result in data loss) */
+};
+
/* save the whole text to the given `filename'. Return true if succesful.
* In which case an implicit snapshot is taken. The save might associate a
* new inode to file. */
@@ -138,7 +144,7 @@ bool text_save_range(Text*, Filerange*, const char *file);
* file ranges. For every call to `text_save_begin` there must be exactly
* one matching call to either `text_save_commit` or `text_save_cancel`
* to release the underlying resources. */
-TextSave *text_save_begin(Text*, const char *filename);
+TextSave *text_save_begin(Text*, const char *filename, enum TextSaveMethod);
ssize_t text_save_write_range(TextSave*, Filerange*);
/* try committing the changes to disk */
bool text_save_commit(TextSave*);