Merge branch 'vendor/EXPAT'
[dragonfly.git] / contrib / expat / xmlwf / readfilemap.c
1 /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
2    See the file COPYING for copying permission.
3 */
4
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10
11 #ifdef __WATCOMC__
12 #ifndef __LINUX__
13 #include <io.h>
14 #else
15 #include <unistd.h>
16 #endif
17 #endif
18
19 #ifdef __BEOS__
20 #include <unistd.h>
21 #endif
22
23 #ifndef S_ISREG
24 #ifndef S_IFREG
25 #define S_IFREG _S_IFREG
26 #endif
27 #ifndef S_IFMT
28 #define S_IFMT _S_IFMT
29 #endif
30 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
31 #endif /* not S_ISREG */
32
33 #ifndef O_BINARY
34 #ifdef _O_BINARY
35 #define O_BINARY _O_BINARY
36 #else
37 #define O_BINARY 0
38 #endif
39 #endif
40
41 #include "filemap.h"
42
43 int
44 filemap(const char *name,
45         void (*processor)(const void *, size_t, const char *, void *arg),
46         void *arg)
47 {
48   size_t nbytes;
49   int fd;
50   int n;
51   struct stat sb;
52   void *p;
53
54   fd = open(name, O_RDONLY|O_BINARY);
55   if (fd < 0) {
56     perror(name);
57     return 0;
58   }
59   if (fstat(fd, &sb) < 0) {
60     perror(name);
61     return 0;
62   }
63   if (!S_ISREG(sb.st_mode)) {
64     fprintf(stderr, "%s: not a regular file\n", name);
65     return 0;
66   }
67   nbytes = sb.st_size;
68   /* malloc will return NULL with nbytes == 0, handle files with size 0 */
69   if (nbytes == 0) {
70     static const char c = '\0';
71     processor(&c, 0, name, arg);
72     close(fd);
73     return 1;
74   }
75   p = malloc(nbytes);
76   if (!p) {
77     fprintf(stderr, "%s: out of memory\n", name);
78     close(fd);
79     return 0;
80   }
81   n = read(fd, p, nbytes);
82   if (n < 0) {
83     perror(name);
84     free(p);
85     close(fd);
86     return 0;
87   }
88   if (n != nbytes) {
89     fprintf(stderr, "%s: read unexpected number of bytes\n", name);
90     free(p);
91     close(fd);
92     return 0;
93   }
94   processor(p, nbytes, name, arg);
95   free(p);
96   close(fd);
97   return 1;
98 }