aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-10-25 15:18:23 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-10-25 15:32:49 +0200
commitc42e9887aac08eeb96ccbe58453969497b5ea0ee (patch)
tree081a4b1096c7cd8362e8855482b7c3ca961c48e1
parentaf1859662a3551f6b0da4c7c56df3854748d66e8 (diff)
downloadvis-c42e9887aac08eeb96ccbe58453969497b5ea0ee.tar.gz
vis-c42e9887aac08eeb96ccbe58453969497b5ea0ee.tar.xz
Support partial writes
-rw-r--r--text.c29
-rw-r--r--text.h1
-rw-r--r--vis.c2
3 files changed, 22 insertions, 10 deletions
diff --git a/text.c b/text.c
index c0b5eee..40d09f0 100644
--- a/text.c
+++ b/text.c
@@ -664,26 +664,37 @@ err:
}
ssize_t text_write(Text *txt, int fd) {
- ssize_t len = 0;
- text_iterate(txt, it, 0) {
- size_t plen = it.end - it.start, poff = 0;
- while (plen > 0) {
- ssize_t res = write(fd, it.start + poff, plen);
+ Filerange r = (Filerange){ .start = 0, .end = text_size(txt) };
+ return text_range_write(txt, &r, fd);
+}
+
+ssize_t text_range_write(Text *txt, Filerange *range, int fd) {
+ size_t size = range->end - range->start;
+ size_t rem = size;
+ for (Iterator it = text_iterator_get(txt, range->start);
+ rem > 0 && text_iterator_valid(&it);
+ text_iterator_next(&it)) {
+ size_t prem = it.end - it.text, poff = 0;
+ if (prem > rem)
+ prem = rem;
+ while (prem > 0) {
+ ssize_t res = write(fd, it.text + poff, prem);
if (res < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
return -1;
}
if (res == 0)
- break;
+ goto out;
poff += res;
- plen -= res;
+ prem -= res;
+ rem -= res;
}
- len += plen;
}
+out:
txt->saved_action = txt->undo;
text_snapshot(txt);
- return len;
+ return size - rem;
}
/* load the given file as starting point for further editing operations.
diff --git a/text.h b/text.h
index 89e2bdc..4a9729e 100644
--- a/text.h
+++ b/text.h
@@ -87,6 +87,7 @@ bool text_newlines_crnl(Text*);
bool text_save(Text*, const char *file);
bool text_range_save(Text*, Filerange*, const char *file);
ssize_t text_write(Text*, int fd);
+ssize_t text_range_write(Text*, Filerange*, int fd);
void text_free(Text*);
typedef struct Regex Regex;
diff --git a/vis.c b/vis.c
index d764eb4..8e0fc1c 100644
--- a/vis.c
+++ b/vis.c
@@ -1416,7 +1416,7 @@ static bool cmd_write(Filerange *range, const char *argv[]) {
argv[1] = text_filename_get(text);
if (!argv[1]) {
if (text_fd_get(text) == STDIN_FILENO)
- return text_write(text, STDOUT_FILENO) >= 0;
+ return text_range_write(text, range, STDOUT_FILENO) >= 0;
editor_info_show(vis, "Filename expected");
return false;
}