OSDN Git Service

Bumped version 2.4.4.
[chasen-legacy/chasen.git] / lib / mmap.c
1 /*
2  * Copyright (c) 2003 Nara Institute of Science and Technology
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name Nara Institute of Science and Technology may not be used to
15  *    endorse or promote products derived from this software without
16  *    specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY Nara Institute of Science and Technology 
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
21  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE Nara Institute
22  * of Science and Technology BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
26  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $Id: mmap.c,v 1.1.1.1 2007/03/13 07:40:10 masayu-a Exp $
31  */
32
33 #include "config.h"
34
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 #ifdef HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif
41 #ifdef HAVE_SYS_STAT_H
42 #include <sys/stat.h>
43 #endif
44 #ifdef HAVE_SYS_TYPES_H
45 #include <sys/types.h>
46 #endif
47 #ifdef HAVE_SYS_PARAM_H
48 #include <sys/param.h>
49 #endif
50
51 #ifdef __MINGW32__
52 #undef HAVE_MMAP
53 #endif
54 #ifdef HAVE_MMAP
55 #include <sys/mman.h>
56 #endif
57
58 #if !defined HAVE_MMAP && defined HAVE_WINDOWS_H
59 #include <windows.h>
60 #endif
61
62 #if ! defined _WIN32 && ! defined __CYGWIN__
63 #define O_BINARY 0
64 #endif
65
66 #ifndef HAVE_MMAP
67 #define PROT_WRITE  2
68 #define PROT_READ   1
69 #endif
70
71 #include "chalib.h"
72
73 struct _cha_mmap_t {
74     void *map;
75     off_t size;
76 #if !defined HAVE_MMAP && defined HAVE_WINDOWS_H
77     HANDLE hfile;
78     HANDLE hmap;
79 #endif
80 };
81
82 static cha_mmap_t *
83 mmap_file(char *filename, int prot)
84 {
85     cha_mmap_t *mm;
86 #if !defined HAVE_MMAP && defined HAVE_WINDOWS_H
87     unsigned long file_mode, map_mode, view_mode;
88 #else
89     int fd;
90     int flag = O_RDONLY;
91     struct stat st;
92 #endif
93
94     mm = cha_malloc(sizeof(cha_mmap_t));
95
96 #if !defined HAVE_MMAP && defined HAVE_WINDOWS_H
97     if ((prot & PROT_WRITE) != 0) {
98         file_mode = GENERIC_READ | GENERIC_WRITE;
99         map_mode = PAGE_READWRITE;
100         view_mode = FILE_MAP_WRITE;
101     } else {
102         file_mode = GENERIC_READ;
103         map_mode = PAGE_READONLY;
104         view_mode = FILE_MAP_READ;
105     }
106
107     mm->hfile = CreateFile(filename, file_mode, FILE_SHARE_READ, NULL,
108                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
109     if (mm->hfile == INVALID_HANDLE_VALUE)
110         cha_exit_perror(filename);
111
112     mm->size = GetFileSize(mm->hfile, NULL);
113
114     mm->hmap = CreateFileMapping(mm->hfile, NULL, map_mode, 0, 0, NULL);
115     if (mm->hmap == NULL) {
116         CloseHandle(mm->hfile);
117         cha_exit_perror(filename);
118     }
119                                 
120     mm->map = MapViewOfFile(mm->hmap, view_mode, 0, 0, 0);
121     if (mm->map == NULL) {
122         CloseHandle(mm->hfile);
123         CloseHandle(mm->hmap);
124         cha_exit_perror(filename);
125     }
126
127 #else /* !defined HAVE_MMAP && defined HAVE_WINDOWS_H */
128     if ((prot & PROT_WRITE) != 0)
129         flag = O_RDWR;
130         
131     if ((fd = open(filename, flag)) < 0)
132         cha_exit_perror(filename);
133     if (fstat(fd, &st) < 0)
134         cha_exit_perror(filename);
135     mm->size = st.st_size;
136 #ifdef HAVE_MMAP
137     if ((mm->map = mmap((void *)0, mm->size, prot, MAP_SHARED, fd, 0))
138         == MAP_FAILED) {
139         cha_exit_perror(filename);
140     }
141 #else /* HAVE_MMAP */
142     mm->map = cha_malloc(mm->size);
143     if (read(fd, mm->map, mm->size) < 0)
144         cha_exit_perror(filename);
145 #endif /* HAVE_MMAP */
146     close(fd);
147
148 #endif /* HAVE_MMAP && defined HAVE_WINDOWS_H */
149     return mm;
150 }
151
152 cha_mmap_t *
153 cha_mmap_file(char *filename)
154 {
155     return mmap_file(filename, PROT_READ);
156 }
157
158 cha_mmap_t *
159 cha_mmap_file_w(char *filename)
160 {
161     return mmap_file(filename, PROT_READ | PROT_WRITE);
162 }
163
164 void
165 cha_munmap_file(cha_mmap_t *mm)
166 {
167 #if !defined HAVE_MMAP && defined HAVE_WINDOWS_H
168     UnmapViewOfFile(mm->map);
169     CloseHandle(mm->hmap);
170     CloseHandle(mm->hfile);
171 #else /* !defined HAVE_MMAP && defined HAVE_WINDOWS_H */
172 #ifdef HAVE_MMAP
173     munmap(mm->map, mm->size);
174 #else /* HAVE_MMAP */
175     cha_free(mm->map);
176 #endif /* HAVE_MMAP */
177 #endif /* !defined HAVE_MMAP && defined HAVE_WINDOWS_H */
178     cha_free(mm);
179 }
180
181 void *
182 cha_mmap_map(cha_mmap_t *mm)
183 {
184     return mm->map;
185 }
186
187 off_t
188 cha_mmap_size(cha_mmap_t *mm)
189 {
190     return mm->size;
191 }