diff options
Diffstat (limited to 'util/intelvbttool/intelvbttool.c')
-rw-r--r-- | util/intelvbttool/intelvbttool.c | 39 |
1 files changed, 17 insertions, 22 deletions
diff --git a/util/intelvbttool/intelvbttool.c b/util/intelvbttool/intelvbttool.c index 1444129b50..f8e4bda0f4 100644 --- a/util/intelvbttool/intelvbttool.c +++ b/util/intelvbttool/intelvbttool.c @@ -29,6 +29,7 @@ typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; +#define DEF_ALLOC 1024 typedef struct { u16 signature; @@ -380,39 +381,33 @@ static struct fileobject *malloc_fo_sub(const struct fileobject *old, static struct fileobject *read_file(const char *filename) { FILE *fd = fopen(filename, "rb"); + off_t read_size = DEF_ALLOC; if (!fd) { printerr("%s open failed: %s\n", filename, strerror(errno)); return NULL; } - if (fseek(fd, 0, SEEK_END)) { - printerr("%s seek failed: %s\n", filename, strerror(errno)); - fclose(fd); - return NULL; - } - - const off_t size = ftell(fd); - if (size < 0 || size > SIZE_MAX) { - printerr("%s tell failed: %s\n", filename, strerror(errno)); - fclose(fd); - return NULL; - } - - if (fseek(fd, 0, SEEK_SET)) { - printerr("%s seek failed: %s\n", filename, strerror(errno)); - fclose(fd); - return NULL; - } - - struct fileobject *fo = malloc_fo(size); + struct fileobject *fo = malloc_fo(read_size); if (!fo) { printerr("malloc failed\n"); fclose(fd); return NULL; } - if (fread(fo->data, 1, size, fd) != size) { + off_t total_bytes_read = 0, bytes_read; + while ((bytes_read = fread(fo->data + total_bytes_read, 1, read_size, fd)) > 0) { + total_bytes_read += bytes_read; + struct fileobject *newfo = remalloc_fo(fo, fo->size + read_size); + if (!newfo) { + fclose(fd); + free_fo(fo); + return NULL; + } + fo = newfo; + } + + if (!total_bytes_read) { fclose(fd); free_fo(fo); return NULL; @@ -424,7 +419,7 @@ static struct fileobject *read_file(const char *filename) return NULL; } - fo->size = size; + fo->size = total_bytes_read; return fo; } |