xref: /aosp_15_r20/external/cpuinfo/src/linux/smallfile.c (revision 2b54f0db79fd8303838913b20ff3780cddaa909f)
1*2b54f0dbSXin Li #include <stdbool.h>
2*2b54f0dbSXin Li #include <stdint.h>
3*2b54f0dbSXin Li #include <stdlib.h>
4*2b54f0dbSXin Li #include <string.h>
5*2b54f0dbSXin Li #include <alloca.h>
6*2b54f0dbSXin Li #include <errno.h>
7*2b54f0dbSXin Li 
8*2b54f0dbSXin Li #include <sys/types.h>
9*2b54f0dbSXin Li #include <sys/stat.h>
10*2b54f0dbSXin Li #include <unistd.h>
11*2b54f0dbSXin Li #include <fcntl.h>
12*2b54f0dbSXin Li 
13*2b54f0dbSXin Li #if CPUINFO_MOCK
14*2b54f0dbSXin Li 	#include <cpuinfo-mock.h>
15*2b54f0dbSXin Li #endif
16*2b54f0dbSXin Li #include <linux/api.h>
17*2b54f0dbSXin Li #include <cpuinfo/log.h>
18*2b54f0dbSXin Li 
19*2b54f0dbSXin Li 
cpuinfo_linux_parse_small_file(const char * filename,size_t buffer_size,cpuinfo_smallfile_callback callback,void * context)20*2b54f0dbSXin Li bool cpuinfo_linux_parse_small_file(const char* filename, size_t buffer_size, cpuinfo_smallfile_callback callback, void* context) {
21*2b54f0dbSXin Li 	int file = -1;
22*2b54f0dbSXin Li 	bool status = false;
23*2b54f0dbSXin Li 	char* buffer = (char*) alloca(buffer_size);
24*2b54f0dbSXin Li 
25*2b54f0dbSXin Li 	#if CPUINFO_LOG_DEBUG_PARSERS
26*2b54f0dbSXin Li 		cpuinfo_log_debug("parsing small file %s", filename);
27*2b54f0dbSXin Li 	#endif
28*2b54f0dbSXin Li 
29*2b54f0dbSXin Li #if CPUINFO_MOCK
30*2b54f0dbSXin Li 	file = cpuinfo_mock_open(filename, O_RDONLY);
31*2b54f0dbSXin Li #else
32*2b54f0dbSXin Li 	file = open(filename, O_RDONLY);
33*2b54f0dbSXin Li #endif
34*2b54f0dbSXin Li 	if (file == -1) {
35*2b54f0dbSXin Li 		cpuinfo_log_info("failed to open %s: %s", filename, strerror(errno));
36*2b54f0dbSXin Li 		goto cleanup;
37*2b54f0dbSXin Li 	}
38*2b54f0dbSXin Li 
39*2b54f0dbSXin Li 	size_t buffer_position = 0;
40*2b54f0dbSXin Li 	ssize_t bytes_read;
41*2b54f0dbSXin Li 	do {
42*2b54f0dbSXin Li #if CPUINFO_MOCK
43*2b54f0dbSXin Li 		bytes_read = cpuinfo_mock_read(file, &buffer[buffer_position], buffer_size - buffer_position);
44*2b54f0dbSXin Li #else
45*2b54f0dbSXin Li 		bytes_read = read(file, &buffer[buffer_position], buffer_size - buffer_position);
46*2b54f0dbSXin Li #endif
47*2b54f0dbSXin Li 		if (bytes_read < 0) {
48*2b54f0dbSXin Li 			cpuinfo_log_info("failed to read file %s at position %zu: %s", filename, buffer_position, strerror(errno));
49*2b54f0dbSXin Li 			goto cleanup;
50*2b54f0dbSXin Li 		}
51*2b54f0dbSXin Li 		buffer_position += (size_t) bytes_read;
52*2b54f0dbSXin Li 		if (buffer_position >= buffer_size) {
53*2b54f0dbSXin Li 			cpuinfo_log_error("failed to read file %s: insufficient buffer of size %zu", filename, buffer_size);
54*2b54f0dbSXin Li 			goto cleanup;
55*2b54f0dbSXin Li 		}
56*2b54f0dbSXin Li 	} while (bytes_read != 0);
57*2b54f0dbSXin Li 
58*2b54f0dbSXin Li 	status = callback(buffer, &buffer[buffer_position], context);
59*2b54f0dbSXin Li 
60*2b54f0dbSXin Li cleanup:
61*2b54f0dbSXin Li 	if (file != -1) {
62*2b54f0dbSXin Li #if CPUINFO_MOCK
63*2b54f0dbSXin Li 		cpuinfo_mock_close(file);
64*2b54f0dbSXin Li #else
65*2b54f0dbSXin Li 		close(file);
66*2b54f0dbSXin Li #endif
67*2b54f0dbSXin Li 		file = -1;
68*2b54f0dbSXin Li 	}
69*2b54f0dbSXin Li 	return status;
70*2b54f0dbSXin Li }
71