summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/intelvbttool/intelvbttool.c39
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;
}