]>
Commit | Line | Data |
---|---|---|
c84142e8 | 1 | /* Load needed message catalogs. |
d0fc4041 | 2 | Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. |
5f2eab42 | 3 | |
c84142e8 | 4 | This file is part of the GNU C Library. Its master source is NOT part of |
40a55d20 | 5 | the C library, however. |
24906b43 | 6 | |
c84142e8 UD |
7 | The GNU C Library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Library General Public License as | |
9 | published by the Free Software Foundation; either version 2 of the | |
10 | License, or (at your option) any later version. | |
0393dfd6 | 11 | |
c84142e8 UD |
12 | The GNU C Library is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | Library General Public License for more details. | |
24906b43 | 16 | |
c84142e8 UD |
17 | You should have received a copy of the GNU Library General Public |
18 | License along with the GNU C Library; see the file COPYING.LIB. If not, | |
19 | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 | Boston, MA 02111-1307, USA. */ | |
24906b43 RM |
21 | |
22 | #ifdef HAVE_CONFIG_H | |
23 | # include <config.h> | |
24 | #endif | |
25 | ||
26 | #include <fcntl.h> | |
27 | #include <sys/types.h> | |
28 | #include <sys/stat.h> | |
29 | ||
30 | #if defined STDC_HEADERS || defined _LIBC | |
31 | # include <stdlib.h> | |
32 | #endif | |
33 | ||
34 | #if defined HAVE_UNISTD_H || defined _LIBC | |
35 | # include <unistd.h> | |
36 | #endif | |
37 | ||
7cabd57c UD |
38 | #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ |
39 | || (defined _LIBC && defined _POSIX_MAPPED_FILES) | |
24906b43 | 40 | # include <sys/mman.h> |
7cabd57c UD |
41 | # undef HAVE_MMAP |
42 | # define HAVE_MMAP 1 | |
43 | #else | |
44 | # undef HAVE_MMAP | |
24906b43 RM |
45 | #endif |
46 | ||
47 | #include "gettext.h" | |
48 | #include "gettextP.h" | |
49 | ||
50 | /* @@ end of prolog @@ */ | |
51 | ||
52 | #ifdef _LIBC | |
c84142e8 UD |
53 | /* Rename the non ISO C functions. This is required by the standard |
54 | because some ISO C functions will require linking with this object | |
24906b43 | 55 | file and the name space must not be polluted. */ |
24906b43 RM |
56 | # define open __open |
57 | # define close __close | |
58 | # define read __read | |
59 | # define mmap __mmap | |
60 | # define munmap __munmap | |
61 | #endif | |
62 | ||
63 | /* We need a sign, whether a new catalog was loaded, which can be associated | |
64 | with all translations. This is important if the translations are | |
65 | cached by one of GCC's features. */ | |
afd4eb37 | 66 | int _nl_msg_cat_cntr = 0; |
24906b43 RM |
67 | |
68 | ||
69 | /* Load the message catalogs specified by FILENAME. If it is no valid | |
70 | message catalog do nothing. */ | |
71 | void | |
d0fc4041 | 72 | internal_function |
7a12c6bb RM |
73 | _nl_load_domain (domain_file) |
74 | struct loaded_l10nfile *domain_file; | |
24906b43 RM |
75 | { |
76 | int fd; | |
dfd2257a | 77 | size_t size; |
24906b43 RM |
78 | struct stat st; |
79 | struct mo_file_header *data = (struct mo_file_header *) -1; | |
24906b43 | 80 | int use_mmap = 0; |
7a12c6bb | 81 | struct loaded_domain *domain; |
24906b43 | 82 | |
7a12c6bb RM |
83 | domain_file->decided = 1; |
84 | domain_file->data = NULL; | |
24906b43 | 85 | |
75914335 RM |
86 | /* If the record does not represent a valid locale the FILENAME |
87 | might be NULL. This can happen when according to the given | |
88 | specification the locale file name is different for XPG and CEN | |
89 | syntax. */ | |
7a12c6bb | 90 | if (domain_file->filename == NULL) |
75914335 RM |
91 | return; |
92 | ||
24906b43 | 93 | /* Try to open the addressed file. */ |
7a12c6bb | 94 | fd = open (domain_file->filename, O_RDONLY); |
24906b43 RM |
95 | if (fd == -1) |
96 | return; | |
97 | ||
98 | /* We must know about the size of the file. */ | |
99 | if (fstat (fd, &st) != 0 | |
dfd2257a UD |
100 | || (size = (size_t) st.st_size) != st.st_size |
101 | || size < sizeof (struct mo_file_header)) | |
24906b43 RM |
102 | { |
103 | /* Something went wrong. */ | |
104 | close (fd); | |
105 | return; | |
106 | } | |
107 | ||
7cabd57c | 108 | #ifdef HAVE_MMAP |
24906b43 RM |
109 | /* Now we are ready to load the file. If mmap() is available we try |
110 | this first. If not available or it failed we try to load it. */ | |
dfd2257a | 111 | data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, |
24906b43 RM |
112 | MAP_PRIVATE, fd, 0); |
113 | ||
114 | if (data != (struct mo_file_header *) -1) | |
115 | { | |
116 | /* mmap() call was successful. */ | |
117 | close (fd); | |
118 | use_mmap = 1; | |
119 | } | |
120 | #endif | |
121 | ||
122 | /* If the data is not yet available (i.e. mmap'ed) we try to load | |
123 | it manually. */ | |
124 | if (data == (struct mo_file_header *) -1) | |
125 | { | |
dfd2257a | 126 | size_t to_read; |
24906b43 RM |
127 | char *read_ptr; |
128 | ||
dfd2257a | 129 | data = (struct mo_file_header *) malloc (size); |
24906b43 RM |
130 | if (data == NULL) |
131 | return; | |
132 | ||
dfd2257a | 133 | to_read = size; |
24906b43 RM |
134 | read_ptr = (char *) data; |
135 | do | |
136 | { | |
137 | long int nb = (long int) read (fd, read_ptr, to_read); | |
138 | if (nb == -1) | |
139 | { | |
140 | close (fd); | |
141 | return; | |
142 | } | |
143 | ||
144 | read_ptr += nb; | |
145 | to_read -= nb; | |
146 | } | |
147 | while (to_read > 0); | |
148 | ||
149 | close (fd); | |
150 | } | |
151 | ||
152 | /* Using the magic number we can test whether it really is a message | |
153 | catalog file. */ | |
154 | if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED) | |
155 | { | |
156 | /* The magic number is wrong: not a message catalog file. */ | |
7cabd57c | 157 | #ifdef HAVE_MMAP |
24906b43 | 158 | if (use_mmap) |
dfd2257a | 159 | munmap ((caddr_t) data, size); |
24906b43 RM |
160 | else |
161 | #endif | |
162 | free (data); | |
163 | return; | |
164 | } | |
165 | ||
7a12c6bb | 166 | domain_file->data |
5f2eab42 | 167 | = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); |
59dd8641 | 168 | if (domain_file->data == NULL) |
7a12c6bb RM |
169 | return; |
170 | ||
171 | domain = (struct loaded_domain *) domain_file->data; | |
24906b43 | 172 | domain->data = (char *) data; |
a5a0310d | 173 | domain->use_mmap = use_mmap; |
dfd2257a | 174 | domain->mmap_size = size; |
24906b43 RM |
175 | domain->must_swap = data->magic != _MAGIC; |
176 | ||
177 | /* Fill in the information about the available tables. */ | |
178 | switch (W (domain->must_swap, data->revision)) | |
179 | { | |
180 | case 0: | |
181 | domain->nstrings = W (domain->must_swap, data->nstrings); | |
182 | domain->orig_tab = (struct string_desc *) | |
183 | ((char *) data + W (domain->must_swap, data->orig_tab_offset)); | |
184 | domain->trans_tab = (struct string_desc *) | |
185 | ((char *) data + W (domain->must_swap, data->trans_tab_offset)); | |
186 | domain->hash_size = W (domain->must_swap, data->hash_tab_size); | |
187 | domain->hash_tab = (nls_uint32 *) | |
188 | ((char *) data + W (domain->must_swap, data->hash_tab_offset)); | |
189 | break; | |
190 | default: | |
7cabd57c UD |
191 | /* This is an invalid revision. */ |
192 | #ifdef HAVE_MMAP | |
24906b43 | 193 | if (use_mmap) |
dfd2257a | 194 | munmap ((caddr_t) data, size); |
24906b43 RM |
195 | else |
196 | #endif | |
197 | free (data); | |
7a12c6bb RM |
198 | free (domain); |
199 | domain_file->data = NULL; | |
24906b43 RM |
200 | return; |
201 | } | |
202 | ||
203 | /* Show that one domain is changed. This might make some cached | |
7a12c6bb | 204 | translations invalid. */ |
24906b43 RM |
205 | ++_nl_msg_cat_cntr; |
206 | } | |
a5a0310d UD |
207 | |
208 | ||
209 | #ifdef _LIBC | |
210 | void | |
d0fc4041 | 211 | internal_function |
a5a0310d UD |
212 | _nl_unload_domain (domain) |
213 | struct loaded_domain *domain; | |
214 | { | |
7cabd57c | 215 | #ifdef _POSIX_MAPPED_FILES |
a5a0310d UD |
216 | if (domain->use_mmap) |
217 | munmap ((caddr_t) domain->data, domain->mmap_size); | |
218 | else | |
7cabd57c | 219 | #endif /* _POSIX_MAPPED_FILES */ |
a5a0310d UD |
220 | free ((void *) domain->data); |
221 | ||
222 | free (domain); | |
223 | } | |
224 | #endif |