1 /***************************************
2 $Header: /home/amb/routino/src/RCS/files.c,v 1.25 2010/10/31 17:52:40 amb Exp $
4 Functions to handle files.
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008-2010 Andrew M. Bishop
10 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.
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.
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 ***************************************/
34 #include <sys/types.h>
39 /*+ A structure to contain the list of memory mapped files. +*/
42 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. +*/
48 /*+ The list of memory mapped files. +*/
49 static struct mmapinfo *mappedfiles;
51 /*+ The number of mapped files. +*/
52 static int nmappedfiles=0;
55 /*++++++++++++++++++++++++++++++++++++++
56 Return a filename composed of the dirname, prefix and filename.
58 char *FileName Returns an allocated filename.
60 const char *dirname The directory name.
62 const char *prefix The file prefix.
64 const char *name The filename.
65 ++++++++++++++++++++++++++++++++++++++*/
67 char *FileName(const char *dirname,const char *prefix, const char *name)
69 char *filename=(char*)malloc((dirname?strlen(dirname):0)+1+(prefix?strlen(prefix):0)+1+strlen(name)+1);
71 sprintf(filename,"%s%s%s%s%s",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":"",name);
77 /*++++++++++++++++++++++++++++++++++++++
78 Open a file and map it into memory.
80 void *MapFile Returns the address of the file or exits in case of an error.
82 const char *filename The name of the file to open.
83 ++++++++++++++++++++++++++++++++++++++*/
85 void *MapFile(const char *filename)
91 /* Open the file and get its size */
93 fd=ReOpenFile(filename);
95 size=SizeFile(filename);
99 address=mmap(NULL,size,PROT_READ,MAP_SHARED,fd,0);
101 if(address==MAP_FAILED)
107 fprintf(stderr,"Cannot mmap file '%s' for reading [%s].\n",filename,strerror(errno));
111 mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo));
113 mappedfiles[nmappedfiles].filename=filename;
114 mappedfiles[nmappedfiles].fd=fd;
115 mappedfiles[nmappedfiles].address=address;
116 mappedfiles[nmappedfiles].length=size;
124 /*++++++++++++++++++++++++++++++++++++++
125 Open a file and map it into memory.
127 void *MapFileWriteable Returns the address of the file or exits in case of an error.
129 const char *filename The name of the file to open.
130 ++++++++++++++++++++++++++++++++++++++*/
132 void *MapFileWriteable(const char *filename)
138 /* Open the file and get its size */
140 fd=ReOpenFileWriteable(filename);
142 size=SizeFile(filename);
146 address=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
148 if(address==MAP_FAILED)
152 fprintf(stderr,"Cannot mmap file '%s' for reading and writing [%s].\n",filename,strerror(errno));
156 mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo));
158 mappedfiles[nmappedfiles].filename=filename;
159 mappedfiles[nmappedfiles].fd=fd;
160 mappedfiles[nmappedfiles].address=address;
161 mappedfiles[nmappedfiles].length=size;
169 /*++++++++++++++++++++++++++++++++++++++
172 void *UnmapFile Returns NULL (for similarity to the MapFile function).
174 const char *filename The name of the file when it was opened.
175 ++++++++++++++++++++++++++++++++++++++*/
177 void *UnmapFile(const char *filename)
181 for(i=0;i<nmappedfiles;i++)
182 if(!strcmp(mappedfiles[i].filename,filename))
187 fprintf(stderr,"The file '%s' was not mapped using MapFile().\n",filename);
193 close(mappedfiles[i].fd);
197 munmap(mappedfiles[i].address,mappedfiles[i].length);
199 /* Shuffle the list of files */
204 memmove(&mappedfiles[i],&mappedfiles[i+1],(nmappedfiles-i)*sizeof(struct mmapinfo));
210 /*++++++++++++++++++++++++++++++++++++++
211 Open a new file on disk for writing to.
213 int OpenFileNew Returns the file descriptor if OK or exits in case of an error.
215 const char *filename The name of the file to create.
216 ++++++++++++++++++++++++++++++++++++++*/
218 int OpenFileNew(const char *filename)
224 fd=open(filename,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
228 fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",filename,strerror(errno));
236 /*++++++++++++++++++++++++++++++++++++++
237 Open a new file on disk for reading from and appending.
239 int OpenFileAppend Returns the file descriptor if OK or exits in case of an error.
241 const char *filename The name of the file to create.
242 ++++++++++++++++++++++++++++++++++++++*/
244 int OpenFileAppend(const char *filename)
250 fd=open(filename,O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
254 fprintf(stderr,"Cannot open file '%s' for appending [%s].\n",filename,strerror(errno));
262 /*++++++++++++++++++++++++++++++++++++++
263 Open an existing file on disk for reading.
265 int ReOpenFile Returns the file descriptor if OK or exits in case of an error.
267 const char *filename The name of the file to open.
268 ++++++++++++++++++++++++++++++++++++++*/
270 int ReOpenFile(const char *filename)
276 fd=open(filename,O_RDONLY);
280 fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
288 /*++++++++++++++++++++++++++++++++++++++
289 Open an existing file on disk for reading from or writing to.
291 int ReOpenFileWriteable Returns the file descriptor if OK or exits in case of an error.
293 const char *filename The name of the file to open.
294 ++++++++++++++++++++++++++++++++++++++*/
296 int ReOpenFileWriteable(const char *filename)
302 fd=open(filename,O_RDWR);
306 fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno));
314 /*++++++++++++++++++++++++++++++++++++++
315 Get the size of a file.
317 off_t SizeFile Returns the file size.
319 const char *filename The name of the file to check.
320 ++++++++++++++++++++++++++++++++++++++*/
322 off_t SizeFile(const char *filename)
326 if(stat(filename,&buf))
328 fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno));
336 /*++++++++++++++++++++++++++++++++++++++
337 Check if a file exists.
339 int ExistsFile Returns 1 if the file exists and 0 if not.
341 const char *filename The name of the file to check.
342 ++++++++++++++++++++++++++++++++++++++*/
344 int ExistsFile(const char *filename)
348 if(stat(filename,&buf))
355 /*++++++++++++++++++++++++++++++++++++++
356 Close a file on disk.
358 int fd The file descriptor to close.
359 ++++++++++++++++++++++++++++++++++++++*/
361 void CloseFile(int fd)
367 /*++++++++++++++++++++++++++++++++++++++
368 Delete a file from disk.
370 int DeleteFile Returns 0 if OK or something else in case of an error.
372 char *filename The name of the file to delete.
373 ++++++++++++++++++++++++++++++++++++++*/
375 int DeleteFile(char *filename)