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
11302385Sdelphij/* Functions close(2) and read(2) */
12178848Scokane#ifdef __WATCOMC__
13178848Scokane#ifndef __LINUX__
14178848Scokane#include <io.h>
15178848Scokane#else
16178848Scokane#include <unistd.h>
17178848Scokane#endif
18302385Sdelphij#else
19302385Sdelphij# if !defined(WIN32) && !defined(_WIN32) && !defined(_WIN64)
20302385Sdelphij#  include <unistd.h>
21302385Sdelphij# endif
22178848Scokane#endif
23178848Scokane
24104349Sphk#ifndef S_ISREG
25104349Sphk#ifndef S_IFREG
26104349Sphk#define S_IFREG _S_IFREG
27104349Sphk#endif
28104349Sphk#ifndef S_IFMT
29104349Sphk#define S_IFMT _S_IFMT
30104349Sphk#endif
31104349Sphk#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
32104349Sphk#endif /* not S_ISREG */
33104349Sphk
34104349Sphk#ifndef O_BINARY
35104349Sphk#ifdef _O_BINARY
36104349Sphk#define O_BINARY _O_BINARY
37104349Sphk#else
38104349Sphk#define O_BINARY 0
39104349Sphk#endif
40104349Sphk#endif
41104349Sphk
42104349Sphk#include "filemap.h"
43104349Sphk
44104349Sphkint
45104349Sphkfilemap(const char *name,
46104349Sphk        void (*processor)(const void *, size_t, const char *, void *arg),
47104349Sphk        void *arg)
48104349Sphk{
49104349Sphk  size_t nbytes;
50104349Sphk  int fd;
51104349Sphk  int n;
52104349Sphk  struct stat sb;
53104349Sphk  void *p;
54104349Sphk
55104349Sphk  fd = open(name, O_RDONLY|O_BINARY);
56104349Sphk  if (fd < 0) {
57104349Sphk    perror(name);
58104349Sphk    return 0;
59104349Sphk  }
60104349Sphk  if (fstat(fd, &sb) < 0) {
61104349Sphk    perror(name);
62247296Sdelphij    close(fd);
63104349Sphk    return 0;
64104349Sphk  }
65104349Sphk  if (!S_ISREG(sb.st_mode)) {
66104349Sphk    fprintf(stderr, "%s: not a regular file\n", name);
67247296Sdelphij    close(fd);
68104349Sphk    return 0;
69104349Sphk  }
70104349Sphk  nbytes = sb.st_size;
71178848Scokane  /* malloc will return NULL with nbytes == 0, handle files with size 0 */
72178848Scokane  if (nbytes == 0) {
73178848Scokane    static const char c = '\0';
74178848Scokane    processor(&c, 0, name, arg);
75178848Scokane    close(fd);
76178848Scokane    return 1;
77178848Scokane  }
78104349Sphk  p = malloc(nbytes);
79104349Sphk  if (!p) {
80104349Sphk    fprintf(stderr, "%s: out of memory\n", name);
81178848Scokane    close(fd);
82104349Sphk    return 0;
83104349Sphk  }
84104349Sphk  n = read(fd, p, nbytes);
85104349Sphk  if (n < 0) {
86104349Sphk    perror(name);
87178848Scokane    free(p);
88104349Sphk    close(fd);
89104349Sphk    return 0;
90104349Sphk  }
91104349Sphk  if (n != nbytes) {
92104349Sphk    fprintf(stderr, "%s: read unexpected number of bytes\n", name);
93178848Scokane    free(p);
94104349Sphk    close(fd);
95104349Sphk    return 0;
96104349Sphk  }
97104349Sphk  processor(p, nbytes, name, arg);
98104349Sphk  free(p);
99104349Sphk  close(fd);
100104349Sphk  return 1;
101104349Sphk}
102