+/* reads a whole file to a buffer - returns -1 on errors and sets errno */
+static ssize_t read_file(const char *filename, void *buf, size_t len, size_t minlen) {
+ FILE *f;
+ ssize_t ret;
+
+ f = fopen(filename, "r");
+ if (!f)
+ return -1;
+
+ ret = fread(buf, 1, len, f);
+
+ /* Ensure that feof() yields the correct result when the file is exactly
+ * len bytes long */
+ fgetc(f);
+
+ if (ferror(f)) {
+ ret = -1;
+ } else if (!feof(f)) {
+ errno = EOVERFLOW;
+ ret = -1;
+ } else if ((size_t)ret < minlen) {
+ errno = EINVAL;
+ ret = -1;
+ }
+
+ fclose(f);
+ return ret;
+}
+