1104349Sphk/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
2104349Sphk   See the file COPYING for copying permission.
3104349Sphk*/
4104349Sphk
5104349Sphk#include <sys/types.h>
6104349Sphk#include <sys/stat.h>
7104349Sphk#include <fcntl.h>
8104349Sphk#include <stdlib.h>
9104349Sphk#include <stdio.h>
10104349Sphk
11178848Scokane#ifdef __WATCOMC__
12178848Scokane#ifndef __LINUX__
13178848Scokane#include <io.h>
14178848Scokane#else
15178848Scokane#include <unistd.h>
16178848Scokane#endif
17178848Scokane#endif
18178848Scokane
19178848Scokane#ifdef __BEOS__
20178848Scokane#include <unistd.h>
21178848Scokane#endif
22178848Scokane
23104349Sphk#ifndef S_ISREG
24104349Sphk#ifndef S_IFREG
25104349Sphk#define S_IFREG _S_IFREG
26104349Sphk#endif
27104349Sphk#ifndef S_IFMT
28104349Sphk#define S_IFMT _S_IFMT
29104349Sphk#endif
30104349Sphk#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
31104349Sphk#endif /* not S_ISREG */
32104349Sphk
33104349Sphk#ifndef O_BINARY
34104349Sphk#ifdef _O_BINARY
35104349Sphk#define O_BINARY _O_BINARY
36104349Sphk#else
37104349Sphk#define O_BINARY 0
38104349Sphk#endif
39104349Sphk#endif
40104349Sphk
41104349Sphk#include "filemap.h"
42104349Sphk
43104349Sphkint
44104349Sphkfilemap(const char *name,
45104349Sphk        void (*processor)(const void *, size_t, const char *, void *arg),
46104349Sphk        void *arg)
47104349Sphk{
48104349Sphk  size_t nbytes;
49104349Sphk  int fd;
50104349Sphk  int n;
51104349Sphk  struct stat sb;
52104349Sphk  void *p;
53104349Sphk
54104349Sphk  fd = open(name, O_RDONLY|O_BINARY);
55104349Sphk  if (fd < 0) {
56104349Sphk    perror(name);
57104349Sphk    return 0;
58104349Sphk  }
59104349Sphk  if (fstat(fd, &sb) < 0) {
60104349Sphk    perror(name);
61247296Sdelphij    close(fd);
62104349Sphk    return 0;
63104349Sphk  }
64104349Sphk  if (!S_ISREG(sb.st_mode)) {
65104349Sphk    fprintf(stderr, "%s: not a regular file\n", name);
66247296Sdelphij    close(fd);
67104349Sphk    return 0;
68104349Sphk  }
69104349Sphk  nbytes = sb.st_size;
70178848Scokane  /* malloc will return NULL with nbytes == 0, handle files with size 0 */
71178848Scokane  if (nbytes == 0) {
72178848Scokane    static const char c = '\0';
73178848Scokane    processor(&c, 0, name, arg);
74178848Scokane    close(fd);
75178848Scokane    return 1;
76178848Scokane  }
77104349Sphk  p = malloc(nbytes);
78104349Sphk  if (!p) {
79104349Sphk    fprintf(stderr, "%s: out of memory\n", name);
80178848Scokane    close(fd);
81104349Sphk    return 0;
82104349Sphk  }
83104349Sphk  n = read(fd, p, nbytes);
84104349Sphk  if (n < 0) {
85104349Sphk    perror(name);
86178848Scokane    free(p);
87104349Sphk    close(fd);
88104349Sphk    return 0;
89104349Sphk  }
90104349Sphk  if (n != nbytes) {
91104349Sphk    fprintf(stderr, "%s: read unexpected number of bytes\n", name);
92178848Scokane    free(p);
93104349Sphk    close(fd);
94104349Sphk    return 0;
95104349Sphk  }
96104349Sphk  processor(p, nbytes, name, arg);
97104349Sphk  free(p);
98104349Sphk  close(fd);
99104349Sphk  return 1;
100104349Sphk}
101