2001-09-01  Ulrich Drepper  <drepper@redhat.com>

	* iconv/gconv_cache.c: Rename variable cache to __gconv_cache and
	export it.
	* iconv/Versions (libc) [GLIBC_2.2.5]: Export __gconv_cache.
	* iconv/iconv_prog.c (insert_cache): New function.
	(print_known_names): If cache is used call insert_cache to use the
	information from the cache [PR libc/2509].
This commit is contained in:
Ulrich Drepper 2001-09-01 19:03:22 +00:00
parent 45e0579fb7
commit 9a1f71a723
4 changed files with 81 additions and 29 deletions

View File

@ -1,3 +1,12 @@
2001-09-01 Ulrich Drepper <drepper@redhat.com>
* iconv/gconv_cache.c: Rename variable cache to __gconv_cache and
export it.
* iconv/Versions (libc) [GLIBC_2.2.5]: Export __gconv_cache.
* iconv/iconv_prog.c (insert_cache): New function.
(print_known_names): If cache is used call insert_cache to use the
information from the cache [PR libc/2509].
2001-08-31 Ulrich Drepper <drepper@redhat.com> 2001-08-31 Ulrich Drepper <drepper@redhat.com>
* time/strptime.c (strptime_internal): Recognize 'l' format and * time/strptime.c (strptime_internal): Recognize 'l' format and

View File

@ -6,4 +6,8 @@ libc {
# i* # i*
iconv_open; iconv; iconv_close; iconv_open; iconv; iconv_close;
} }
GLIBC_2.2.5 {
# variable shared with iconv program
__gconv_cache;
}
} }

View File

@ -31,7 +31,7 @@
#include "../intl/hash-string.h" #include "../intl/hash-string.h"
static void *cache; void *__gconv_cache;
static size_t cache_size; static size_t cache_size;
static int cache_malloced; static int cache_malloced;
@ -70,25 +70,25 @@ __gconv_load_cache (void)
/* Make the file content available. */ /* Make the file content available. */
cache_size = st.st_size; cache_size = st.st_size;
#ifdef _POSIX_MAPPED_FILES #ifdef _POSIX_MAPPED_FILES
cache = __mmap (NULL, cache_size, PROT_READ, MAP_SHARED, fd, 0); __gconv_cache = __mmap (NULL, cache_size, PROT_READ, MAP_SHARED, fd, 0);
if (__builtin_expect (cache == MAP_FAILED, 0)) if (__builtin_expect (__gconv_cache == MAP_FAILED, 0))
#endif #endif
{ {
size_t already_read; size_t already_read;
cache = malloc (cache_size); __gconv_cache = malloc (cache_size);
if (cache == NULL) if (__gconv_cache == NULL)
goto close_and_exit; goto close_and_exit;
already_read = 0; already_read = 0;
do do
{ {
ssize_t n = __read (fd, (char *) cache + already_read, ssize_t n = __read (fd, (char *) __gconv_cache + already_read,
cache_size - already_read); cache_size - already_read);
if (__builtin_expect (n, 0) == -1) if (__builtin_expect (n, 0) == -1)
{ {
free (cache); free (__gconv_cache);
cache = NULL; __gconv_cache = NULL;
goto close_and_exit; goto close_and_exit;
} }
@ -103,7 +103,7 @@ __gconv_load_cache (void)
__close (fd); __close (fd);
/* Check the consistency. */ /* Check the consistency. */
header = (struct gconvcache_header *) cache; header = (struct gconvcache_header *) __gconv_cache;
if (__builtin_expect (header->magic, GCONVCACHE_MAGIC) != GCONVCACHE_MAGIC if (__builtin_expect (header->magic, GCONVCACHE_MAGIC) != GCONVCACHE_MAGIC
|| __builtin_expect (header->string_offset >= cache_size, 0) || __builtin_expect (header->string_offset >= cache_size, 0)
|| __builtin_expect (header->hash_offset >= cache_size, 0) || __builtin_expect (header->hash_offset >= cache_size, 0)
@ -116,14 +116,14 @@ __gconv_load_cache (void)
{ {
if (cache_malloced) if (cache_malloced)
{ {
free (cache); free (__gconv_cache);
cache_malloced = 0; cache_malloced = 0;
} }
#ifdef _POSIX_MAPPED_FILES #ifdef _POSIX_MAPPED_FILES
else else
__munmap (cache, cache_size); __munmap (__gconv_cache, cache_size);
#endif #endif
cache = NULL; __gconv_cache = NULL;
return -1; return -1;
} }
@ -145,9 +145,10 @@ find_module_idx (const char *str, size_t *idxp)
const struct hash_entry *hashtab; const struct hash_entry *hashtab;
unsigned int limit; unsigned int limit;
header = (const struct gconvcache_header *) cache; header = (const struct gconvcache_header *) __gconv_cache;
strtab = (char *) cache + header->string_offset; strtab = (char *) __gconv_cache + header->string_offset;
hashtab = (struct hash_entry *) ((char *) cache + header->hash_offset); hashtab = (struct hash_entry *) ((char *) __gconv_cache
+ header->hash_offset);
hval = hash_string (str); hval = hash_string (str);
idx = hval % header->hash_size; idx = hval % header->hash_size;
@ -210,7 +211,7 @@ __gconv_compare_alias_cache (const char *name1, const char *name2, int *result)
size_t name1_idx; size_t name1_idx;
size_t name2_idx; size_t name2_idx;
if (cache == NULL) if (__gconv_cache == NULL)
return -1; return -1;
if (find_module_idx (name1, &name1_idx) != 0 if (find_module_idx (name1, &name1_idx) != 0
@ -237,13 +238,13 @@ __gconv_lookup_cache (const char *toset, const char *fromset,
const struct module_entry *to_module; const struct module_entry *to_module;
struct __gconv_step *result; struct __gconv_step *result;
if (cache == NULL) if (__gconv_cache == NULL)
/* We have no cache available. */ /* We have no cache available. */
return __GCONV_NODB; return __GCONV_NODB;
header = (const struct gconvcache_header *) cache; header = (const struct gconvcache_header *) __gconv_cache;
strtab = (char *) cache + header->string_offset; strtab = (char *) __gconv_cache + header->string_offset;
modtab = (const struct module_entry *) ((char *) cache modtab = (const struct module_entry *) ((char *) __gconv_cache
+ header->module_offset); + header->module_offset);
if (find_module_idx (fromset, &fromidx) != 0 if (find_module_idx (fromset, &fromidx) != 0
@ -272,7 +273,7 @@ __gconv_lookup_cache (const char *toset, const char *fromset,
/* Note the -1. This is due to the offset added in iconvconfig. /* Note the -1. This is due to the offset added in iconvconfig.
See there for more explanations. */ See there for more explanations. */
extra = (const struct extra_entry *) ((char *) cache extra = (const struct extra_entry *) ((char *) __gconv_cache
+ header->otherconv_offset + header->otherconv_offset
+ from_module->extra_offset - 1); + from_module->extra_offset - 1);
while (extra->module_cnt != 0 while (extra->module_cnt != 0
@ -429,7 +430,7 @@ void
internal_function internal_function
__gconv_release_cache (struct __gconv_step *steps, size_t nsteps) __gconv_release_cache (struct __gconv_step *steps, size_t nsteps)
{ {
if (cache != NULL) if (__gconv_cache != NULL)
/* The only thing we have to deallocate is the record with the /* The only thing we have to deallocate is the record with the
steps. */ steps. */
free (steps); free (steps);
@ -441,10 +442,10 @@ static void __attribute__ ((unused))
free_mem (void) free_mem (void)
{ {
if (cache_malloced) if (cache_malloced)
free (cache); free (__gconv_cache);
#ifdef _POSIX_MAPPED_FILES #ifdef _POSIX_MAPPED_FILES
else else
__munmap (cache, cache_size); __munmap (__gconv_cache, cache_size);
#endif #endif
} }

View File

@ -39,6 +39,7 @@
#include <charmap.h> #include <charmap.h>
#include <gconv_int.h> #include <gconv_int.h>
#include "iconv_prog.h" #include "iconv_prog.h"
#include "iconvconfig.h"
/* Get libc version number. */ /* Get libc version number. */
#include "../version.h" #include "../version.h"
@ -46,6 +47,9 @@
#define PACKAGE _libc_intl_domainname #define PACKAGE _libc_intl_domainname
/* Defined in gconv_cache.c. */
extern void *__gconv_cache;
/* Name and version of program. */ /* Name and version of program. */
static void print_version (FILE *stream, struct argp_state *state); static void print_version (FILE *stream, struct argp_state *state);
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
@ -653,7 +657,7 @@ add_known_names (struct gconv_module *node)
if (strcmp (node->from_string, "INTERNAL")) if (strcmp (node->from_string, "INTERNAL"))
tsearch (node->from_string, &printlist, tsearch (node->from_string, &printlist,
(__compar_fn_t) strverscmp); (__compar_fn_t) strverscmp);
if (strcmp (node->to_string, "INTERNAL")) if (strcmp (node->to_string, "INTERNAL") != 0)
tsearch (node->to_string, &printlist, (__compar_fn_t) strverscmp); tsearch (node->to_string, &printlist, (__compar_fn_t) strverscmp);
node = node->same; node = node->same;
@ -661,6 +665,31 @@ add_known_names (struct gconv_module *node)
while (node != NULL); while (node != NULL);
} }
static void
insert_cache (void)
{
const struct gconvcache_header *header;
const char *strtab;
const struct hash_entry *hashtab;
size_t cnt;
header = (const struct gconvcache_header *) __gconv_cache;
strtab = (char *) __gconv_cache + header->string_offset;
hashtab = (struct hash_entry *) ((char *) __gconv_cache
+ header->hash_offset);
for (cnt = 0; cnt < header->hash_size; ++cnt)
if (hashtab[cnt].string_offset != 0)
{
const char *str = strtab + hashtab[cnt].string_offset;
if (strcmp (str, "INTERNAL") != 0)
tsearch (str, &printlist, (__compar_fn_t) strverscmp);
}
}
static void static void
internal_function internal_function
print_known_names (void) print_known_names (void)
@ -671,11 +700,20 @@ print_known_names (void)
h = iconv_open ("L1", "L1"); h = iconv_open ("L1", "L1");
iconv_close (h); iconv_close (h);
/* First add the aliases. */ /* See whether we have a cache. */
twalk (__gconv_alias_db, insert_print_list); if (__gconv_cache != NULL)
/* Yep, use only this information. */
insert_cache ();
else
{
/* No, then use the information read from the gconv-modules file.
First add the aliases. */
twalk (__gconv_alias_db, insert_print_list);
/* Add the from- and to-names from the known modules. */ /* Add the from- and to-names from the known modules. */
add_known_names (__gconv_modules_db); if (__gconv_modules_db != NULL)
add_known_names (__gconv_modules_db);
}
fputs (_("\ fputs (_("\
The following list contain all the coded character sets known. This does\n\ The following list contain all the coded character sets known. This does\n\