Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/files.c
Parent Directory
|
Revision Log
Revision 518 -
(hide annotations)
(download)
(as text)
Sun Oct 31 17:52:40 2010 UTC (14 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 8714 byte(s)
Sun Oct 31 17:52:40 2010 UTC (14 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 8714 byte(s)
Ensure that enough memory gets allocated in FileName() function.
1 | amb | 2 | /*************************************** |
2 | amb | 518 | $Header: /home/amb/CVS/routino/src/files.c,v 1.25 2010-10-31 17:52:40 amb Exp $ |
3 | amb | 2 | |
4 | amb | 326 | Functions to handle files. |
5 | amb | 151 | |
6 | Part of the Routino routing software. | ||
7 | amb | 2 | ******************/ /****************** |
8 | amb | 326 | This file Copyright 2008-2010 Andrew M. Bishop |
9 | amb | 2 | |
10 | amb | 151 | This program is free software: you can redistribute it and/or modify |
11 | it under the terms of the GNU Affero General Public License as published by | ||
12 | the Free Software Foundation, either version 3 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU Affero General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU Affero General Public License | ||
21 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
22 | amb | 2 | ***************************************/ |
23 | |||
24 | amb | 507 | #include <assert.h> |
25 | amb | 2 | |
26 | #include <unistd.h> | ||
27 | #include <stdlib.h> | ||
28 | amb | 449 | #include <stdio.h> |
29 | amb | 162 | #include <string.h> |
30 | amb | 2 | #include <fcntl.h> |
31 | amb | 330 | #include <errno.h> |
32 | amb | 2 | #include <sys/stat.h> |
33 | #include <sys/mman.h> | ||
34 | amb | 251 | #include <sys/types.h> |
35 | amb | 2 | |
36 | amb | 449 | #include "files.h" |
37 | amb | 2 | |
38 | |||
39 | amb | 289 | /*+ A structure to contain the list of memory mapped files. +*/ |
40 | amb | 248 | struct mmapinfo |
41 | { | ||
42 | amb | 289 | const char *filename; /*+ The name of the file (the index of the list). +*/ |
43 | int fd; /*+ The file descriptor used when it was opened. +*/ | ||
44 | void *address; /*+ The address the file was mapped to. +*/ | ||
45 | size_t length; /*+ The length of the file. +*/ | ||
46 | amb | 248 | }; |
47 | |||
48 | amb | 289 | /*+ The list of memory mapped files. +*/ |
49 | static struct mmapinfo *mappedfiles; | ||
50 | amb | 248 | |
51 | amb | 289 | /*+ The number of mapped files. +*/ |
52 | static int nmappedfiles=0; | ||
53 | amb | 248 | |
54 | amb | 289 | |
55 | amb | 2 | /*++++++++++++++++++++++++++++++++++++++ |
56 | amb | 162 | Return a filename composed of the dirname, prefix and filename. |
57 | |||
58 | char *FileName Returns an allocated filename. | ||
59 | |||
60 | const char *dirname The directory name. | ||
61 | |||
62 | const char *prefix The file prefix. | ||
63 | |||
64 | const char *name The filename. | ||
65 | ++++++++++++++++++++++++++++++++++++++*/ | ||
66 | |||
67 | char *FileName(const char *dirname,const char *prefix, const char *name) | ||
68 | { | ||
69 | amb | 518 | char *filename=(char*)malloc((dirname?strlen(dirname):0)+1+(prefix?strlen(prefix):0)+1+strlen(name)+1); |
70 | amb | 162 | |
71 | sprintf(filename,"%s%s%s%s%s",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":"",name); | ||
72 | |||
73 | return(filename); | ||
74 | } | ||
75 | |||
76 | |||
77 | /*++++++++++++++++++++++++++++++++++++++ | ||
78 | amb | 250 | Open a file and map it into memory. |
79 | amb | 2 | |
80 | amb | 331 | void *MapFile Returns the address of the file or exits in case of an error. |
81 | amb | 2 | |
82 | const char *filename The name of the file to open. | ||
83 | ++++++++++++++++++++++++++++++++++++++*/ | ||
84 | |||
85 | amb | 250 | void *MapFile(const char *filename) |
86 | amb | 2 | { |
87 | int fd; | ||
88 | amb | 331 | off_t size; |
89 | amb | 2 | void *address; |
90 | |||
91 | amb | 331 | /* Open the file and get its size */ |
92 | amb | 2 | |
93 | amb | 331 | fd=ReOpenFile(filename); |
94 | amb | 2 | |
95 | amb | 331 | size=SizeFile(filename); |
96 | amb | 2 | |
97 | /* Map the file */ | ||
98 | |||
99 | amb | 331 | address=mmap(NULL,size,PROT_READ,MAP_SHARED,fd,0); |
100 | amb | 2 | |
101 | amb | 245 | if(address==MAP_FAILED) |
102 | amb | 2 | { |
103 | close(fd); | ||
104 | amb | 177 | |
105 | amb | 507 | assert(0); |
106 | |||
107 | amb | 511 | fprintf(stderr,"Cannot mmap file '%s' for reading [%s].\n",filename,strerror(errno)); |
108 | amb | 177 | exit(EXIT_FAILURE); |
109 | amb | 2 | } |
110 | |||
111 | amb | 248 | mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo)); |
112 | |||
113 | mappedfiles[nmappedfiles].filename=filename; | ||
114 | mappedfiles[nmappedfiles].fd=fd; | ||
115 | mappedfiles[nmappedfiles].address=address; | ||
116 | amb | 331 | mappedfiles[nmappedfiles].length=size; |
117 | amb | 248 | |
118 | nmappedfiles++; | ||
119 | |||
120 | amb | 2 | return(address); |
121 | } | ||
122 | |||
123 | |||
124 | /*++++++++++++++++++++++++++++++++++++++ | ||
125 | amb | 507 | Open a file and map it into memory. |
126 | |||
127 | amb | 513 | void *MapFileWriteable Returns the address of the file or exits in case of an error. |
128 | amb | 507 | |
129 | const char *filename The name of the file to open. | ||
130 | ++++++++++++++++++++++++++++++++++++++*/ | ||
131 | |||
132 | void *MapFileWriteable(const char *filename) | ||
133 | { | ||
134 | int fd; | ||
135 | off_t size; | ||
136 | void *address; | ||
137 | |||
138 | /* Open the file and get its size */ | ||
139 | |||
140 | amb | 511 | fd=ReOpenFileWriteable(filename); |
141 | amb | 507 | |
142 | size=SizeFile(filename); | ||
143 | |||
144 | /* Map the file */ | ||
145 | |||
146 | address=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); | ||
147 | |||
148 | if(address==MAP_FAILED) | ||
149 | { | ||
150 | close(fd); | ||
151 | |||
152 | amb | 511 | fprintf(stderr,"Cannot mmap file '%s' for reading and writing [%s].\n",filename,strerror(errno)); |
153 | amb | 507 | exit(EXIT_FAILURE); |
154 | } | ||
155 | |||
156 | mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo)); | ||
157 | |||
158 | mappedfiles[nmappedfiles].filename=filename; | ||
159 | mappedfiles[nmappedfiles].fd=fd; | ||
160 | mappedfiles[nmappedfiles].address=address; | ||
161 | mappedfiles[nmappedfiles].length=size; | ||
162 | |||
163 | nmappedfiles++; | ||
164 | |||
165 | return(address); | ||
166 | } | ||
167 | |||
168 | |||
169 | /*++++++++++++++++++++++++++++++++++++++ | ||
170 | amb | 331 | Unmap a file. |
171 | amb | 2 | |
172 | amb | 289 | void *UnmapFile Returns NULL (for similarity to the MapFile function). |
173 | amb | 255 | |
174 | amb | 248 | const char *filename The name of the file when it was opened. |
175 | ++++++++++++++++++++++++++++++++++++++*/ | ||
176 | |||
177 | amb | 255 | void *UnmapFile(const char *filename) |
178 | amb | 248 | { |
179 | int i; | ||
180 | |||
181 | for(i=0;i<nmappedfiles;i++) | ||
182 | if(!strcmp(mappedfiles[i].filename,filename)) | ||
183 | break; | ||
184 | |||
185 | if(i==nmappedfiles) | ||
186 | { | ||
187 | amb | 330 | fprintf(stderr,"The file '%s' was not mapped using MapFile().\n",filename); |
188 | amb | 248 | exit(EXIT_FAILURE); |
189 | } | ||
190 | |||
191 | /* Close the file */ | ||
192 | |||
193 | close(mappedfiles[i].fd); | ||
194 | |||
195 | /* Unmap the file */ | ||
196 | |||
197 | munmap(mappedfiles[i].address,mappedfiles[i].length); | ||
198 | |||
199 | /* Shuffle the list of files */ | ||
200 | |||
201 | nmappedfiles--; | ||
202 | |||
203 | if(nmappedfiles>i) | ||
204 | memmove(&mappedfiles[i],&mappedfiles[i+1],(nmappedfiles-i)*sizeof(struct mmapinfo)); | ||
205 | amb | 255 | |
206 | return(NULL); | ||
207 | amb | 248 | } |
208 | |||
209 | |||
210 | /*++++++++++++++++++++++++++++++++++++++ | ||
211 | Open a new file on disk for writing to. | ||
212 | |||
213 | amb | 513 | int OpenFileNew Returns the file descriptor if OK or exits in case of an error. |
214 | amb | 248 | |
215 | amb | 97 | const char *filename The name of the file to create. |
216 | amb | 2 | ++++++++++++++++++++++++++++++++++++++*/ |
217 | |||
218 | amb | 502 | int OpenFileNew(const char *filename) |
219 | amb | 2 | { |
220 | amb | 97 | int fd; |
221 | amb | 2 | |
222 | amb | 97 | /* Open the file */ |
223 | amb | 2 | |
224 | amb | 448 | fd=open(filename,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); |
225 | amb | 2 | |
226 | amb | 97 | if(fd<0) |
227 | amb | 177 | { |
228 | amb | 330 | fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",filename,strerror(errno)); |
229 | amb | 177 | exit(EXIT_FAILURE); |
230 | } | ||
231 | amb | 2 | |
232 | amb | 97 | return(fd); |
233 | amb | 2 | } |
234 | |||
235 | |||
236 | /*++++++++++++++++++++++++++++++++++++++ | ||
237 | amb | 502 | Open a new file on disk for reading from and appending. |
238 | amb | 326 | |
239 | amb | 502 | int OpenFileAppend Returns the file descriptor if OK or exits in case of an error. |
240 | amb | 326 | |
241 | const char *filename The name of the file to create. | ||
242 | ++++++++++++++++++++++++++++++++++++++*/ | ||
243 | |||
244 | amb | 502 | int OpenFileAppend(const char *filename) |
245 | amb | 326 | { |
246 | int fd; | ||
247 | |||
248 | /* Open the file */ | ||
249 | |||
250 | fd=open(filename,O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); | ||
251 | |||
252 | if(fd<0) | ||
253 | { | ||
254 | amb | 330 | fprintf(stderr,"Cannot open file '%s' for appending [%s].\n",filename,strerror(errno)); |
255 | amb | 326 | exit(EXIT_FAILURE); |
256 | } | ||
257 | |||
258 | return(fd); | ||
259 | } | ||
260 | |||
261 | |||
262 | /*++++++++++++++++++++++++++++++++++++++ | ||
263 | amb | 511 | Open an existing file on disk for reading. |
264 | amb | 251 | |
265 | amb | 331 | int ReOpenFile Returns the file descriptor if OK or exits in case of an error. |
266 | amb | 251 | |
267 | const char *filename The name of the file to open. | ||
268 | ++++++++++++++++++++++++++++++++++++++*/ | ||
269 | |||
270 | int ReOpenFile(const char *filename) | ||
271 | { | ||
272 | int fd; | ||
273 | |||
274 | /* Open the file */ | ||
275 | |||
276 | amb | 511 | fd=open(filename,O_RDONLY); |
277 | amb | 251 | |
278 | if(fd<0) | ||
279 | { | ||
280 | amb | 330 | fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno)); |
281 | amb | 251 | exit(EXIT_FAILURE); |
282 | } | ||
283 | |||
284 | return(fd); | ||
285 | } | ||
286 | |||
287 | |||
288 | /*++++++++++++++++++++++++++++++++++++++ | ||
289 | amb | 511 | Open an existing file on disk for reading from or writing to. |
290 | |||
291 | int ReOpenFileWriteable Returns the file descriptor if OK or exits in case of an error. | ||
292 | |||
293 | const char *filename The name of the file to open. | ||
294 | ++++++++++++++++++++++++++++++++++++++*/ | ||
295 | |||
296 | int ReOpenFileWriteable(const char *filename) | ||
297 | { | ||
298 | int fd; | ||
299 | |||
300 | /* Open the file */ | ||
301 | |||
302 | fd=open(filename,O_RDWR); | ||
303 | |||
304 | if(fd<0) | ||
305 | { | ||
306 | fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno)); | ||
307 | exit(EXIT_FAILURE); | ||
308 | } | ||
309 | |||
310 | return(fd); | ||
311 | } | ||
312 | |||
313 | |||
314 | /*++++++++++++++++++++++++++++++++++++++ | ||
315 | amb | 331 | Get the size of a file. |
316 | |||
317 | off_t SizeFile Returns the file size. | ||
318 | |||
319 | const char *filename The name of the file to check. | ||
320 | ++++++++++++++++++++++++++++++++++++++*/ | ||
321 | |||
322 | off_t SizeFile(const char *filename) | ||
323 | { | ||
324 | struct stat buf; | ||
325 | |||
326 | if(stat(filename,&buf)) | ||
327 | { | ||
328 | fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno)); | ||
329 | exit(EXIT_FAILURE); | ||
330 | } | ||
331 | |||
332 | return(buf.st_size); | ||
333 | } | ||
334 | |||
335 | |||
336 | /*++++++++++++++++++++++++++++++++++++++ | ||
337 | amb | 341 | Check if a file exists. |
338 | |||
339 | int ExistsFile Returns 1 if the file exists and 0 if not. | ||
340 | |||
341 | const char *filename The name of the file to check. | ||
342 | ++++++++++++++++++++++++++++++++++++++*/ | ||
343 | |||
344 | int ExistsFile(const char *filename) | ||
345 | { | ||
346 | struct stat buf; | ||
347 | |||
348 | if(stat(filename,&buf)) | ||
349 | return(0); | ||
350 | else | ||
351 | return(1); | ||
352 | } | ||
353 | |||
354 | |||
355 | /*++++++++++++++++++++++++++++++++++++++ | ||
356 | amb | 97 | Close a file on disk. |
357 | amb | 87 | |
358 | amb | 97 | int fd The file descriptor to close. |
359 | amb | 87 | ++++++++++++++++++++++++++++++++++++++*/ |
360 | |||
361 | amb | 97 | void CloseFile(int fd) |
362 | amb | 87 | { |
363 | amb | 97 | close(fd); |
364 | amb | 87 | } |
365 | amb | 251 | |
366 | |||
367 | /*++++++++++++++++++++++++++++++++++++++ | ||
368 | Delete a file from disk. | ||
369 | |||
370 | int DeleteFile Returns 0 if OK or something else in case of an error. | ||
371 | |||
372 | char *filename The name of the file to delete. | ||
373 | ++++++++++++++++++++++++++++++++++++++*/ | ||
374 | |||
375 | int DeleteFile(char *filename) | ||
376 | { | ||
377 | unlink(filename); | ||
378 | |||
379 | return(0); | ||
380 | } |
Properties
Name | Value |
---|---|
cvs:description | File handling functions. |