diff options
author | Anthony Towns <aj@erisian.com.au> | 2014-01-21 05:00:12 +1000 |
---|---|---|
committer | Anthony Towns <aj@erisian.com.au> | 2014-01-21 05:00:12 +1000 |
commit | 2fd754cfe9a92fe85f4dd56447c70112b64b003e (patch) | |
tree | f47ae55bd34e5237e1e478e1c8bc8039677af5a8 /methods/rred.cc | |
parent | 1700c3cfb902f3f61fa4d9269523467fcceaaf58 (diff) |
methods/rred: minor robustness improvements
Use retry_fwrite to better handle partial fwrite successes, and to keep
the Hashes in sync with what's actually written.
Diffstat (limited to 'methods/rred.cc')
-rw-r--r-- | methods/rred.cc | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/methods/rred.cc b/methods/rred.cc index 313166160..d17ab110d 100644 --- a/methods/rred.cc +++ b/methods/rred.cc @@ -351,14 +351,27 @@ class Patch { FileChanges filechanges; MemBlock add_text; + static bool retry_fwrite(char *b, size_t l, FILE *f, Hashes *hash) + { + size_t r = 1; + while (r > 0 && l > 0) + { + r = fwrite(b, 1, l, f); + if (hash) + hash->Add((unsigned char*)b, r); + l -= r; + b += r; + } + return l == 0; + } + static void dump_rest(FILE *o, FILE *i, Hashes *hash) { char buffer[BLOCK_SIZE]; size_t l; while (0 < (l = fread(buffer, 1, sizeof(buffer), i))) { - fwrite(buffer, 1, l, o); - if (hash) - hash->Add((unsigned char*)buffer, l); + if (!retry_fwrite(buffer, l, o, hash)) + break; } } @@ -372,10 +385,7 @@ class Patch { l = strlen(buffer); if (l == 0 || buffer[l-1] == '\n') n--; - fwrite(buffer, 1, l, o); - - if (hash) - hash->Add((unsigned char*)buffer, l); + retry_fwrite(buffer, l, o, hash); } } @@ -392,17 +402,8 @@ class Patch { } } - static bool dump_mem(FILE *o, char *p, size_t s, Hashes *hash) { - size_t r; - while (s > 0) { - r = fwrite(p, 1, s, o); - if (hash) - hash->Add((unsigned char*)p, s); - s -= r; - p += r; - if (r == 0) return false; - } - return true; + static void dump_mem(FILE *o, char *p, size_t s, Hashes *hash) { + retry_fwrite(p, s, o, hash); } public: @@ -455,7 +456,7 @@ class Patch { filechanges.add_change(ch); break; } - } else { /* !cmdwaanted */ + } else { /* !cmdwanted */ if (buffer[0] == '.' && buffer[1] == '\n') { cmdwanted = true; filechanges.add_change(ch); |