1 #include <stdbool.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <stddef.h>
5 #include <string.h>
6 #include <errno.h>
7
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <sched.h>
13
14 #if !CPUINFO_MOCK
15 #error This file should be built only in mock mode
16 #endif
17
18 #include <cpuinfo-mock.h>
19 #include <arm/linux/api.h>
20 #include <arm/midr.h>
21 #include <cpuinfo/log.h>
22
23
24 static struct cpuinfo_mock_file* cpuinfo_mock_files = NULL;
25 static uint32_t cpuinfo_mock_file_count = 0;
26
27
cpuinfo_mock_filesystem(struct cpuinfo_mock_file * files)28 void CPUINFO_ABI cpuinfo_mock_filesystem(struct cpuinfo_mock_file* files) {
29 cpuinfo_log_info("filesystem mocking enabled");
30 uint32_t file_count = 0;
31 while (files[file_count].path != NULL) {
32 /* Indicate that file is not opened */
33 files[file_count].offset = SIZE_MAX;
34 file_count += 1;
35 }
36 cpuinfo_mock_files = files;
37 cpuinfo_mock_file_count = file_count;
38 }
39
cpuinfo_mock_open(const char * path,int oflag)40 int CPUINFO_ABI cpuinfo_mock_open(const char* path, int oflag) {
41 if (cpuinfo_mock_files == NULL) {
42 cpuinfo_log_warning("cpuinfo_mock_open called without mock filesystem; redictering to open");
43 return open(path, oflag);
44 }
45
46 for (uint32_t i = 0; i < cpuinfo_mock_file_count; i++) {
47 if (strcmp(cpuinfo_mock_files[i].path, path) == 0) {
48 if (oflag != O_RDONLY) {
49 errno = EACCES;
50 return -1;
51 }
52 if (cpuinfo_mock_files[i].offset != SIZE_MAX) {
53 errno = ENFILE;
54 return -1;
55 }
56 cpuinfo_mock_files[i].offset = 0;
57 return (int) i;
58 }
59 }
60 errno = ENOENT;
61 return -1;
62 }
63
cpuinfo_mock_close(int fd)64 int CPUINFO_ABI cpuinfo_mock_close(int fd) {
65 if (cpuinfo_mock_files == NULL) {
66 cpuinfo_log_warning("cpuinfo_mock_close called without mock filesystem; redictering to close");
67 return close(fd);
68 }
69
70 if ((unsigned int) fd >= cpuinfo_mock_file_count) {
71 errno = EBADF;
72 return -1;
73 }
74 if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
75 errno = EBADF;
76 return -1;
77 }
78 cpuinfo_mock_files[fd].offset = SIZE_MAX;
79 return 0;
80 }
81
cpuinfo_mock_read(int fd,void * buffer,size_t capacity)82 ssize_t CPUINFO_ABI cpuinfo_mock_read(int fd, void* buffer, size_t capacity) {
83 if (cpuinfo_mock_files == NULL) {
84 cpuinfo_log_warning("cpuinfo_mock_read called without mock filesystem; redictering to read");
85 return read(fd, buffer, capacity);
86 }
87
88 if ((unsigned int) fd >= cpuinfo_mock_file_count) {
89 errno = EBADF;
90 return -1;
91 }
92 if (cpuinfo_mock_files[fd].offset == SIZE_MAX) {
93 errno = EBADF;
94 return -1;
95 }
96
97 const size_t offset = cpuinfo_mock_files[fd].offset;
98 size_t count = cpuinfo_mock_files[fd].size - offset;
99 if (count > capacity) {
100 count = capacity;
101 }
102 memcpy(buffer, (void*) cpuinfo_mock_files[fd].content + offset, count);
103 cpuinfo_mock_files[fd].offset += count;
104 return (ssize_t) count;
105 }
106