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 1403 -
(hide annotations)
(download)
(as text)
Thu Jun 20 17:35:36 2013 UTC (11 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 14922 byte(s)
Thu Jun 20 17:35:36 2013 UTC (11 years, 8 months ago) by amb
File MIME type: text/x-csrc
File size: 14922 byte(s)
Fix the non-buffered close function assertion and re-factor the code for buffered reading (although not used yet).
1 | amb | 2 | /*************************************** |
2 | amb | 326 | Functions to handle files. |
3 | amb | 151 | |
4 | Part of the Routino routing software. | ||
5 | amb | 2 | ******************/ /****************** |
6 | amb | 1401 | This file Copyright 2008-2013 Andrew M. Bishop |
7 | amb | 2 | |
8 | amb | 151 | This program is free software: you can redistribute it and/or modify |
9 | it under the terms of the GNU Affero General Public License as published by | ||
10 | the Free Software Foundation, either version 3 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU Affero General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU Affero General Public License | ||
19 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | amb | 2 | ***************************************/ |
21 | |||
22 | amb | 680 | |
23 | amb | 2 | #include <unistd.h> |
24 | #include <stdlib.h> | ||
25 | amb | 449 | #include <stdio.h> |
26 | amb | 162 | #include <string.h> |
27 | amb | 2 | #include <fcntl.h> |
28 | amb | 330 | #include <errno.h> |
29 | amb | 2 | #include <sys/stat.h> |
30 | #include <sys/mman.h> | ||
31 | amb | 251 | #include <sys/types.h> |
32 | amb | 2 | |
33 | amb | 449 | #include "files.h" |
34 | amb | 2 | |
35 | |||
36 | amb | 289 | /*+ A structure to contain the list of memory mapped files. +*/ |
37 | amb | 248 | struct mmapinfo |
38 | { | ||
39 | amb | 289 | const char *filename; /*+ The name of the file (the index of the list). +*/ |
40 | int fd; /*+ The file descriptor used when it was opened. +*/ | ||
41 | void *address; /*+ The address the file was mapped to. +*/ | ||
42 | size_t length; /*+ The length of the file. +*/ | ||
43 | amb | 248 | }; |
44 | |||
45 | amb | 289 | /*+ The list of memory mapped files. +*/ |
46 | static struct mmapinfo *mappedfiles; | ||
47 | amb | 248 | |
48 | amb | 289 | /*+ The number of mapped files. +*/ |
49 | static int nmappedfiles=0; | ||
50 | amb | 248 | |
51 | amb | 289 | |
52 | amb | 1401 | #define BUFFLEN 1024 |
53 | |||
54 | /*+ A structure to contain the list of file buffers. +*/ | ||
55 | struct filebuffer | ||
56 | { | ||
57 | int fd; /*+ The file descriptor used when it was opened. +*/ | ||
58 | char buffer[BUFFLEN]; /*+ The data buffer. +*/ | ||
59 | size_t pointer; /*+ The read/write pointer for the file buffer. +*/ | ||
60 | size_t length; /*+ The read pointer for the file buffer. +*/ | ||
61 | int reading; /*+ A flag to indicate if the file is for reading. +*/ | ||
62 | }; | ||
63 | |||
64 | /*+ The list of file buffers. +*/ | ||
65 | static struct filebuffer **filebuffers=NULL; | ||
66 | |||
67 | /*+ The number of allocated file buffer pointers. +*/ | ||
68 | static int nfilebuffers=0; | ||
69 | |||
70 | |||
71 | static void CreateFileBuffer(int fd,int reading); | ||
72 | |||
73 | |||
74 | amb | 2 | /*++++++++++++++++++++++++++++++++++++++ |
75 | amb | 680 | Return a filename composed of the dirname, prefix and name. |
76 | amb | 162 | |
77 | amb | 680 | char *FileName Returns a pointer to memory allocated to the filename. |
78 | amb | 162 | |
79 | const char *dirname The directory name. | ||
80 | |||
81 | const char *prefix The file prefix. | ||
82 | |||
83 | amb | 680 | const char *name The main part of the name. |
84 | amb | 162 | ++++++++++++++++++++++++++++++++++++++*/ |
85 | |||
86 | char *FileName(const char *dirname,const char *prefix, const char *name) | ||
87 | { | ||
88 | amb | 518 | char *filename=(char*)malloc((dirname?strlen(dirname):0)+1+(prefix?strlen(prefix):0)+1+strlen(name)+1); |
89 | amb | 162 | |
90 | sprintf(filename,"%s%s%s%s%s",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":"",name); | ||
91 | |||
92 | return(filename); | ||
93 | } | ||
94 | |||
95 | |||
96 | /*++++++++++++++++++++++++++++++++++++++ | ||
97 | amb | 680 | Open a file read-only and map it into memory. |
98 | amb | 2 | |
99 | amb | 331 | void *MapFile Returns the address of the file or exits in case of an error. |
100 | amb | 2 | |
101 | const char *filename The name of the file to open. | ||
102 | ++++++++++++++++++++++++++++++++++++++*/ | ||
103 | |||
104 | amb | 250 | void *MapFile(const char *filename) |
105 | amb | 2 | { |
106 | int fd; | ||
107 | amb | 331 | off_t size; |
108 | amb | 2 | void *address; |
109 | |||
110 | amb | 331 | /* Open the file and get its size */ |
111 | amb | 2 | |
112 | amb | 331 | fd=ReOpenFile(filename); |
113 | amb | 2 | |
114 | amb | 331 | size=SizeFile(filename); |
115 | amb | 2 | |
116 | /* Map the file */ | ||
117 | |||
118 | amb | 331 | address=mmap(NULL,size,PROT_READ,MAP_SHARED,fd,0); |
119 | amb | 2 | |
120 | amb | 245 | if(address==MAP_FAILED) |
121 | amb | 2 | { |
122 | close(fd); | ||
123 | amb | 177 | |
124 | amb | 511 | fprintf(stderr,"Cannot mmap file '%s' for reading [%s].\n",filename,strerror(errno)); |
125 | amb | 177 | exit(EXIT_FAILURE); |
126 | amb | 2 | } |
127 | |||
128 | amb | 680 | /* Store the information about the mapped file */ |
129 | |||
130 | amb | 248 | mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo)); |
131 | |||
132 | mappedfiles[nmappedfiles].filename=filename; | ||
133 | mappedfiles[nmappedfiles].fd=fd; | ||
134 | mappedfiles[nmappedfiles].address=address; | ||
135 | amb | 331 | mappedfiles[nmappedfiles].length=size; |
136 | amb | 248 | |
137 | nmappedfiles++; | ||
138 | |||
139 | amb | 2 | return(address); |
140 | } | ||
141 | |||
142 | |||
143 | /*++++++++++++++++++++++++++++++++++++++ | ||
144 | amb | 680 | Open a file read-write and map it into memory. |
145 | amb | 507 | |
146 | amb | 513 | void *MapFileWriteable Returns the address of the file or exits in case of an error. |
147 | amb | 507 | |
148 | const char *filename The name of the file to open. | ||
149 | ++++++++++++++++++++++++++++++++++++++*/ | ||
150 | |||
151 | void *MapFileWriteable(const char *filename) | ||
152 | { | ||
153 | int fd; | ||
154 | off_t size; | ||
155 | void *address; | ||
156 | |||
157 | /* Open the file and get its size */ | ||
158 | |||
159 | amb | 511 | fd=ReOpenFileWriteable(filename); |
160 | amb | 507 | |
161 | size=SizeFile(filename); | ||
162 | |||
163 | /* Map the file */ | ||
164 | |||
165 | address=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); | ||
166 | |||
167 | if(address==MAP_FAILED) | ||
168 | { | ||
169 | close(fd); | ||
170 | |||
171 | amb | 511 | fprintf(stderr,"Cannot mmap file '%s' for reading and writing [%s].\n",filename,strerror(errno)); |
172 | amb | 507 | exit(EXIT_FAILURE); |
173 | } | ||
174 | |||
175 | amb | 680 | /* Store the information about the mapped file */ |
176 | |||
177 | amb | 507 | mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo)); |
178 | |||
179 | mappedfiles[nmappedfiles].filename=filename; | ||
180 | mappedfiles[nmappedfiles].fd=fd; | ||
181 | mappedfiles[nmappedfiles].address=address; | ||
182 | mappedfiles[nmappedfiles].length=size; | ||
183 | |||
184 | nmappedfiles++; | ||
185 | |||
186 | return(address); | ||
187 | } | ||
188 | |||
189 | |||
190 | /*++++++++++++++++++++++++++++++++++++++ | ||
191 | amb | 680 | Unmap a file and close it. |
192 | amb | 2 | |
193 | amb | 289 | void *UnmapFile Returns NULL (for similarity to the MapFile function). |
194 | amb | 255 | |
195 | amb | 1122 | const void *address The address of the mapped file in memory. |
196 | amb | 248 | ++++++++++++++++++++++++++++++++++++++*/ |
197 | |||
198 | amb | 1122 | void *UnmapFile(const void *address) |
199 | amb | 248 | { |
200 | int i; | ||
201 | |||
202 | for(i=0;i<nmappedfiles;i++) | ||
203 | amb | 1122 | if(mappedfiles[i].address==address) |
204 | amb | 248 | break; |
205 | |||
206 | if(i==nmappedfiles) | ||
207 | { | ||
208 | amb | 1122 | fprintf(stderr,"The data at address %p was not mapped using MapFile().\n",address); |
209 | amb | 248 | exit(EXIT_FAILURE); |
210 | } | ||
211 | |||
212 | /* Close the file */ | ||
213 | |||
214 | close(mappedfiles[i].fd); | ||
215 | |||
216 | /* Unmap the file */ | ||
217 | |||
218 | munmap(mappedfiles[i].address,mappedfiles[i].length); | ||
219 | |||
220 | /* Shuffle the list of files */ | ||
221 | |||
222 | nmappedfiles--; | ||
223 | |||
224 | if(nmappedfiles>i) | ||
225 | memmove(&mappedfiles[i],&mappedfiles[i+1],(nmappedfiles-i)*sizeof(struct mmapinfo)); | ||
226 | amb | 255 | |
227 | return(NULL); | ||
228 | amb | 248 | } |
229 | |||
230 | |||
231 | /*++++++++++++++++++++++++++++++++++++++ | ||
232 | amb | 680 | Open a new file on disk for writing. |
233 | amb | 248 | |
234 | amb | 513 | int OpenFileNew Returns the file descriptor if OK or exits in case of an error. |
235 | amb | 248 | |
236 | amb | 97 | const char *filename The name of the file to create. |
237 | amb | 2 | ++++++++++++++++++++++++++++++++++++++*/ |
238 | |||
239 | amb | 502 | int OpenFileNew(const char *filename) |
240 | amb | 2 | { |
241 | amb | 97 | int fd; |
242 | amb | 2 | |
243 | amb | 97 | /* Open the file */ |
244 | amb | 2 | |
245 | amb | 448 | fd=open(filename,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); |
246 | amb | 2 | |
247 | amb | 97 | if(fd<0) |
248 | amb | 177 | { |
249 | amb | 330 | fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",filename,strerror(errno)); |
250 | amb | 177 | exit(EXIT_FAILURE); |
251 | } | ||
252 | amb | 2 | |
253 | amb | 97 | return(fd); |
254 | amb | 2 | } |
255 | |||
256 | |||
257 | /*++++++++++++++++++++++++++++++++++++++ | ||
258 | amb | 1401 | Open a new file on disk for writing (with buffering). |
259 | |||
260 | int OpenFileBufferedNew Returns the file descriptor if OK or exits in case of an error. | ||
261 | |||
262 | const char *filename The name of the file to create. | ||
263 | ++++++++++++++++++++++++++++++++++++++*/ | ||
264 | |||
265 | int OpenFileBufferedNew(const char *filename) | ||
266 | { | ||
267 | int fd; | ||
268 | |||
269 | fd=OpenFileNew(filename); | ||
270 | |||
271 | CreateFileBuffer(fd,0); | ||
272 | |||
273 | return(fd); | ||
274 | } | ||
275 | |||
276 | |||
277 | /*++++++++++++++++++++++++++++++++++++++ | ||
278 | amb | 680 | Open a new or existing file on disk for reading and appending. |
279 | amb | 326 | |
280 | amb | 502 | int OpenFileAppend Returns the file descriptor if OK or exits in case of an error. |
281 | amb | 326 | |
282 | amb | 680 | const char *filename The name of the file to create or open. |
283 | amb | 326 | ++++++++++++++++++++++++++++++++++++++*/ |
284 | |||
285 | amb | 502 | int OpenFileAppend(const char *filename) |
286 | amb | 326 | { |
287 | int fd; | ||
288 | |||
289 | /* Open the file */ | ||
290 | |||
291 | fd=open(filename,O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); | ||
292 | |||
293 | if(fd<0) | ||
294 | { | ||
295 | amb | 330 | fprintf(stderr,"Cannot open file '%s' for appending [%s].\n",filename,strerror(errno)); |
296 | amb | 326 | exit(EXIT_FAILURE); |
297 | } | ||
298 | |||
299 | return(fd); | ||
300 | } | ||
301 | |||
302 | |||
303 | /*++++++++++++++++++++++++++++++++++++++ | ||
304 | amb | 1401 | Open a new or existing file on disk for reading and appending (with buffering). |
305 | |||
306 | int OpenFileBufferedAppend Returns the file descriptor if OK or exits in case of an error. | ||
307 | |||
308 | const char *filename The name of the file to create or open. | ||
309 | ++++++++++++++++++++++++++++++++++++++*/ | ||
310 | |||
311 | int OpenFileBufferedAppend(const char *filename) | ||
312 | { | ||
313 | int fd; | ||
314 | |||
315 | fd=OpenFileAppend(filename); | ||
316 | |||
317 | CreateFileBuffer(fd,0); | ||
318 | |||
319 | return(fd); | ||
320 | } | ||
321 | |||
322 | |||
323 | /*++++++++++++++++++++++++++++++++++++++ | ||
324 | amb | 511 | Open an existing file on disk for reading. |
325 | amb | 251 | |
326 | amb | 331 | int ReOpenFile Returns the file descriptor if OK or exits in case of an error. |
327 | amb | 251 | |
328 | const char *filename The name of the file to open. | ||
329 | ++++++++++++++++++++++++++++++++++++++*/ | ||
330 | |||
331 | int ReOpenFile(const char *filename) | ||
332 | { | ||
333 | int fd; | ||
334 | |||
335 | /* Open the file */ | ||
336 | |||
337 | amb | 511 | fd=open(filename,O_RDONLY); |
338 | amb | 251 | |
339 | if(fd<0) | ||
340 | { | ||
341 | amb | 330 | fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno)); |
342 | amb | 251 | exit(EXIT_FAILURE); |
343 | } | ||
344 | |||
345 | return(fd); | ||
346 | } | ||
347 | |||
348 | |||
349 | /*++++++++++++++++++++++++++++++++++++++ | ||
350 | amb | 680 | Open an existing file on disk for reading or writing. |
351 | amb | 511 | |
352 | int ReOpenFileWriteable Returns the file descriptor if OK or exits in case of an error. | ||
353 | |||
354 | const char *filename The name of the file to open. | ||
355 | ++++++++++++++++++++++++++++++++++++++*/ | ||
356 | |||
357 | int ReOpenFileWriteable(const char *filename) | ||
358 | { | ||
359 | int fd; | ||
360 | |||
361 | /* Open the file */ | ||
362 | |||
363 | fd=open(filename,O_RDWR); | ||
364 | |||
365 | if(fd<0) | ||
366 | { | ||
367 | fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno)); | ||
368 | exit(EXIT_FAILURE); | ||
369 | } | ||
370 | |||
371 | return(fd); | ||
372 | } | ||
373 | |||
374 | |||
375 | /*++++++++++++++++++++++++++++++++++++++ | ||
376 | amb | 1401 | Write data to a file descriptor (via a buffer). |
377 | |||
378 | int WriteFileBuffered Returns 0 if OK or something else in case of an error. | ||
379 | |||
380 | int fd The file descriptor to write to. | ||
381 | |||
382 | const void *address The address of the data to be written. | ||
383 | |||
384 | size_t length The length of data to write. | ||
385 | ++++++++++++++++++++++++++++++++++++++*/ | ||
386 | |||
387 | int WriteFileBuffered(int fd,const void *address,size_t length) | ||
388 | { | ||
389 | logassert(fd!=-1,"File descriptor is in error - report a bug"); | ||
390 | |||
391 | logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug"); | ||
392 | |||
393 | logassert(!filebuffers[fd]->reading,"File descriptor was not opened for writing - report a bug"); | ||
394 | |||
395 | /* Write the data */ | ||
396 | |||
397 | if((filebuffers[fd]->pointer+length)>BUFFLEN) | ||
398 | { | ||
399 | if(write(fd,filebuffers[fd]->buffer,filebuffers[fd]->pointer)!=(ssize_t)filebuffers[fd]->pointer) | ||
400 | return(-1); | ||
401 | |||
402 | filebuffers[fd]->pointer=0; | ||
403 | } | ||
404 | |||
405 | amb | 1403 | if(length>=BUFFLEN) |
406 | amb | 1401 | { |
407 | amb | 1403 | if(write(fd,address,length)!=(ssize_t)length) |
408 | amb | 1401 | return(-1); |
409 | |||
410 | amb | 1403 | return(0); |
411 | amb | 1401 | } |
412 | |||
413 | amb | 1403 | memcpy(filebuffers[fd]->buffer+filebuffers[fd]->pointer,address,length); |
414 | amb | 1401 | |
415 | amb | 1403 | filebuffers[fd]->pointer+=length; |
416 | amb | 1401 | |
417 | return(0); | ||
418 | } | ||
419 | |||
420 | |||
421 | /*++++++++++++++++++++++++++++++++++++++ | ||
422 | Read data from a file descriptor (via a buffer). | ||
423 | |||
424 | int ReadFileBuffered Returns 0 if OK or something else in case of an error. | ||
425 | |||
426 | int fd The file descriptor to read from. | ||
427 | |||
428 | void *address The address the data is to be read into. | ||
429 | |||
430 | size_t length The length of data to read. | ||
431 | ++++++++++++++++++++++++++++++++++++++*/ | ||
432 | |||
433 | int ReadFileBuffered(int fd,void *address,size_t length) | ||
434 | { | ||
435 | logassert(fd!=-1,"File descriptor is in error - report a bug"); | ||
436 | |||
437 | logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug"); | ||
438 | |||
439 | logassert(filebuffers[fd]->reading,"File descriptor was not opened for reading - report a bug"); | ||
440 | |||
441 | /* Read the data */ | ||
442 | |||
443 | amb | 1403 | if((filebuffers[fd]->pointer+length)>filebuffers[fd]->length) |
444 | amb | 1401 | if(filebuffers[fd]->pointer<filebuffers[fd]->length) |
445 | { | ||
446 | memcpy(address,filebuffers[fd]->buffer+filebuffers[fd]->pointer,filebuffers[fd]->length-filebuffers[fd]->pointer); | ||
447 | |||
448 | address+=filebuffers[fd]->length-filebuffers[fd]->pointer; | ||
449 | length-=filebuffers[fd]->length-filebuffers[fd]->pointer; | ||
450 | |||
451 | filebuffers[fd]->pointer=0; | ||
452 | filebuffers[fd]->length=0; | ||
453 | } | ||
454 | |||
455 | amb | 1403 | if(length>=BUFFLEN) |
456 | { | ||
457 | if(read(fd,address,length)!=(ssize_t)length) | ||
458 | return(-1); | ||
459 | amb | 1401 | |
460 | amb | 1403 | return(0); |
461 | amb | 1401 | } |
462 | |||
463 | amb | 1403 | if(filebuffers[fd]->pointer==filebuffers[fd]->length) |
464 | amb | 1401 | { |
465 | amb | 1403 | filebuffers[fd]->length=read(fd,filebuffers[fd]->buffer,BUFFLEN); |
466 | amb | 1401 | filebuffers[fd]->pointer=0; |
467 | } | ||
468 | |||
469 | if(filebuffers[fd]->length==0) | ||
470 | return(-1); | ||
471 | |||
472 | memcpy(address,filebuffers[fd]->buffer+filebuffers[fd]->pointer,length); | ||
473 | |||
474 | filebuffers[fd]->pointer+=length; | ||
475 | |||
476 | return(0); | ||
477 | } | ||
478 | |||
479 | |||
480 | /*++++++++++++++++++++++++++++++++++++++ | ||
481 | amb | 331 | Get the size of a file. |
482 | |||
483 | amb | 680 | off_t SizeFile Returns the file size if OK or exits in case of an error. |
484 | amb | 331 | |
485 | const char *filename The name of the file to check. | ||
486 | ++++++++++++++++++++++++++++++++++++++*/ | ||
487 | |||
488 | off_t SizeFile(const char *filename) | ||
489 | { | ||
490 | struct stat buf; | ||
491 | |||
492 | if(stat(filename,&buf)) | ||
493 | { | ||
494 | fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno)); | ||
495 | exit(EXIT_FAILURE); | ||
496 | } | ||
497 | |||
498 | return(buf.st_size); | ||
499 | } | ||
500 | |||
501 | |||
502 | /*++++++++++++++++++++++++++++++++++++++ | ||
503 | amb | 341 | Check if a file exists. |
504 | |||
505 | int ExistsFile Returns 1 if the file exists and 0 if not. | ||
506 | |||
507 | const char *filename The name of the file to check. | ||
508 | ++++++++++++++++++++++++++++++++++++++*/ | ||
509 | |||
510 | int ExistsFile(const char *filename) | ||
511 | { | ||
512 | struct stat buf; | ||
513 | |||
514 | if(stat(filename,&buf)) | ||
515 | return(0); | ||
516 | else | ||
517 | return(1); | ||
518 | } | ||
519 | |||
520 | |||
521 | /*++++++++++++++++++++++++++++++++++++++ | ||
522 | amb | 97 | Close a file on disk. |
523 | amb | 87 | |
524 | amb | 680 | int CloseFile returns -1 (for similarity to the *OpenFile* functions). |
525 | amb | 612 | |
526 | amb | 97 | int fd The file descriptor to close. |
527 | amb | 87 | ++++++++++++++++++++++++++++++++++++++*/ |
528 | |||
529 | amb | 612 | int CloseFile(int fd) |
530 | amb | 87 | { |
531 | amb | 1403 | logassert(fd>=nfilebuffers || !filebuffers[fd],"File descriptor has a buffer - report a bug"); |
532 | amb | 1401 | |
533 | amb | 97 | close(fd); |
534 | amb | 612 | |
535 | return(-1); | ||
536 | amb | 87 | } |
537 | amb | 251 | |
538 | |||
539 | /*++++++++++++++++++++++++++++++++++++++ | ||
540 | amb | 1401 | Close a file on disk (and flush the buffer). |
541 | |||
542 | amb | 1403 | int CloseFileBuffered returns -1 (for similarity to the *OpenFileBuffered* functions). |
543 | amb | 1401 | |
544 | int fd The file descriptor to close. | ||
545 | ++++++++++++++++++++++++++++++++++++++*/ | ||
546 | |||
547 | int CloseFileBuffered(int fd) | ||
548 | { | ||
549 | logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug"); | ||
550 | |||
551 | if(!filebuffers[fd]->reading) | ||
552 | write(fd,filebuffers[fd]->buffer,filebuffers[fd]->pointer); | ||
553 | |||
554 | close(fd); | ||
555 | |||
556 | free(filebuffers[fd]); | ||
557 | |||
558 | filebuffers[fd]=NULL; | ||
559 | |||
560 | return(-1); | ||
561 | } | ||
562 | |||
563 | |||
564 | /*++++++++++++++++++++++++++++++++++++++ | ||
565 | amb | 251 | Delete a file from disk. |
566 | |||
567 | amb | 680 | int DeleteFile Returns 0 if OK. |
568 | amb | 251 | |
569 | amb | 1119 | const char *filename The name of the file to delete. |
570 | amb | 251 | ++++++++++++++++++++++++++++++++++++++*/ |
571 | |||
572 | amb | 1119 | int DeleteFile(const char *filename) |
573 | amb | 251 | { |
574 | unlink(filename); | ||
575 | |||
576 | return(0); | ||
577 | } | ||
578 | amb | 1119 | |
579 | |||
580 | /*++++++++++++++++++++++++++++++++++++++ | ||
581 | Rename a file on disk. | ||
582 | |||
583 | amb | 1162 | int RenameFile Returns 0 if OK. |
584 | amb | 1119 | |
585 | const char *oldfilename The old name of the file before renaming. | ||
586 | |||
587 | const char *newfilename The new name of the file after renaming. | ||
588 | ++++++++++++++++++++++++++++++++++++++*/ | ||
589 | |||
590 | int RenameFile(const char *oldfilename,const char *newfilename) | ||
591 | { | ||
592 | rename(oldfilename,newfilename); | ||
593 | |||
594 | return(0); | ||
595 | } | ||
596 | amb | 1401 | |
597 | |||
598 | /*++++++++++++++++++++++++++++++++++++++ | ||
599 | Create a file buffer. | ||
600 | |||
601 | int fd The file descriptor. | ||
602 | |||
603 | int reading A flag set if the file descriptor is to be used for reading. | ||
604 | ++++++++++++++++++++++++++++++++++++++*/ | ||
605 | |||
606 | static void CreateFileBuffer(int fd,int reading) | ||
607 | { | ||
608 | if(nfilebuffers<=fd) | ||
609 | { | ||
610 | int i; | ||
611 | |||
612 | filebuffers=(struct filebuffer**)realloc((void*)filebuffers,(fd+1)*sizeof(struct filebuffer*)); | ||
613 | |||
614 | for(i=nfilebuffers;i<=fd;i++) | ||
615 | filebuffers[i]=NULL; | ||
616 | |||
617 | nfilebuffers=fd+1; | ||
618 | } | ||
619 | |||
620 | filebuffers[fd]=(struct filebuffer*)calloc(sizeof(struct filebuffer),1); | ||
621 | |||
622 | filebuffers[fd]->reading=reading; | ||
623 | } |
Properties
Name | Value |
---|---|
cvs:description | File handling functions. |