2022-06-29 21:29:15 +02:00
|
|
|
#include "../lib/io.h"
|
2022-06-29 10:58:49 +02:00
|
|
|
|
2022-07-12 22:33:01 +02:00
|
|
|
bool open_file(const char* path, FILE** file, struct stat* file_stat) {
|
|
|
|
(*file) = fopen(path, "r");
|
|
|
|
if ((*file) == NULL) {
|
2022-07-12 22:53:17 +02:00
|
|
|
if (errno == 0) errno = EIO;
|
2022-07-12 22:33:01 +02:00
|
|
|
return false;
|
2022-06-29 11:12:35 +02:00
|
|
|
}
|
2022-06-29 10:58:49 +02:00
|
|
|
|
2022-07-12 22:33:01 +02:00
|
|
|
int status = fstat(fileno((*file)), file_stat);
|
2022-06-29 11:12:35 +02:00
|
|
|
if (status == -1) {
|
2022-07-12 22:53:17 +02:00
|
|
|
if (errno == 0) errno = EIO;
|
2022-07-12 22:33:01 +02:00
|
|
|
fclose((*file));
|
|
|
|
return false;
|
2022-06-29 11:12:35 +02:00
|
|
|
};
|
2022-06-29 10:58:49 +02:00
|
|
|
|
2022-07-12 22:33:01 +02:00
|
|
|
if ((file_stat->st_mode & S_IFMT) != S_IFREG) {
|
2022-06-29 11:12:35 +02:00
|
|
|
printf("File is not a regular file!\n");
|
2022-07-12 22:53:17 +02:00
|
|
|
errno = ENOENT;
|
2022-07-12 22:33:01 +02:00
|
|
|
fclose((*file));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-07-23 18:06:25 +02:00
|
|
|
unsigned long get_available_memory() {
|
|
|
|
FILE* f;
|
|
|
|
struct stat statOfFile;
|
|
|
|
if (!open_file("/proc/meminfo", &f, &statOfFile)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char line[100];
|
|
|
|
while (fgets(line, sizeof(line), f)) {
|
|
|
|
unsigned long available_memory;
|
|
|
|
if (sscanf(line, "MemAvailable: %ld kB", &available_memory) == 1) {
|
|
|
|
fclose(f);
|
|
|
|
return available_memory * 1000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-07-12 22:33:01 +02:00
|
|
|
uint8_t* read_file(const char* path, size_t* size) {
|
|
|
|
// Read the contents of the file specified by path into a heap-allocated
|
|
|
|
// buffer and return a pointer to that buffer.
|
|
|
|
FILE* f;
|
|
|
|
struct stat statOfFile;
|
|
|
|
if (!open_file(path, &f, &statOfFile)) {
|
2022-06-29 22:02:18 +02:00
|
|
|
return NULL;
|
2022-06-29 11:12:35 +02:00
|
|
|
}
|
2022-06-29 10:58:49 +02:00
|
|
|
|
2022-07-23 18:06:25 +02:00
|
|
|
unsigned long available_memory = get_available_memory();
|
2022-07-20 15:51:29 +02:00
|
|
|
|
2022-07-23 18:06:25 +02:00
|
|
|
if (available_memory < (unsigned long)(statOfFile.st_size * 2)) {
|
2022-07-20 12:22:43 +02:00
|
|
|
errno = ENOMEM;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2022-07-20 15:51:29 +02:00
|
|
|
uint8_t* data = malloc(statOfFile.st_size);
|
2022-07-20 12:22:43 +02:00
|
|
|
if (data == NULL) {
|
|
|
|
fclose(f);
|
|
|
|
return NULL;
|
|
|
|
}
|
2022-06-29 10:58:49 +02:00
|
|
|
|
2022-08-29 20:27:39 +02:00
|
|
|
fread(data, 1, statOfFile.st_size, f);
|
2022-07-20 15:51:29 +02:00
|
|
|
|
2022-08-29 20:27:39 +02:00
|
|
|
if (ferror(f)) {
|
2022-06-29 10:58:49 +02:00
|
|
|
fclose(f);
|
2022-07-12 22:53:17 +02:00
|
|
|
if (errno == 0) errno = EIO;
|
2022-06-29 22:02:18 +02:00
|
|
|
return NULL;
|
2022-06-29 11:12:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fclose(f);
|
2022-06-29 10:58:49 +02:00
|
|
|
|
2022-06-29 20:54:41 +02:00
|
|
|
(*size) = statOfFile.st_size;
|
2022-06-29 22:02:18 +02:00
|
|
|
return data;
|
2022-06-29 10:58:49 +02:00
|
|
|
}
|