1b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
2b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project   See the file COPYING for copying permission.
3b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project*/
4b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
5b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <sys/types.h>
6b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <sys/mman.h>
7b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <sys/stat.h>
8b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <fcntl.h>
9b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <errno.h>
10b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <string.h>
11b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <stdio.h>
12b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <unistd.h>
13b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
14b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#ifndef MAP_FILE
15b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#define MAP_FILE 0
16b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#endif
17b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
18b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include "filemap.h"
19b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
20b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectint
21b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectfilemap(const char *name,
22b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        void (*processor)(const void *, size_t, const char *, void *arg),
23b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        void *arg)
24b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
25b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  int fd;
26b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  size_t nbytes;
27b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  struct stat sb;
28b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  void *p;
29b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
30b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  fd = open(name, O_RDONLY);
31b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  if (fd < 0) {
32b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    perror(name);
33b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    return 0;
34b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  }
35b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  if (fstat(fd, &sb) < 0) {
36b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    perror(name);
37b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    close(fd);
38b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    return 0;
39b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  }
40b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  if (!S_ISREG(sb.st_mode)) {
41b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    close(fd);
42b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    fprintf(stderr, "%s: not a regular file\n", name);
43b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    return 0;
44b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  }
45b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
46b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  nbytes = sb.st_size;
47d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes  /* mmap fails for zero length files */
48d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes  if (nbytes == 0) {
49d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes    static const char c = '\0';
50d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes    processor(&c, 0, name, arg);
51d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes    close(fd);
52d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes    return 1;
53d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes  }
54b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  p = (void *)mmap((caddr_t)0, (size_t)nbytes, PROT_READ,
55b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                   MAP_FILE|MAP_PRIVATE, fd, (off_t)0);
56b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  if (p == (void *)-1) {
57b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    perror(name);
58b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    close(fd);
59b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    return 0;
60b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  }
61b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  processor(p, nbytes, name, arg);
62b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  munmap((caddr_t)p, nbytes);
63b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  close(fd);
64b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project  return 1;
65b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
66