1 /***************************************
2 $Header: /home/amb/routino/src/RCS/files.c,v 1.18 2010/03/29 18:20:06 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 ***************************************/
32 #include <sys/types.h>
34 #include "functions.h"
37 /*+ A structure to contain the list of memory mapped files. +*/
40 const char *filename; /*+ The name of the file (the index of the list). +*/
41 int fd; /*+ The file descriptor used when it was opened. +*/
42 void *address; /*+ The address the file was mapped to. +*/
43 size_t length; /*+ The length of the file. +*/
46 /*+ The list of memory mapped files. +*/
47 static struct mmapinfo *mappedfiles;
49 /*+ The number of mapped files. +*/
50 static int nmappedfiles=0;
53 /*++++++++++++++++++++++++++++++++++++++
54 Return a filename composed of the dirname, prefix and filename.
56 char *FileName Returns an allocated filename.
58 const char *dirname The directory name.
60 const char *prefix The file prefix.
62 const char *name The filename.
63 ++++++++++++++++++++++++++++++++++++++*/
65 char *FileName(const char *dirname,const char *prefix, const char *name)
67 char *filename=(char*)malloc((dirname?strlen(dirname):0)+1+(prefix?strlen(prefix):0)+1+strlen(name));
69 sprintf(filename,"%s%s%s%s%s",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":"",name);
75 /*++++++++++++++++++++++++++++++++++++++
76 Open a file and map it into memory.
78 void *MapFile Returns the address of the file or exits in case of an error.
80 const char *filename The name of the file to open.
81 ++++++++++++++++++++++++++++++++++++++*/
83 void *MapFile(const char *filename)
89 /* Open the file and get its size */
91 fd=ReOpenFile(filename);
93 size=SizeFile(filename);
97 address=mmap(NULL,size,PROT_READ,MAP_SHARED,fd,0);
99 if(address==MAP_FAILED)
103 fprintf(stderr,"Cannot mmap file '%s' [%s].\n",filename,strerror(errno));
107 mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo));
109 mappedfiles[nmappedfiles].filename=filename;
110 mappedfiles[nmappedfiles].fd=fd;
111 mappedfiles[nmappedfiles].address=address;
112 mappedfiles[nmappedfiles].length=size;
120 /*++++++++++++++++++++++++++++++++++++++
123 void *UnmapFile Returns NULL (for similarity to the MapFile function).
125 const char *filename The name of the file when it was opened.
126 ++++++++++++++++++++++++++++++++++++++*/
128 void *UnmapFile(const char *filename)
132 for(i=0;i<nmappedfiles;i++)
133 if(!strcmp(mappedfiles[i].filename,filename))
138 fprintf(stderr,"The file '%s' was not mapped using MapFile().\n",filename);
144 close(mappedfiles[i].fd);
148 munmap(mappedfiles[i].address,mappedfiles[i].length);
150 /* Shuffle the list of files */
155 memmove(&mappedfiles[i],&mappedfiles[i+1],(nmappedfiles-i)*sizeof(struct mmapinfo));
161 /*++++++++++++++++++++++++++++++++++++++
162 Open a new file on disk for writing to.
164 int OpenFile Returns the file descriptor if OK or exits in case of an error.
166 const char *filename The name of the file to create.
167 ++++++++++++++++++++++++++++++++++++++*/
169 int OpenFile(const char *filename)
175 fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
179 fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",filename,strerror(errno));
187 /*++++++++++++++++++++++++++++++++++++++
188 Open a new file on disk for reading and appending.
190 int AppendFile Returns the file descriptor if OK or exits in case of an error.
192 const char *filename The name of the file to create.
193 ++++++++++++++++++++++++++++++++++++++*/
195 int AppendFile(const char *filename)
201 fd=open(filename,O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
205 fprintf(stderr,"Cannot open file '%s' for appending [%s].\n",filename,strerror(errno));
213 /*++++++++++++++++++++++++++++++++++++++
214 Open an existing file on disk for reading from.
216 int ReOpenFile Returns the file descriptor if OK or exits in case of an error.
218 const char *filename The name of the file to open.
219 ++++++++++++++++++++++++++++++++++++++*/
221 int ReOpenFile(const char *filename)
227 fd=open(filename,O_RDONLY);
231 fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
239 /*++++++++++++++++++++++++++++++++++++++
240 Write data to a file on disk.
242 int WriteFile Returns 0 if OK or something else in case of an error.
244 int fd The file descriptor to write to.
246 const void *address The address of the data to be written from.
248 size_t length The length of data to write.
249 ++++++++++++++++++++++++++++++++++++++*/
251 int WriteFile(int fd,const void *address,size_t length)
255 if(write(fd,address,length)!=length)
262 /*++++++++++++++++++++++++++++++++++++++
263 Read data from a file on disk.
265 int ReadFile Returns 0 if OK or something else in case of an error.
267 int fd The file descriptor to read from.
269 void *address The address of the data to be read into.
271 size_t length The length of data to read.
272 ++++++++++++++++++++++++++++++++++++++*/
274 int ReadFile(int fd,void *address,size_t length)
278 if(read(fd,address,length)!=length)
285 /*++++++++++++++++++++++++++++++++++++++
286 Get the size of a file.
288 off_t SizeFile Returns the file size.
290 const char *filename The name of the file to check.
291 ++++++++++++++++++++++++++++++++++++++*/
293 off_t SizeFile(const char *filename)
297 if(stat(filename,&buf))
299 fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno));
307 /*++++++++++++++++++++++++++++++++++++++
308 Check if a file exists.
310 int ExistsFile Returns 1 if the file exists and 0 if not.
312 const char *filename The name of the file to check.
313 ++++++++++++++++++++++++++++++++++++++*/
315 int ExistsFile(const char *filename)
319 if(stat(filename,&buf))
326 /*++++++++++++++++++++++++++++++++++++++
327 Seek to a position in a file on disk.
329 int SeekFile Returns 0 if OK or something else in case of an error.
331 int fd The file descriptor to seek within.
333 off_t position The position to seek to.
334 ++++++++++++++++++++++++++++++++++++++*/
336 int SeekFile(int fd,off_t position)
340 if(lseek(fd,position,SEEK_SET)!=position)
347 /*++++++++++++++++++++++++++++++++++++++
348 Close a file on disk.
350 int fd The file descriptor to close.
351 ++++++++++++++++++++++++++++++++++++++*/
353 void CloseFile(int fd)
359 /*++++++++++++++++++++++++++++++++++++++
360 Delete a file from disk.
362 int DeleteFile Returns 0 if OK or something else in case of an error.
364 char *filename The name of the file to delete.
365 ++++++++++++++++++++++++++++++++++++++*/
367 int DeleteFile(char *filename)