summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2009-08-11 21:27:57 +0930
committerRusty Russell <rusty@rustcorp.com.au>2009-08-11 21:27:57 +0930
commitba91d9ad7decb787e83c2826ba66bcaba670d450 (patch)
tree4ce2faaaabf6e7047144331e337209b08539bdf1
parente23f74c7fbf6a3db16b7f1b0c3e1122a65d7b258 (diff)
Fix multiply by three error, stat to get initial size.
-rw-r--r--ccan/grab_file/grab_file.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/ccan/grab_file/grab_file.c b/ccan/grab_file/grab_file.c
index f21e1e5e..b3a2f54d 100644
--- a/ccan/grab_file/grab_file.c
+++ b/ccan/grab_file/grab_file.c
@@ -9,18 +9,33 @@
void *grab_fd(const void *ctx, int fd, size_t *size)
{
int ret;
- size_t max = 16384, s;
+ size_t max, s;
char *buffer;
+ struct stat st;
if (!size)
size = &s;
*size = 0;
+ if (fstat(fd, &st) == 0)
+ max = st.st_size;
+ else
+ max = 16384;
+
buffer = talloc_array(ctx, char, max+1);
while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
*size += ret;
- if (*size == max)
- buffer = talloc_realloc(ctx, buffer, char, max*=2 + 1);
+ if (*size == max) {
+ buffer = talloc_realloc(ctx, buffer, char, max*2+1);
+ if (!buffer) {
+ buffer = talloc_realloc(ctx, buffer, char,
+ max + 1024*1024 + 1);
+ if (!buffer)
+ return NULL;
+ max += 1024*1024;
+ } else
+ max *= 2;
+ }
}
if (ret < 0) {
talloc_free(buffer);