Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /trunk/src/files.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1699 - (show annotations) (download) (as text)
Tue Jun 9 18:05:06 2015 UTC (9 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 23367 byte(s)
Merge the MS-Windows branch back into the trunk.
Code changes and documentation for Cygwin and MinGW compilers.

1 /***************************************
2 Functions to handle files.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-2015 Andrew M. Bishop
7
8 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 ***************************************/
21
22
23 #if defined(_MSC_VER)
24 #include <io.h>
25 typedef unsigned __int64 ssize_t;
26 #define read(fd,address,length) _read(fd,address,(unsigned int)(length))
27 #define write(fd,address,length) _write(fd,address,(unsigned int)(length))
28 #define lseek _lseeki64
29 #define open _open
30 #define close _close
31 #define unlink _unlink
32 #else
33 #include <unistd.h>
34 #endif
35
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <fcntl.h>
40 #include <errno.h>
41 #include <sys/stat.h>
42
43 #if defined(_MSC_VER) || defined(__MINGW32__)
44 #include "mman-win32.h"
45 #else
46 #include <sys/mman.h>
47 #endif
48
49 #include <sys/types.h>
50
51 #include "files.h"
52
53
54 /*+ A structure to contain the list of memory mapped files. +*/
55 struct mmapinfo
56 {
57 const char *filename; /*+ The name of the file (the index of the list). +*/
58 int fd; /*+ The file descriptor used when it was opened. +*/
59 char *address; /*+ The address the file was mapped to. +*/
60 size_t length; /*+ The length of the file. +*/
61 };
62
63 /*+ The list of memory mapped files. +*/
64 static struct mmapinfo *mappedfiles;
65
66 /*+ The number of mapped files. +*/
67 static int nmappedfiles=0;
68
69
70 #define BUFFLEN 4096
71
72 /*+ A structure to contain the list of file buffers. +*/
73 struct filebuffer
74 {
75 char buffer[BUFFLEN]; /*+ The data buffer. +*/
76 size_t pointer; /*+ The read/write pointer for the file buffer. +*/
77 size_t length; /*+ The read pointer for the file buffer. +*/
78 int reading; /*+ A flag to indicate if the file is for reading. +*/
79 };
80
81 /*+ The list of file buffers. +*/
82 static struct filebuffer **filebuffers=NULL;
83
84 /*+ The number of allocated file buffer pointers. +*/
85 static int nfilebuffers=0;
86
87
88 #if defined(_MSC_VER) || defined(__MINGW32__)
89
90 /*+ A structure to contain the list of opened files to record which are to be deleted when closed. +*/
91 struct openedfile
92 {
93 const char *filename; /*+ The name of the file. +*/
94 int delete; /*+ Set to non-zero value if the file is to be deleted when closed. +*/
95 };
96
97 /*+ The list of opened files. +*/
98 static struct openedfile **openedfiles=NULL;
99
100 /*+ The number of allocated opened file buffer pointers. +*/
101 static int nopenedfiles=0;
102
103 #endif
104
105
106 /* Local functions */
107
108 static void CreateFileBuffer(int fd,int read_write);
109
110 #if defined(_MSC_VER) || defined(__MINGW32__)
111
112 static void CreateOpenedFile(int fd,const char *filename);
113
114 #endif
115
116
117 /*++++++++++++++++++++++++++++++++++++++
118 Return a filename composed of the dirname, prefix and name.
119
120 char *FileName Returns a pointer to memory allocated to the filename.
121
122 const char *dirname The directory name.
123
124 const char *prefix The file prefix.
125
126 const char *name The main part of the name.
127 ++++++++++++++++++++++++++++++++++++++*/
128
129 char *FileName(const char *dirname,const char *prefix, const char *name)
130 {
131 char *filename=(char*)malloc((dirname?strlen(dirname):0)+1+(prefix?strlen(prefix):0)+1+strlen(name)+1);
132
133 sprintf(filename,"%s%s%s%s%s",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":"",name);
134
135 return(filename);
136 }
137
138
139 /*++++++++++++++++++++++++++++++++++++++
140 Open a file read-only and map it into memory.
141
142 void *MapFile Returns the address of the file or exits in case of an error.
143
144 const char *filename The name of the file to open.
145 ++++++++++++++++++++++++++++++++++++++*/
146
147 void *MapFile(const char *filename)
148 {
149 int fd;
150 struct stat buf;
151 off_t size;
152 void *address;
153
154 /* Open the file */
155
156 #if defined(_MSC_VER) || defined(__MINGW32__)
157 fd=open(filename,O_RDONLY|O_BINARY);
158 #else
159 fd=open(filename,O_RDONLY);
160 #endif
161
162 if(fd<0)
163 {
164 fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
165 exit(EXIT_FAILURE);
166 }
167
168 /* Get its size */
169
170 if(stat(filename,&buf))
171 {
172 fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno));
173 exit(EXIT_FAILURE);
174 }
175
176 size=buf.st_size;
177
178 /* Map the file */
179
180 address=mmap(NULL,size,PROT_READ,MAP_SHARED,fd,0);
181
182 if(address==MAP_FAILED)
183 {
184 close(fd);
185
186 fprintf(stderr,"Cannot mmap file '%s' for reading [%s].\n",filename,strerror(errno));
187 exit(EXIT_FAILURE);
188 }
189
190 log_mmap(size);
191
192 /* Store the information about the mapped file */
193
194 mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo));
195
196 mappedfiles[nmappedfiles].filename=filename;
197 mappedfiles[nmappedfiles].fd=fd;
198 mappedfiles[nmappedfiles].address=address;
199 mappedfiles[nmappedfiles].length=size;
200
201 nmappedfiles++;
202
203 return(address);
204 }
205
206
207 /*++++++++++++++++++++++++++++++++++++++
208 Open a file read-write and map it into memory.
209
210 void *MapFileWriteable Returns the address of the file or exits in case of an error.
211
212 const char *filename The name of the file to open.
213 ++++++++++++++++++++++++++++++++++++++*/
214
215 void *MapFileWriteable(const char *filename)
216 {
217 int fd;
218 struct stat buf;
219 off_t size;
220 void *address;
221
222 /* Open the file */
223
224 #if defined(_MSC_VER) || defined(__MINGW32__)
225 fd=open(filename,O_RDWR|O_BINARY);
226 #else
227 fd=open(filename,O_RDWR);
228 #endif
229
230 if(fd<0)
231 {
232 fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno));
233 exit(EXIT_FAILURE);
234 }
235
236 /* Get its size */
237
238 if(stat(filename,&buf))
239 {
240 fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno));
241 exit(EXIT_FAILURE);
242 }
243
244 size=buf.st_size;
245
246 /* Map the file */
247
248 address=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
249
250 if(address==MAP_FAILED)
251 {
252 close(fd);
253
254 fprintf(stderr,"Cannot mmap file '%s' for reading and writing [%s].\n",filename,strerror(errno));
255 exit(EXIT_FAILURE);
256 }
257
258 log_mmap(size);
259
260 /* Store the information about the mapped file */
261
262 mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo));
263
264 mappedfiles[nmappedfiles].filename=filename;
265 mappedfiles[nmappedfiles].fd=fd;
266 mappedfiles[nmappedfiles].address=address;
267 mappedfiles[nmappedfiles].length=size;
268
269 nmappedfiles++;
270
271 return(address);
272 }
273
274
275 /*++++++++++++++++++++++++++++++++++++++
276 Unmap a file and close it.
277
278 void *UnmapFile Returns NULL (for similarity to the MapFile function).
279
280 const void *address The address of the mapped file in memory.
281 ++++++++++++++++++++++++++++++++++++++*/
282
283 void *UnmapFile(const void *address)
284 {
285 int i;
286
287 for(i=0;i<nmappedfiles;i++)
288 if(mappedfiles[i].address==address)
289 break;
290
291 if(i==nmappedfiles)
292 {
293 fprintf(stderr,"The data at address %p was not mapped using MapFile().\n",address);
294 exit(EXIT_FAILURE);
295 }
296
297 /* Close the file */
298
299 close(mappedfiles[i].fd);
300
301 /* Unmap the file */
302
303 munmap(mappedfiles[i].address,mappedfiles[i].length);
304
305 log_munmap(mappedfiles[i].length);
306
307 /* Shuffle the list of files */
308
309 nmappedfiles--;
310
311 if(nmappedfiles>i)
312 memmove(&mappedfiles[i],&mappedfiles[i+1],(nmappedfiles-i)*sizeof(struct mmapinfo));
313
314 return(NULL);
315 }
316
317
318 /*++++++++++++++++++++++++++++++++++++++
319 Open an existing file on disk for reading.
320
321 int SlimMapFile Returns the file descriptor if OK or exits in case of an error.
322
323 const char *filename The name of the file to open.
324 ++++++++++++++++++++++++++++++++++++++*/
325
326 int SlimMapFile(const char *filename)
327 {
328 int fd;
329
330 /* Open the file */
331
332 #if defined(_MSC_VER) || defined(__MINGW32__)
333 fd=open(filename,O_RDONLY|O_BINARY);
334 #else
335 fd=open(filename,O_RDONLY);
336 #endif
337
338 if(fd<0)
339 {
340 fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
341 exit(EXIT_FAILURE);
342 }
343
344 CreateFileBuffer(fd,0);
345
346 return(fd);
347 }
348
349
350 /*++++++++++++++++++++++++++++++++++++++
351 Open an existing file on disk for reading or writing.
352
353 int SlimMapFileWriteable Returns the file descriptor if OK or exits in case of an error.
354
355 const char *filename The name of the file to open.
356 ++++++++++++++++++++++++++++++++++++++*/
357
358 int SlimMapFileWriteable(const char *filename)
359 {
360 int fd;
361
362 /* Open the file */
363
364 #if defined(_MSC_VER) || defined(__MINGW32__)
365 fd=open(filename,O_RDWR|O_BINARY);
366 #else
367 fd=open(filename,O_RDWR);
368 #endif
369
370 if(fd<0)
371 {
372 fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno));
373 exit(EXIT_FAILURE);
374 }
375
376 CreateFileBuffer(fd,0);
377
378 return(fd);
379 }
380
381
382 /*++++++++++++++++++++++++++++++++++++++
383 Close a file on disk.
384
385 int SlimUnmapFile returns -1 (for similarity to the UnmapFile function).
386
387 int fd The file descriptor to close.
388 ++++++++++++++++++++++++++++++++++++++*/
389
390 int SlimUnmapFile(int fd)
391 {
392 close(fd);
393
394 return(-1);
395 }
396
397
398 /*++++++++++++++++++++++++++++++++++++++
399 Open a new file on disk for writing (with buffering).
400
401 int OpenFileBufferedNew Returns the file descriptor if OK or exits in case of an error.
402
403 const char *filename The name of the file to create.
404 ++++++++++++++++++++++++++++++++++++++*/
405
406 int OpenFileBufferedNew(const char *filename)
407 {
408 int fd;
409
410 /* Open the file */
411
412 #if defined(_MSC_VER)
413 fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY);
414 #else
415 #if defined(__MINGW32__)
416 fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,S_IRUSR|S_IWUSR);
417 #else
418 fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC ,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
419 #endif
420 #endif
421
422 if(fd<0)
423 {
424 fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",filename,strerror(errno));
425 exit(EXIT_FAILURE);
426 }
427
428 CreateFileBuffer(fd,-1);
429
430 #if defined(_MSC_VER) || defined(__MINGW32__)
431 CreateOpenedFile(fd,filename);
432 #endif
433
434 return(fd);
435 }
436
437
438 /*++++++++++++++++++++++++++++++++++++++
439 Open a new or existing file on disk for appending (with buffering).
440
441 int OpenFileBufferedAppend Returns the file descriptor if OK or exits in case of an error.
442
443 const char *filename The name of the file to create or open.
444 ++++++++++++++++++++++++++++++++++++++*/
445
446 int OpenFileBufferedAppend(const char *filename)
447 {
448 int fd;
449
450 /* Open the file */
451
452 #if defined(_MSC_VER)
453 fd=open(filename,O_WRONLY|O_CREAT|O_APPEND|O_BINARY);
454 #else
455 #if defined(__MINGW32__)
456 fd=open(filename,O_WRONLY|O_CREAT|O_APPEND|O_BINARY,S_IRUSR|S_IWUSR);
457 #else
458 fd=open(filename,O_WRONLY|O_CREAT|O_APPEND ,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
459 #endif
460 #endif
461
462 if(fd<0)
463 {
464 fprintf(stderr,"Cannot open file '%s' for appending [%s].\n",filename,strerror(errno));
465 exit(EXIT_FAILURE);
466 }
467
468 CreateFileBuffer(fd,-1);
469
470 #if defined(_MSC_VER) || defined(__MINGW32__)
471 CreateOpenedFile(fd,filename);
472 #endif
473
474 return(fd);
475 }
476
477
478 /*++++++++++++++++++++++++++++++++++++++
479 Open an existing file on disk for reading (with buffering).
480
481 int ReOpenFileBuffered Returns the file descriptor if OK or exits in case of an error.
482
483 const char *filename The name of the file to open.
484 ++++++++++++++++++++++++++++++++++++++*/
485
486 int ReOpenFileBuffered(const char *filename)
487 {
488 int fd;
489
490 /* Open the file */
491
492 #if defined(_MSC_VER) || defined(__MINGW32__)
493 fd=open(filename,O_RDONLY|O_BINARY);
494 #else
495 fd=open(filename,O_RDONLY);
496 #endif
497
498 if(fd<0)
499 {
500 fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
501 exit(EXIT_FAILURE);
502 }
503
504 CreateFileBuffer(fd,1);
505
506 #if defined(_MSC_VER) || defined(__MINGW32__)
507 CreateOpenedFile(fd,filename);
508 #endif
509
510 return(fd);
511 }
512
513
514 /*++++++++++++++++++++++++++++++++++++++
515 Open an existing file on disk for reading (with buffering), delete
516 it and open a new file on disk for writing (with buffering).
517
518 int ReplaceFileBuffered Returns the file descriptor of the new writable file.
519
520 const char *filename The name of the file to open, delete and replace.
521
522 int *oldfd Returns the file descriptor of the old, readable file.
523 ++++++++++++++++++++++++++++++++++++++*/
524
525 int ReplaceFileBuffered(const char *filename,int *oldfd)
526 {
527 int newfd;
528
529 #if defined(_MSC_VER) || defined(__MINGW32__)
530
531 char *filename2;
532
533 filename2=strcpy(malloc(strlen(filename)+2),filename);
534 strcat(filename2,"2");
535
536 RenameFile(filename,filename2);
537
538 *oldfd=ReOpenFileBuffered(filename2);
539
540 DeleteFile(filename2);
541
542 #else
543
544 *oldfd=ReOpenFileBuffered(filename);
545
546 DeleteFile(filename);
547
548 #endif
549
550 newfd=OpenFileBufferedNew(filename);
551
552 return(newfd);
553 }
554
555
556 /*++++++++++++++++++++++++++++++++++++++
557 Write data to a file descriptor (via a buffer).
558
559 int WriteFileBuffered Returns 0 if OK or something else in case of an error.
560
561 int fd The file descriptor to write to.
562
563 const void *address The address of the data to be written.
564
565 size_t length The length of data to write.
566 ++++++++++++++++++++++++++++++++++++++*/
567
568 int WriteFileBuffered(int fd,const void *address,size_t length)
569 {
570 logassert(fd!=-1,"File descriptor is in error - report a bug");
571
572 logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
573
574 logassert(!filebuffers[fd]->reading,"File descriptor was not opened for writing - report a bug");
575
576 /* Write the data */
577
578 if((filebuffers[fd]->pointer+length)>BUFFLEN)
579 {
580 if(write(fd,filebuffers[fd]->buffer,filebuffers[fd]->pointer)!=(ssize_t)filebuffers[fd]->pointer)
581 return(-1);
582
583 filebuffers[fd]->pointer=0;
584 }
585
586 if(length>=BUFFLEN)
587 {
588 if(write(fd,address,length)!=(ssize_t)length)
589 return(-1);
590
591 return(0);
592 }
593
594 memcpy(filebuffers[fd]->buffer+filebuffers[fd]->pointer,address,length);
595
596 filebuffers[fd]->pointer+=length;
597
598 return(0);
599 }
600
601
602 /*++++++++++++++++++++++++++++++++++++++
603 Read data from a file descriptor (via a buffer).
604
605 int ReadFileBuffered Returns 0 if OK or something else in case of an error.
606
607 int fd The file descriptor to read from.
608
609 void *address The address the data is to be read into.
610
611 size_t length The length of data to read.
612 ++++++++++++++++++++++++++++++++++++++*/
613
614 int ReadFileBuffered(int fd,void *address,size_t length)
615 {
616 logassert(fd!=-1,"File descriptor is in error - report a bug");
617
618 logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
619
620 logassert(filebuffers[fd]->reading,"File descriptor was not opened for reading - report a bug");
621
622 /* Read the data */
623
624 if((filebuffers[fd]->pointer+length)>filebuffers[fd]->length)
625 if(filebuffers[fd]->pointer<filebuffers[fd]->length)
626 {
627 memcpy(address,filebuffers[fd]->buffer+filebuffers[fd]->pointer,filebuffers[fd]->length-filebuffers[fd]->pointer);
628
629 address=(char*)address+filebuffers[fd]->length-filebuffers[fd]->pointer;
630 length-=filebuffers[fd]->length-filebuffers[fd]->pointer;
631
632 filebuffers[fd]->pointer=0;
633 filebuffers[fd]->length=0;
634 }
635
636 if(length>=BUFFLEN)
637 {
638 if(read(fd,address,length)!=(ssize_t)length)
639 return(-1);
640
641 return(0);
642 }
643
644 if(filebuffers[fd]->pointer==filebuffers[fd]->length)
645 {
646 ssize_t len=read(fd,filebuffers[fd]->buffer,BUFFLEN);
647
648 if(len<=0)
649 return(-1);
650
651 filebuffers[fd]->length=len;
652 filebuffers[fd]->pointer=0;
653 }
654
655 if(filebuffers[fd]->length==0)
656 return(-1);
657
658 memcpy(address,filebuffers[fd]->buffer+filebuffers[fd]->pointer,length);
659
660 filebuffers[fd]->pointer+=length;
661
662 return(0);
663 }
664
665
666 /*++++++++++++++++++++++++++++++++++++++
667 Seek to a position in a file descriptor that uses a buffer.
668
669 int SeekFileBuffered Returns 0 if OK or something else in case of an error.
670
671 int fd The file descriptor to seek within.
672
673 off_t position The position to seek to.
674 ++++++++++++++++++++++++++++++++++++++*/
675
676 int SeekFileBuffered(int fd,off_t position)
677 {
678 logassert(fd!=-1,"File descriptor is in error - report a bug");
679
680 logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
681
682 /* Seek the data - doesn't need to be highly optimised */
683
684 if(!filebuffers[fd]->reading)
685 if(write(fd,filebuffers[fd]->buffer,filebuffers[fd]->pointer)!=(ssize_t)filebuffers[fd]->pointer)
686 return(-1);
687
688 filebuffers[fd]->pointer=0;
689 filebuffers[fd]->length=0;
690
691 if(lseek(fd,position,SEEK_SET)!=position)
692 return(-1);
693
694 return(0);
695 }
696
697
698 /*++++++++++++++++++++++++++++++++++++++
699 Skip forward by an offset in a file descriptor that uses a buffer.
700
701 int SkipFileBuffered Returns 0 if OK or something else in case of an error.
702
703 int fd The file descriptor to skip within.
704
705 off_t skip The amount to skip forward.
706 ++++++++++++++++++++++++++++++++++++++*/
707
708 int SkipFileBuffered(int fd,off_t skip)
709 {
710 logassert(fd!=-1,"File descriptor is in error - report a bug");
711
712 logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
713
714 logassert(filebuffers[fd]->reading,"File descriptor was not opened for reading - report a bug");
715
716 /* Skip the data - needs to be optimised */
717
718 if((filebuffers[fd]->pointer+skip)>filebuffers[fd]->length)
719 {
720 skip-=(off_t)(filebuffers[fd]->length-filebuffers[fd]->pointer);
721
722 filebuffers[fd]->pointer=0;
723 filebuffers[fd]->length=0;
724
725 if(lseek(fd,skip,SEEK_CUR)==-1)
726 return(-1);
727 }
728 else
729 filebuffers[fd]->pointer+=skip;
730
731 return(0);
732 }
733
734
735 /*++++++++++++++++++++++++++++++++++++++
736 Get the size of a file.
737
738 off_t SizeFile Returns the file size if OK or exits in case of an error.
739
740 const char *filename The name of the file to check.
741 ++++++++++++++++++++++++++++++++++++++*/
742
743 off_t SizeFile(const char *filename)
744 {
745 struct stat buf;
746
747 if(stat(filename,&buf))
748 {
749 fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno));
750 exit(EXIT_FAILURE);
751 }
752
753 return(buf.st_size);
754 }
755
756
757 /*++++++++++++++++++++++++++++++++++++++
758 Get the size of a file from a file descriptor.
759
760 off_t SizeFileFD Returns the file size if OK or exits in case of an error.
761
762 int fd The file descriptor to check.
763 ++++++++++++++++++++++++++++++++++++++*/
764
765 off_t SizeFileFD(int fd)
766 {
767 struct stat buf;
768
769 if(fstat(fd,&buf))
770 {
771 fprintf(stderr,"Cannot stat file descriptor '%d' [%s].\n",fd,strerror(errno));
772 exit(EXIT_FAILURE);
773 }
774
775 return(buf.st_size);
776 }
777
778
779 /*++++++++++++++++++++++++++++++++++++++
780 Check if a file exists.
781
782 int ExistsFile Returns 1 if the file exists and 0 if not.
783
784 const char *filename The name of the file to check.
785 ++++++++++++++++++++++++++++++++++++++*/
786
787 int ExistsFile(const char *filename)
788 {
789 struct stat buf;
790
791 if(stat(filename,&buf))
792 return(0);
793 else
794 return(1);
795 }
796
797
798 /*++++++++++++++++++++++++++++++++++++++
799 Close a file on disk (and flush the buffer).
800
801 int CloseFileBuffered returns -1 (for similarity to the *OpenFileBuffered* functions).
802
803 int fd The file descriptor to close.
804 ++++++++++++++++++++++++++++++++++++++*/
805
806 int CloseFileBuffered(int fd)
807 {
808 logassert(fd<nfilebuffers && filebuffers[fd],"File descriptor has no buffer - report a bug");
809
810 if(!filebuffers[fd]->reading)
811 if(write(fd,filebuffers[fd]->buffer,filebuffers[fd]->pointer)!=(ssize_t)filebuffers[fd]->pointer)
812 return(-1);
813
814 close(fd);
815
816 free(filebuffers[fd]);
817 filebuffers[fd]=NULL;
818
819 #if defined(_MSC_VER) || defined(__MINGW32__)
820
821 logassert(fd<nopenedfiles && openedfiles[fd],"File descriptor has no record of opening - report a bug");
822
823 if(openedfiles[fd]->delete)
824 unlink(openedfiles[fd]->filename);
825
826 free(openedfiles[fd]);
827 openedfiles[fd]=NULL;
828
829 #endif
830
831 return(-1);
832 }
833
834
835 /*++++++++++++++++++++++++++++++++++++++
836 Open an existing file on disk for reading (in a simple mode).
837
838 int OpenFile Returns the file descriptor if OK or exits in case of an error.
839
840 const char *filename The name of the file to open.
841 ++++++++++++++++++++++++++++++++++++++*/
842
843 int OpenFile(const char *filename)
844 {
845 int fd;
846
847 /* Open the file */
848
849 #if defined(_MSC_VER) || defined(__MINGW32__)
850 fd=open(filename,O_RDONLY|O_BINARY);
851 #else
852 fd=open(filename,O_RDONLY);
853 #endif
854
855 if(fd<0)
856 {
857 fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno));
858 exit(EXIT_FAILURE);
859 }
860
861 #if defined(_MSC_VER) || defined(__MINGW32__)
862 CreateOpenedFile(fd,filename);
863 #endif
864
865 return(fd);
866 }
867
868
869 /*++++++++++++++++++++++++++++++++++++++
870 Close a file on disk (that was opened in simple mode).
871
872 int fd The file descriptor to close.
873 ++++++++++++++++++++++++++++++++++++++*/
874
875 void CloseFile(int fd)
876 {
877 close(fd);
878
879 #if defined(_MSC_VER) || defined(__MINGW32__)
880
881 logassert(fd<nopenedfiles && openedfiles[fd],"File descriptor has no record of opening - report a bug");
882
883 if(openedfiles[fd]->delete)
884 unlink(openedfiles[fd]->filename);
885
886 free(openedfiles[fd]);
887 openedfiles[fd]=NULL;
888
889 #endif
890 }
891
892
893 /*++++++++++++++++++++++++++++++++++++++
894 Delete a file from disk.
895
896 int DeleteFile Returns 0 if OK.
897
898 const char *filename The name of the file to delete.
899 ++++++++++++++++++++++++++++++++++++++*/
900
901 int DeleteFile(const char *filename)
902 {
903 #if defined(_MSC_VER) || defined(__MINGW32__)
904
905 int fd;
906
907 for(fd=0;fd<nopenedfiles;fd++)
908 if(openedfiles[fd] && !strcmp(openedfiles[fd]->filename,filename))
909 {
910 openedfiles[fd]->delete=1;
911 return(0);
912 }
913
914 #endif
915
916 unlink(filename);
917
918 return(0);
919 }
920
921
922 /*++++++++++++++++++++++++++++++++++++++
923 Rename a file on disk.
924
925 int RenameFile Returns 0 if OK.
926
927 const char *oldfilename The old name of the file before renaming.
928
929 const char *newfilename The new name of the file after renaming.
930 ++++++++++++++++++++++++++++++++++++++*/
931
932 int RenameFile(const char *oldfilename,const char *newfilename)
933 {
934 rename(oldfilename,newfilename);
935
936 return(0);
937 }
938
939
940 /*++++++++++++++++++++++++++++++++++++++
941 Create a file buffer.
942
943 int fd The file descriptor.
944
945 int read_write A flag set to 1 for reading, -1 for writing and 0 for unbuffered.
946 ++++++++++++++++++++++++++++++++++++++*/
947
948 static void CreateFileBuffer(int fd,int read_write)
949 {
950 if(nfilebuffers<=fd)
951 {
952 int i;
953
954 filebuffers=(struct filebuffer**)realloc((void*)filebuffers,(fd+1)*sizeof(struct filebuffer*));
955
956 for(i=nfilebuffers;i<=fd;i++)
957 filebuffers[i]=NULL;
958
959 nfilebuffers=fd+1;
960 }
961
962 if(read_write)
963 {
964 filebuffers[fd]=(struct filebuffer*)calloc(sizeof(struct filebuffer),1);
965
966 filebuffers[fd]->reading=(read_write==1);
967 }
968 }
969
970
971 #if defined(_MSC_VER) || defined(__MINGW32__)
972
973 /*++++++++++++++++++++++++++++++++++++++
974 Create an opened file record.
975
976 int fd The file descriptor.
977
978 const char *filename The name of the file.
979 ++++++++++++++++++++++++++++++++++++++*/
980
981 static void CreateOpenedFile(int fd,const char *filename)
982 {
983 if(nopenedfiles<=fd)
984 {
985 int i;
986
987 openedfiles=(struct openedfile**)realloc((void*)openedfiles,(fd+1)*sizeof(struct openedfile*));
988
989 for(i=nopenedfiles;i<=fd;i++)
990 openedfiles[i]=NULL;
991
992 nopenedfiles=fd+1;
993 }
994
995 openedfiles[fd]=(struct openedfile*)calloc(sizeof(struct openedfile),1);
996
997 openedfiles[fd]->filename=strcpy(malloc(strlen(filename)+1),filename);
998 openedfiles[fd]->delete=0;
999 }
1000
1001 #endif

Properties

Name Value
cvs:description File handling functions.