106 lines
2.6 KiB
C
106 lines
2.6 KiB
C
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sched.h>
|
|
|
|
#if !CPUINFO_MOCK
|
|
#error This file should be built only in mock mode
|
|
#endif
|
|
|
|
#include <cpuinfo-mock.h>
|
|
#include <arm/linux/api.h>
|
|
#include <arm/midr.h>
|
|
#include <cpuinfo/log.h>
|
|
|
|
|
|
static struct cpuinfo_mock_file* cpuinfo_mock_files = NULL;
|
|
static uint32_t cpuinfo_mock_file_count = 0;
|
|
|
|
|
|
void CPUINFO_ABI cpuinfo_mock_filesystem(struct cpuinfo_mock_file* files) {
|
|
cpuinfo_log_info("filesystem mocking enabled");
|
|
uint32_t file_count = 0;
|
|
while (files[file_count].path != NULL) {
|
|
/* Indicate that file is not opened */
|
|
files[file_count].offset = SIZE_MAX;
|
|
file_count += 1;
|
|
}
|
|
cpuinfo_mock_files = files;
|
|
cpuinfo_mock_file_count = file_count;
|
|
}
|
|
|
|
int CPUINFO_ABI cpuinfo_mock_open(const char* path, int oflag) {
|
|
if (cpuinfo_mock_files == NULL) {
|
|
cpuinfo_log_warning("cpuinfo_mock_open called without mock filesystem; redictering to open");
|
|
return open(path, oflag);
|
|
}
|
|
|
|
for (uint32_t i = 0; i < cpuinfo_mock_file_count; i++) {
|
|
if (strcmp(cpuinfo_mock_files[i].path, path) == 0) {
|
|
if (oflag != O_RDONLY) {
|
|
errno = EACCES;
|
|
return -1;
|
|
}
|
|
if (cpuinfo_mock_files[i].offset != SIZE_MAX) {
|
|
errno = ENFILE;
|
|
return -1;
|
|
}
|
|
cpuinfo_mock_files[i].offset = 0;
|
|
return (int) i;
|
|
}
|
|
}
|
|
errno = ENOENT;
|
|
return -1;
|
|
}
|
|
|
|
int CPUINFO_ABI cpuinfo_mock_close(int fd) {
|
|
if (cpuinfo_mock_files == NULL) {
|
|
cpuinfo_log_warning("cpuinfo_mock_close called without mock filesystem; redictering to close");
|
|
return close(fd);
|
|
}
|
|
|
|
if ((unsigned int) fd >= cpuinfo_mock_file_count) {
|
|
errno = EBADF;
|
|
return -1;
|
|
}
|
|
if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
|
|
errno = EBADF;
|
|
return -1;
|
|
}
|
|
cpuinfo_mock_files[fd].offset = SIZE_MAX;
|
|
return 0;
|
|
}
|
|
|
|
ssize_t CPUINFO_ABI cpuinfo_mock_read(int fd, void* buffer, size_t capacity) {
|
|
if (cpuinfo_mock_files == NULL) {
|
|
cpuinfo_log_warning("cpuinfo_mock_read called without mock filesystem; redictering to read");
|
|
return read(fd, buffer, capacity);
|
|
}
|
|
|
|
if ((unsigned int) fd >= cpuinfo_mock_file_count) {
|
|
errno = EBADF;
|
|
return -1;
|
|
}
|
|
if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
|
|
errno = EBADF;
|
|
return -1;
|
|
}
|
|
|
|
const size_t offset = cpuinfo_mock_files[fd].offset;
|
|
size_t count = cpuinfo_mock_files[fd].size - offset;
|
|
if (count > capacity) {
|
|
count = capacity;
|
|
}
|
|
memcpy(buffer, (void*) cpuinfo_mock_files[fd].content + offset, count);
|
|
cpuinfo_mock_files[fd].offset += count;
|
|
return (ssize_t) count;
|
|
}
|