xref: /third_party/musl/src/time/__map_file.c (revision 570af302)
1#include <stdlib.h>
2#include <string.h>
3#include <sys/mman.h>
4#include <fcntl.h>
5#include <sys/stat.h>
6#include "syscall.h"
7
8static const size_t index_offset_offset = 12;
9static const size_t data_offset_offset = 16;
10static const size_t per_index_size = 48;
11
12const char unsigned *__map_file(const char *pathname, size_t *size)
13{
14	struct stat st;
15	const unsigned char *map = MAP_FAILED;
16	int fd = sys_open(pathname, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
17	if (fd < 0) return 0;
18	if (!__fstat(fd, &st)) {
19		map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
20		*size = st.st_size;
21	}
22#ifdef __LITEOS_A__
23	if (map == MAP_FAILED) {
24		__syscall(SYS_close, fd);
25	}
26#else
27	__syscall(SYS_close, fd);
28#endif
29
30	return map == MAP_FAILED ? 0 : map;
31}
32
33static size_t convert_byte_to_size_t(const unsigned char *map)
34{
35	/* Parse 4 continue bytes to size_t. 0, 1, 2, 3 is the index of bytes, 24, 16, 8 is the offset of byte in size_t*/
36	return ((size_t)map[0] << 24) + ((size_t)map[1] << 16) + ((size_t)map[2] << 8) + (size_t)map[3];
37}
38
39const char unsigned *__map_tzdata_file(const char * tzdata_path, const char *tz_id, size_t *tzdata_size,
40	size_t *offset, size_t *size)
41{
42	struct stat st;
43	const unsigned char *map = MAP_FAILED;
44	int fd = sys_open(tzdata_path, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
45	if (fd < 0) return 0;
46	if (!__fstat(fd, &st)) {
47		map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
48		*tzdata_size = st.st_size;
49	}
50	if (map == MAP_FAILED) {
51		__syscall(SYS_close, fd);
52		return 0;
53	}
54	size_t index_offset = convert_byte_to_size_t(map + index_offset_offset);
55	size_t data_offset = convert_byte_to_size_t(map + data_offset_offset);
56	int flag = 0;
57	while (index_offset < data_offset) {
58		if (!strncmp((const char *)map + index_offset, tz_id, strlen(tz_id))) {
59			/* 40 is the offset of file offset value in per index data*/
60			*offset = data_offset + convert_byte_to_size_t(map + index_offset + 40);
61			/* 44 is the offset of file length value in per index data*/
62			*size = convert_byte_to_size_t(map + index_offset + 44);
63			flag = 1;
64			break;
65		}
66		index_offset += per_index_size;
67	}
68	__syscall(SYS_close, fd);
69	if (flag) {
70		return map;
71	}
72	__munmap((void *)map, st.st_size);
73	return 0;
74}
75