/[LeafOK_CVS]/lbbs/src/file_loader.c
ViewVC logotype

Contents of /lbbs/src/file_loader.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.27 - (show annotations)
Sat Jan 3 10:27:14 2026 UTC (2 months, 1 week ago) by sysadm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.26: +1 -1 lines
Content type: text/x-csrc
Update copyright info

1 /* SPDX-License-Identifier: GPL-3.0-or-later */
2 /*
3 * file_loader
4 * - shared memory based file loader
5 *
6 * Copyright (C) 2004-2026 Leaflet <leaflet@leafok.com>
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include "file_loader.h"
14 #include "log.h"
15 #include "str_process.h"
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <time.h>
21 #include <unistd.h>
22 #include <sys/mman.h>
23 #include <sys/stat.h>
24
25 struct shm_header_t
26 {
27 size_t shm_size;
28 size_t data_len;
29 long line_total;
30 };
31
32 int load_file(const char *filename)
33 {
34 char filepath[FILE_PATH_LEN];
35 char shm_name[FILE_NAME_LEN];
36 int fd;
37 struct stat sb;
38 void *p_data;
39 size_t data_len;
40 size_t size;
41 void *p_shm;
42 long line_total;
43 long line_offsets[MAX_SPLIT_FILE_LINES];
44 long *p_line_offsets;
45
46 if (filename == NULL)
47 {
48 log_error("NULL pointer error");
49 return -1;
50 }
51
52 if ((fd = open(filename, O_RDONLY)) < 0)
53 {
54 log_error("open(%s) error (%d)", filename, errno);
55 return -1;
56 }
57
58 if (fstat(fd, &sb) < 0)
59 {
60 log_error("fstat(fd) error (%d)", errno);
61 close(fd);
62 return -1;
63 }
64
65 data_len = (size_t)sb.st_size;
66 p_data = mmap(NULL, data_len, PROT_READ, MAP_SHARED, fd, 0L);
67 if (p_data == MAP_FAILED)
68 {
69 log_error("mmap() error (%d)", errno);
70 close(fd);
71 return -2;
72 }
73
74 if (close(fd) < 0)
75 {
76 log_error("close(fd) error (%d)", errno);
77 return -1;
78 }
79
80 line_total = split_data_lines(p_data, SCREEN_COLS, line_offsets, MAX_SPLIT_FILE_LINES, 1, NULL);
81
82 // Allocate shared memory
83 size = sizeof(struct shm_header_t) + data_len + 1 + sizeof(long) * (size_t)(line_total + 1);
84
85 strncpy(filepath, filename, sizeof(filepath) - 1);
86 filepath[sizeof(filepath) - 1] = '\0';
87 snprintf(shm_name, sizeof(shm_name), "/FILE_SHM_%s", basename(filepath));
88
89 if (shm_unlink(shm_name) == -1 && errno != ENOENT)
90 {
91 log_error("shm_unlink(%s) error (%d)", shm_name, errno);
92 return -2;
93 }
94
95 if ((fd = shm_open(shm_name, O_CREAT | O_EXCL | O_RDWR, 0600)) == -1)
96 {
97 log_error("shm_open(%s) error (%d)", shm_name, errno);
98 return -2;
99 }
100 if (ftruncate(fd, (off_t)size) == -1)
101 {
102 log_error("ftruncate(size=%d) error (%d)", size, errno);
103 close(fd);
104 return -2;
105 }
106
107 p_shm = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0L);
108 if (p_shm == MAP_FAILED)
109 {
110 log_error("mmap() error (%d)", errno);
111 close(fd);
112 return -2;
113 }
114
115 if (close(fd) < 0)
116 {
117 log_error("close(fd) error (%d)", errno);
118 return -1;
119 }
120
121 ((struct shm_header_t *)p_shm)->shm_size = size;
122 ((struct shm_header_t *)p_shm)->data_len = data_len;
123 ((struct shm_header_t *)p_shm)->line_total = line_total;
124 memcpy((char *)p_shm + sizeof(struct shm_header_t), p_data, data_len);
125
126 if (munmap(p_data, data_len) < 0)
127 {
128 log_error("munmap() error (%d)", errno);
129 munmap(p_shm, size);
130 return -2;
131 }
132
133 p_data = (char *)p_shm + sizeof(struct shm_header_t);
134 p_line_offsets = (long *)((char *)p_data + data_len + 1);
135 memcpy(p_line_offsets, line_offsets, sizeof(long) * (size_t)(line_total + 1));
136
137 if (munmap(p_shm, size) < 0)
138 {
139 log_error("munmap() error (%d)", errno);
140 return -2;
141 }
142
143 return 0;
144 }
145
146 int unload_file(const char *filename)
147 {
148 char filepath[FILE_PATH_LEN];
149 char shm_name[FILE_NAME_LEN];
150
151 if (filename == NULL)
152 {
153 log_error("NULL pointer error");
154 return -1;
155 }
156
157 strncpy(filepath, filename, sizeof(filepath) - 1);
158 filepath[sizeof(filepath) - 1] = '\0';
159 snprintf(shm_name, sizeof(shm_name), "/FILE_SHM_%s", basename(filepath));
160
161 if (shm_unlink(shm_name) == -1 && errno != ENOENT)
162 {
163 log_error("shm_unlink(%s) error (%d)", shm_name, errno);
164 return -2;
165 }
166
167 return 0;
168 }
169
170 void *get_file_shm_readonly(const char *filename, size_t *p_data_len, long *p_line_total, const void **pp_data, const long **pp_line_offsets)
171 {
172 char filepath[FILE_PATH_LEN];
173 char shm_name[FILE_NAME_LEN];
174 int fd;
175 void *p_shm = NULL;
176 struct stat sb;
177 size_t size;
178
179 if (filename == NULL || p_data_len == NULL || p_line_total == NULL || pp_data == NULL || pp_line_offsets == NULL)
180 {
181 log_error("NULL pointer error");
182 return NULL;
183 }
184
185 strncpy(filepath, filename, sizeof(filepath) - 1);
186 filepath[sizeof(filepath) - 1] = '\0';
187 snprintf(shm_name, sizeof(shm_name), "/FILE_SHM_%s", basename(filepath));
188
189 if ((fd = shm_open(shm_name, O_RDONLY, 0600)) == -1)
190 {
191 log_error("shm_open(%s) error (%d)", shm_name, errno);
192 return NULL;
193 }
194
195 if (fstat(fd, &sb) < 0)
196 {
197 log_error("fstat(fd) error (%d)", errno);
198 close(fd);
199 return NULL;
200 }
201
202 size = (size_t)sb.st_size;
203
204 p_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0L);
205 if (p_shm == MAP_FAILED)
206 {
207 log_error("mmap() error (%d)", errno);
208 close(fd);
209 return NULL;
210 }
211
212 if (close(fd) < 0)
213 {
214 log_error("close(fd) error (%d)", errno);
215 return NULL;
216 }
217
218 if (((struct shm_header_t *)p_shm)->shm_size != size)
219 {
220 log_error("Shared memory size mismatch (%ld != %ld)", ((struct shm_header_t *)p_shm)->shm_size, size);
221 munmap(p_shm, size);
222 return NULL;
223 }
224
225 *p_data_len = ((struct shm_header_t *)p_shm)->data_len;
226 *p_line_total = ((struct shm_header_t *)p_shm)->line_total;
227 *pp_data = (char *)p_shm + sizeof(struct shm_header_t);
228 *pp_line_offsets = (const long *)((const char *)(*pp_data) + *p_data_len + 1);
229
230 return p_shm;
231 }
232
233 int detach_file_shm(void *p_shm)
234 {
235 size_t size;
236
237 if (p_shm == NULL)
238 {
239 return -1;
240 }
241
242 size = ((struct shm_header_t *)p_shm)->shm_size;
243
244 if (munmap(p_shm, size) < 0)
245 {
246 log_error("munmap() error (%d)", errno);
247 return -2;
248 }
249
250 return 0;
251 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1