diff options
author | Roland McGrath <roland@gnu.org> | 1995-09-28 18:42:29 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1995-09-28 18:42:29 +0000 |
commit | 24906b43b9bd9108aef17d18dfbb8764212085f7 (patch) | |
tree | 48d641dc176c9941b3b036e66c383b00a6974bad /intl/loadmsgcat.c | |
parent | 91f62ce6b5797f04006ac5aff08416ecd61bf972 (diff) | |
download | glibc-24906b43b9bd9108aef17d18dfbb8764212085f7.zip glibc-24906b43b9bd9108aef17d18dfbb8764212085f7.tar.gz glibc-24906b43b9bd9108aef17d18dfbb8764212085f7.tar.bz2 |
Thu Sep 28 13:05:54 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
Merge new message handling code from GNU gettext, by Drepper.
* intl: New directory.
* Makefile (subdirs): Add intl.
* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Return
USER_ENTRY instead of storing it on our stack.
* elf/rtld.c (rtld_command): Variable removed.
(_dl_skip_args): New variable.
(dl_main): Increment _dl_skip_args instead of setting rtld_command.
If the link_map for the executable itself is not first in the chain,
make it so.
* sysdeps/i386/dl-machine.h (RTLD_START): Use _dl_skip_args as
count of args to skip.
Thu Sep 28 09:20:04 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
* stdlib/strtod.c (STRTOF): Fix handling of numbers with lots of
leading zeroes.
Diffstat (limited to 'intl/loadmsgcat.c')
-rw-r--r-- | intl/loadmsgcat.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c new file mode 100644 index 0000000..b05c630 --- /dev/null +++ b/intl/loadmsgcat.c @@ -0,0 +1,184 @@ +/* loadmsgcat.c -- load needed message catalogs + Copyright (C) 1995 Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> + +#if defined STDC_HEADERS || defined _LIBC +# include <stdlib.h> +#endif + +#if defined HAVE_UNISTD_H || defined _LIBC +# include <unistd.h> +#endif + +#if (defined HAVE_MMAP && defined HAVE_MUNMAP) || defined _LIBC +# include <sys/mman.h> +#endif + +#include "gettext.h" +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# define fstat __fstat +# define open __open +# define close __close +# define read __read +# define mmap __mmap +# define munmap __munmap +#endif + +/* We need a sign, whether a new catalog was loaded, which can be associated + with all translations. This is important if the translations are + cached by one of GCC's features. */ +int _nl_msg_cat_cntr; + + +/* Load the message catalogs specified by FILENAME. If it is no valid + message catalog do nothing. */ +void +_nl_load_domain (domain) + struct loaded_domain *domain; +{ + int fd; + struct stat st; + struct mo_file_header *data = (struct mo_file_header *) -1; +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || defined _LIBC + int use_mmap = 0; +#endif + + domain->decided = 1; + domain->data = NULL; + + /* Try to open the addressed file. */ + fd = open (domain->filename, O_RDONLY); + if (fd == -1) + return; + + /* We must know about the size of the file. */ + if (fstat (fd, &st) != 0 + && st.st_size < (off_t) sizeof (struct mo_file_header)) + { + /* Something went wrong. */ + close (fd); + return; + } + +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || defined _LIBC + /* Now we are ready to load the file. If mmap() is available we try + this first. If not available or it failed we try to load it. */ + data = (struct mo_file_header *) mmap (NULL, st.st_size, PROT_READ, + MAP_PRIVATE, fd, 0); + + if (data != (struct mo_file_header *) -1) + { + /* mmap() call was successful. */ + close (fd); + use_mmap = 1; + } +#endif + + /* If the data is not yet available (i.e. mmap'ed) we try to load + it manually. */ + if (data == (struct mo_file_header *) -1) + { + off_t to_read; + char *read_ptr; + + data = (struct mo_file_header *) malloc (st.st_size); + if (data == NULL) + return; + + to_read = st.st_size; + read_ptr = (char *) data; + do + { + long int nb = (long int) read (fd, read_ptr, to_read); + if (nb == -1) + { + close (fd); + return; + } + + read_ptr += nb; + to_read -= nb; + } + while (to_read > 0); + + close (fd); + } + + /* Using the magic number we can test whether it really is a message + catalog file. */ + if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED) + { + /* The magic number is wrong: not a message catalog file. */ +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || defined _LIBC + if (use_mmap) + munmap ((caddr_t) data, st.st_size); + else +#endif + free (data); + return; + } + + domain->data = (char *) data; + domain->must_swap = data->magic != _MAGIC; + + /* Fill in the information about the available tables. */ + switch (W (domain->must_swap, data->revision)) + { + case 0: + domain->nstrings = W (domain->must_swap, data->nstrings); + domain->orig_tab = (struct string_desc *) + ((char *) data + W (domain->must_swap, data->orig_tab_offset)); + domain->trans_tab = (struct string_desc *) + ((char *) data + W (domain->must_swap, data->trans_tab_offset)); + domain->hash_size = W (domain->must_swap, data->hash_tab_size); + domain->hash_tab = (nls_uint32 *) + ((char *) data + W (domain->must_swap, data->hash_tab_offset)); + break; + default: + /* This is an illegal revision. */ +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || defined _LIBC + if (use_mmap) + munmap ((caddr_t) data, st.st_size); + else +#endif + free (data); + domain->data = NULL; + return; + } + + /* Show that one domain is changed. This might make some cached + translation invalid. */ + ++_nl_msg_cat_cntr; +} |