summaryrefslogtreecommitdiffstats
path: root/flashrom.c
diff options
context:
space:
mode:
Diffstat (limited to 'flashrom.c')
-rw-r--r--flashrom.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/flashrom.c b/flashrom.c
index c9c7e31..113a05b 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -28,6 +28,7 @@
#include <sys/stat.h>
#endif
#include <string.h>
+#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
@@ -1255,36 +1256,36 @@ int read_buf_from_file(unsigned char *buf, unsigned long size,
msg_gerr("Error: No file I/O support in libpayload\n");
return 1;
#else
- unsigned long numbytes;
- FILE *image;
- struct stat image_stat;
+ int ret = 0;
+ FILE *image;
if ((image = fopen(filename, "rb")) == NULL) {
msg_gerr("Error: opening file \"%s\" failed: %s\n", filename, strerror(errno));
return 1;
}
+
+ struct stat image_stat;
if (fstat(fileno(image), &image_stat) != 0) {
msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
- fclose(image);
- return 1;
+ ret = 1;
+ goto out;
}
if (image_stat.st_size != size) {
msg_gerr("Error: Image size (%jd B) doesn't match the flash chip's size (%lu B)!\n",
(intmax_t)image_stat.st_size, size);
- fclose(image);
- return 1;
- }
- numbytes = fread(buf, 1, size, image);
- if (fclose(image)) {
- msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
- return 1;
+ ret = 1;
+ goto out;
}
+
+ unsigned long numbytes = fread(buf, 1, size, image);
if (numbytes != size) {
msg_gerr("Error: Failed to read complete file. Got %ld bytes, "
"wanted %ld!\n", numbytes, size);
- return 1;
+ ret = 1;
}
- return 0;
+out:
+ (void)fclose(image);
+ return ret;
#endif
}
@@ -1294,8 +1295,8 @@ int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *
msg_gerr("Error: No file I/O support in libpayload\n");
return 1;
#else
- unsigned long numbytes;
FILE *image;
+ int ret = 0;
if (!filename) {
msg_gerr("No filename specified.\n");
@@ -1306,14 +1307,37 @@ int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *
return 1;
}
- numbytes = fwrite(buf, 1, size, image);
- fclose(image);
+ unsigned long numbytes = fwrite(buf, 1, size, image);
if (numbytes != size) {
- msg_gerr("File %s could not be written completely.\n",
- filename);
- return 1;
+ msg_gerr("Error: file %s could not be written completely.\n", filename);
+ ret = 1;
+ goto out;
}
- return 0;
+ if (fflush(image)) {
+ msg_gerr("Error: flushing file \"%s\" failed: %s\n", filename, strerror(errno));
+ ret = 1;
+ }
+ // Try to fsync() only regular files and if that function is available at all (e.g. not on MinGW).
+#if defined(_POSIX_FSYNC) && (_POSIX_FSYNC != -1)
+ struct stat image_stat;
+ if (fstat(fileno(image), &image_stat) != 0) {
+ msg_gerr("Error: getting metadata of file \"%s\" failed: %s\n", filename, strerror(errno));
+ ret = 1;
+ goto out;
+ }
+ if (S_ISREG(image_stat.st_mode)) {
+ if (fsync(fileno(image))) {
+ msg_gerr("Error: fsyncing file \"%s\" failed: %s\n", filename, strerror(errno));
+ ret = 1;
+ }
+ }
+#endif
+out:
+ if (fclose(image)) {
+ msg_gerr("Error: closing file \"%s\" failed: %s\n", filename, strerror(errno));
+ ret = 1;
+ }
+ return ret;
#endif
}
OpenPOWER on IntegriCloud