diff options
| -rw-r--r-- | ChangeLog | 88 | ||||
| -rw-r--r-- | inet/rexec.c | 1 | ||||
| -rw-r--r-- | locale/C-address.c | 1 | ||||
| -rw-r--r-- | locale/C-collate.c | 1 | ||||
| -rw-r--r-- | locale/C-ctype.c | 1 | ||||
| -rw-r--r-- | locale/C-identification.c | 1 | ||||
| -rw-r--r-- | locale/C-measurement.c | 1 | ||||
| -rw-r--r-- | locale/C-messages.c | 1 | ||||
| -rw-r--r-- | locale/C-monetary.c | 1 | ||||
| -rw-r--r-- | locale/C-name.c | 1 | ||||
| -rw-r--r-- | locale/C-numeric.c | 1 | ||||
| -rw-r--r-- | locale/C-paper.c | 1 | ||||
| -rw-r--r-- | locale/C-telephone.c | 1 | ||||
| -rw-r--r-- | locale/C-time.c | 1 | ||||
| -rw-r--r-- | locale/Makefile | 4 | ||||
| -rw-r--r-- | locale/findlocale.c | 21 | ||||
| -rw-r--r-- | locale/hashval.h | 3 | ||||
| -rw-r--r-- | locale/loadarchive.c | 447 | ||||
| -rw-r--r-- | locale/loadlocale.c | 188 | ||||
| -rw-r--r-- | locale/localeinfo.h | 52 | ||||
| -rw-r--r-- | locale/newlocale.c | 17 | ||||
| -rw-r--r-- | locale/programs/localedef.c | 8 | ||||
| -rw-r--r-- | locale/programs/localedef.h | 1 | ||||
| -rw-r--r-- | locale/programs/locarchive.c | 416 | ||||
| -rw-r--r-- | locale/setlocale.c | 16 | ||||
| -rw-r--r-- | misc/err.c | 4 | ||||
| -rw-r--r-- | signal/allocrtsig.c | 4 | ||||
| -rw-r--r-- | sysdeps/generic/morecore.c | 1 |
28 files changed, 1085 insertions, 198 deletions
@@ -1,3 +1,91 @@ +2002-08-09 Roland McGrath <roland@redhat.com> + + * locale/loadarchive.c (_nl_load_locale_from_archive): Parse locale + name to find codeset name (if any) and normalize it. If the + normalized name differs, look up only that in the archive. + * locale/programs/locarchive.c (add_locale_to_archive): If the name + contains a codeset, normalize the codeset store only the normalized + name in the archive. If not, add an alias containing the locale's + normalized codeset name. Apply codeset name normalization when + matching entries in the alias file. + + * locale/programs/locarchive.c (delete_locales_from_archive): Don't + decrement HEAD->namehash_used here. + (add_locale): Only need to insert name string when name_offset != 0. + + * locale/programs/localedef.c (options): Add -A/--alias-file. + (alias_file): New variable. + (parse_opt): Grok -A, set that. + * locale/programs/localedef.h: Declare it. + + * locale/programs/locarchive.c (insert_name): New function, broken out + of ... + (add_locale_to_archive): ... here. Call that. + (add_alias): New function. + (add_locale): New static function, add_locale_to_archive renamed. + (add_locale_to_archive): Call that and use add_alias to add an alias + for the name with codeset if the given name lacks it. + (enlarge_archive): Call add_locale instead of add_locale_to_archive. + + * locale/Makefile (routines): Add loadarchive. + * locale/loadarchive.c: New file, started from code by Ulrich Drepper. + (_nl_load_locale_from_archive): New function. + * locale/localeinfo.h: Declare it. + * locale/findlocale.c (_nl_find_locale): If using default locale path, + try _nl_load_locale_from_archive first. + + * locale/loadlocale.c (_nl_intern_locale_data): New function, + broken out of _nl_load_locale. + (_nl_load_locale): Call that. + * locale/localeinfo.h: Declare it. + (struct locale_data): Replace member `mmaped' with `alloc', an enum. + (struct locale_data): Remove unused member `options'. + * locale/findlocale.c (_nl_remove_locale): Update uses. + * locale/loadlocale.c (_nl_load_locale, _nl_unload_locale): Likewise. + * locale/C-collate.c: Update initializer. + * locale/C-identification.c: Likewise. + * locale/C-measurement.c: Likewise. + * locale/C-telephone.c: Likewise. + * locale/C-address.c: Likewise. + * locale/C-name.c: Likewise. + * locale/C-paper.c: Likewise. + * locale/C-time.c: Likewise. + * locale/C-numeric.c: Likewise. + * locale/C-monetary.c: Likewise. + * locale/C-messages.c : Likewise. + * locale/C-ctype.c: Likewise. + + * locale/hashval.h [! LONGBITS]: Include <limits.h> here and + use CHAR_BIT instead of BITSPERBYTE. + + * locale/localeinfo.h (_nl_find_locale, _nl_load_locale, + _nl_unload_locale): Add `internal_function attribute_hidden' to decls. + * locale/findlocale.c (_nl_find_locale): Add internal_function to defn. + (_nl_remove_locale): Likewise. + * locale/loadlocale.c (_nl_load_locale, _nl_unload_locale): Likewise. + + * locale/findlocale.c (_nl_default_locale_path): New variable. + (_nl_find_locale): If LOCALE_PATH is null, default to that. + * locale/localeinfo.h: Declare it. + * locale/setlocale.c (setlocale): Use _nl_default_locale_path + in place of LOCALEDIR. If no LOCPATH, pass null to _nl_find_locale. + * locale/newlocale.c (__newlocale): Likewise. + + * misc/err.c (vwarnx, vwarn): Fix typos in libc_hidden_def uses. + * inet/rexec.c (rexec_af): Add libc_hidden_def. + * sysdeps/generic/morecore.c: Likewise. + * signal/allocrtsig.c (__libc_current_sigrtmin): Likewise. + (__libc_current_sigrtmax): Likewise. + +2002-08-08 Roland McGrath <roland@redhat.com> + + * locale/loadlocale.c (_nl_load_locale): Don't use MAP_INHERIT. + * catgets/open_catalog.c (__open_catalog): Likewise. + + * locale/programs/locarchive.c (INITIAL_NUM_NAMES): Renamed + from typo INITIAL_NUM_NANES. + (create_archive): Update use. + 2002-08-08 Ulrich Drepper <drepper@redhat.com> * sysdeps/unix/sysv/linux/sigwait.c: New file. diff --git a/inet/rexec.c b/inet/rexec.c index e8ecf79c54..8f6190a834 100644 --- a/inet/rexec.c +++ b/inet/rexec.c @@ -177,6 +177,7 @@ bad: freeaddrinfo(res0); return (-1); } +libc_hidden_def (rexec_af) int rexec(ahost, rport, name, pass, cmd, fd2p) diff --git a/locale/C-address.c b/locale/C-address.c index 12c9dde8d7..78b5a28468 100644 --- a/locale/C-address.c +++ b/locale/C-address.c @@ -30,7 +30,6 @@ const struct locale_data _nl_C_LC_ADDRESS attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 13, { { string: "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N" }, diff --git a/locale/C-collate.c b/locale/C-collate.c index 0f31b08d10..f6db63feb7 100644 --- a/locale/C-collate.c +++ b/locale/C-collate.c @@ -104,7 +104,6 @@ const struct locale_data _nl_C_LC_COLLATE attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 19, { /* _NL_COLLATE_NRULES */ diff --git a/locale/C-ctype.c b/locale/C-ctype.c index 3dcd5fe121..57234844ce 100644 --- a/locale/C-ctype.c +++ b/locale/C-ctype.c @@ -544,7 +544,6 @@ const struct locale_data _nl_C_LC_CTYPE attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 1, /* Enable transliteration by default. */ - NULL, NR_FIXED + NR_CLASSES + NR_MAPS, { /* _NL_CTYPE_CLASS */ diff --git a/locale/C-identification.c b/locale/C-identification.c index c2fd478289..542b33ccaf 100644 --- a/locale/C-identification.c +++ b/locale/C-identification.c @@ -30,7 +30,6 @@ const struct locale_data _nl_C_LC_IDENTIFICATION attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 16, { { string: "ISO/IEC 14652 i18n FDCC-set" }, diff --git a/locale/C-measurement.c b/locale/C-measurement.c index 590432146f..0a9c9831af 100644 --- a/locale/C-measurement.c +++ b/locale/C-measurement.c @@ -30,7 +30,6 @@ const struct locale_data _nl_C_LC_MEASUREMENT attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 2, { { string: "\1" }, diff --git a/locale/C-messages.c b/locale/C-messages.c index a118398394..f446e3dda6 100644 --- a/locale/C-messages.c +++ b/locale/C-messages.c @@ -30,7 +30,6 @@ const struct locale_data _nl_C_LC_MESSAGES attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 5, { { string: "^[yY]" }, diff --git a/locale/C-monetary.c b/locale/C-monetary.c index 0c91145f5c..643a1c4198 100644 --- a/locale/C-monetary.c +++ b/locale/C-monetary.c @@ -34,7 +34,6 @@ const struct locale_data _nl_C_LC_MONETARY attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 46, { { string: "" }, diff --git a/locale/C-name.c b/locale/C-name.c index 8526ec076f..7e714b3a37 100644 --- a/locale/C-name.c +++ b/locale/C-name.c @@ -30,7 +30,6 @@ const struct locale_data _nl_C_LC_NAME attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 7, { { string: "%p%t%g%t%m%t%f" }, diff --git a/locale/C-numeric.c b/locale/C-numeric.c index 3c096c6479..1171a4b973 100644 --- a/locale/C-numeric.c +++ b/locale/C-numeric.c @@ -27,7 +27,6 @@ const struct locale_data _nl_C_LC_NUMERIC attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 6, { { string: "." }, diff --git a/locale/C-paper.c b/locale/C-paper.c index fb3e619ad3..62d1a7dec7 100644 --- a/locale/C-paper.c +++ b/locale/C-paper.c @@ -30,7 +30,6 @@ const struct locale_data _nl_C_LC_PAPER attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 3, { { word: 297 }, diff --git a/locale/C-telephone.c b/locale/C-telephone.c index 795de3c1f3..abd667ea8a 100644 --- a/locale/C-telephone.c +++ b/locale/C-telephone.c @@ -30,7 +30,6 @@ const struct locale_data _nl_C_LC_TELEPHONE attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 5, { { string: "+%c %a %l" }, diff --git a/locale/C-time.c b/locale/C-time.c index 9ce133a6ce..b50fea57b9 100644 --- a/locale/C-time.c +++ b/locale/C-time.c @@ -29,7 +29,6 @@ const struct locale_data _nl_C_LC_TIME attribute_hidden = NULL, 0, 0, /* no file mapped */ UNDELETABLE, 0, - NULL, 111, { { string: "Sun" }, diff --git a/locale/Makefile b/locale/Makefile index d3c62adc07..9509c1f7f7 100644 --- a/locale/Makefile +++ b/locale/Makefile @@ -35,8 +35,8 @@ distribute = localeinfo.h categories.def iso-639.def iso-3166.def \ locfile-kw.gperf locfile-kw.h linereader.h \ locfile.h charmap.h repertoire.h localedef.h \ 3level.h charmap-dir.h locarchive.c) -routines = setlocale findlocale loadlocale localeconv nl_langinfo \ - nl_langinfo_l mb_cur_max \ +routines = setlocale findlocale loadlocale loadarchive \ + localeconv nl_langinfo nl_langinfo_l mb_cur_max \ newlocale duplocale freelocale uselocale tests = tst-C-locale categories = ctype messages monetary numeric time paper name \ diff --git a/locale/findlocale.c b/locale/findlocale.c index 75784bab9f..80480113c0 100644 --- a/locale/findlocale.c +++ b/locale/findlocale.c @@ -42,8 +42,11 @@ extern struct locale_data *const _nl_C[] attribute_hidden; which are somehow addressed. */ struct loaded_l10nfile *_nl_locale_file_list[__LC_LAST]; +const char _nl_default_locale_path[] attribute_hidden = LOCALEDIR; + struct locale_data * +internal_function _nl_find_locale (const char *locale_path, size_t locale_path_len, int category, const char **name) { @@ -82,6 +85,19 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len, return _nl_C[category]; } + /* We really have to load some data. First we try the archive, + but only if there was no LOCPATH environment variable specified. */ + if (__builtin_expect (locale_path == NULL, 1)) + { + struct locale_data *data = _nl_load_locale_from_archive (category, name); + if (__builtin_expect (data != NULL, 1)) + return data; + + /* Nothing in the archive. Set the default path to search below. */ + locale_path = _nl_default_locale_path; + locale_path_len = sizeof _nl_default_locale_path; + } + /* We really have to load some data. First see whether the name is an alias. Please note that this makes it impossible to have "C" or "POSIX" as aliases. */ @@ -99,7 +115,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len, Beside the first all of them are allowed to be missing. If the full specified locale is not found, the less specific one are - looked for. The various part will be stripped of according to + looked for. The various part will be stripped off according to the following order: (1) codeset (2) normalized codeset @@ -236,6 +252,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len, /* Calling this function assumes the lock for handling global locale data is acquired. */ void +internal_function _nl_remove_locale (int locale, struct locale_data *data) { if (--data->usage_count == 0) @@ -258,7 +275,7 @@ _nl_remove_locale (int locale, struct locale_data *data) #ifdef _POSIX_MAPPED_FILES /* Really delete the data. First delete the real data. */ - if (__builtin_expect (data->mmaped, 1)) + if (__builtin_expect (data->alloc == ld_mapped, 1)) { /* Try to unmap the area. If this fails we mark the area as permanent. */ diff --git a/locale/hashval.h b/locale/hashval.h index e35957dde3..f846cdfb27 100644 --- a/locale/hashval.h +++ b/locale/hashval.h @@ -19,7 +19,8 @@ 02111-1307 USA. */ #ifndef LONGBITS -# define LONGBITS (sizeof (long int) * BITSPERBYTE) +# include <limits.h> +# define LONGBITS (sizeof (long int) * CHAR_BIT) #endif unsigned long int compute_hashval (const void *key, size_t keylen); diff --git a/locale/loadarchive.c b/locale/loadarchive.c new file mode 100644 index 0000000000..08e5f94905 --- /dev/null +++ b/locale/loadarchive.c @@ -0,0 +1,447 @@ +/* Code to load locale data from the locale archive file. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <locale.h> +#include <stddef.h> +#include <stdbool.h> +#include <errno.h> +#include <assert.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/param.h> + +#include "localeinfo.h" +#include "locarchive.h" + +/* Define the hash function. We define the function as static inline. */ +#define compute_hashval static inline compute_hashval +#include "hashval.h" +#undef compute_hashval + +#undef LOCALEDIR +#define LOCALEDIR "/spare/roland/tmp/usr/lib/locale/" + +/* Name of the locale archive file. */ +static const char archfname[] = LOCALEDIR "locale-archive"; + + +/* Record of contiguous pages already mapped from the locale archive. */ +struct archmapped +{ + void *ptr; + uint32_t from; + uint32_t len; + struct archmapped *next; +}; +static struct archmapped *archmapped; + +/* This describes the mapping at the beginning of the file that contains + the header data. There could be data in the following partial page, + so this is searched like any other. Once the archive has been used, + ARCHMAPPED points to this; if mapping the archive header failed, + then headmap.ptr is null. */ +static struct archmapped headmap; +static struct stat64 archive_stat; /* stat of archive when header mapped. */ + +/* Record of locales that we have already loaded from the archive. */ +struct locale_in_archive +{ + struct locale_in_archive *next; + const char *name; + struct locale_data *data[__LC_LAST]; +}; +static struct locale_in_archive *archloaded; + + +/* Local structure and subroutine of _nl_load_archive, see below. */ +struct range +{ + uint32_t from; + uint32_t len; + int category; + void *result; +}; + +static int +rangecmp (const void *p1, const void *p2) +{ + return ((struct range *) p1)->from - ((struct range *) p2)->from; +} + + +/* Calculate the amount of space needed for all the tables described + by the given header. Note we do not include the empty table space + that has been preallocated in the file, so our mapping may not be + large enough if localedef adds data to the file in place. However, + doing that would permute the header fields while we are accessing + them and thus not be safe anyway, so we don't allow for that. */ +static inline off_t +calculate_head_size (const struct locarhead *h) +{ + off_t namehash_end = (h->namehash_offset + + h->namehash_size * sizeof (struct namehashent)); + off_t string_end = h->string_offset + h->string_used; + off_t locrectab_end = (h->locrectab_offset + + h->locrectab_used * sizeof (struct locrecent)); + return MAX (namehash_end, MAX (string_end, locrectab_end)); +} + + +/* Find the locale *NAMEP in the locale archive, and return the + internalized data structure for its CATEGORY data. If this locale has + already been loaded from the archive, just returns the existing data + structure. If successful, sets *NAMEP to point directly into the mapped + archive string table; that way, the next call can short-circuit strcmp. */ +struct locale_data * +internal_function +_nl_load_locale_from_archive (int category, const char **namep) +{ + const char *name = *namep; + struct + { + void *addr; + size_t len; + } results[__LC_LAST]; + struct locale_in_archive *lia; + struct locarhead *head; + struct namehashent *namehashtab; + struct locrecent *locrec; + struct archmapped *mapped; + struct archmapped *last; + unsigned long int hval; + size_t idx; + size_t incr; + struct range ranges[__LC_LAST - 1]; + int nranges; + int cnt; + size_t ps = __sysconf (_SC_PAGE_SIZE); + int fd = -1; + + /* Check if we have already loaded this locale from the archive. + If we previously loaded the locale but found bogons in the data, + then we will have stored a null pointer to return here. */ + for (lia = archloaded; lia != NULL; lia = lia->next) + if (name == lia->name || !strcmp (name, lia->name)) + { + *namep = lia->n |
