aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog88
-rw-r--r--inet/rexec.c1
-rw-r--r--locale/C-address.c1
-rw-r--r--locale/C-collate.c1
-rw-r--r--locale/C-ctype.c1
-rw-r--r--locale/C-identification.c1
-rw-r--r--locale/C-measurement.c1
-rw-r--r--locale/C-messages.c1
-rw-r--r--locale/C-monetary.c1
-rw-r--r--locale/C-name.c1
-rw-r--r--locale/C-numeric.c1
-rw-r--r--locale/C-paper.c1
-rw-r--r--locale/C-telephone.c1
-rw-r--r--locale/C-time.c1
-rw-r--r--locale/Makefile4
-rw-r--r--locale/findlocale.c21
-rw-r--r--locale/hashval.h3
-rw-r--r--locale/loadarchive.c447
-rw-r--r--locale/loadlocale.c188
-rw-r--r--locale/localeinfo.h52
-rw-r--r--locale/newlocale.c17
-rw-r--r--locale/programs/localedef.c8
-rw-r--r--locale/programs/localedef.h1
-rw-r--r--locale/programs/locarchive.c416
-rw-r--r--locale/setlocale.c16
-rw-r--r--misc/err.c4
-rw-r--r--signal/allocrtsig.c4
-rw-r--r--sysdeps/generic/morecore.c1
28 files changed, 1085 insertions, 198 deletions
diff --git a/ChangeLog b/ChangeLog
index 15af2f314b..9464fc0610 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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