summaryrefslogtreecommitdiff
path: root/methods/rred.cc
diff options
context:
space:
mode:
authorAnthony Towns <aj@erisian.com.au>2014-01-21 05:00:12 +1000
committerAnthony Towns <aj@erisian.com.au>2014-01-21 05:00:12 +1000
commit2fd754cfe9a92fe85f4dd56447c70112b64b003e (patch)
treef47ae55bd34e5237e1e478e1c8bc8039677af5a8 /methods/rred.cc
parent1700c3cfb902f3f61fa4d9269523467fcceaaf58 (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.cc39
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);