refactoring old locale-db(BSDCTYPE) loading method with mmap(2).

This commit is contained in:
tnozaki 2010-06-01 18:00:28 +00:00
parent 9a35d7972b
commit d8217122b9
7 changed files with 173 additions and 178 deletions

View File

@ -1,5 +1,5 @@
# from: @(#)Makefile.inc 5.1 (Berkeley) 2/18/91
# $NetBSD: Makefile.inc,v 1.55 2010/05/30 08:28:53 tnozaki Exp $
# $NetBSD: Makefile.inc,v 1.56 2010/06/01 18:00:28 tnozaki Exp $
# locale sources
.PATH: ${ARCHDIR}/locale ${.CURDIR}/locale
@ -29,7 +29,7 @@ CPPFLAGS+= -UWITH_RUNE
SRCS+= aliasname.c bsdctype.c localeio.c \
multibyte_sb.c iswctype_sb.c \
localeio_lc_ctype.c localeio_lc_monetary.c \
localeio_lc_numeric.c localeio_lc_time.c
localeio_lc_numeric.c localeio_lc_time.c localeio_lc_messages.c
.endif
MAN+= setlocale.3 nl_langinfo.3

View File

@ -1,4 +1,4 @@
/* $NetBSD: bsdctype.c,v 1.4 2010/05/30 08:28:53 tnozaki Exp $ */
/* $NetBSD: bsdctype.c,v 1.5 2010/06/01 18:00:28 tnozaki Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -28,9 +28,19 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: bsdctype.c,v 1.4 2010/05/30 08:28:53 tnozaki Exp $");
__RCSID("$NetBSD: bsdctype.c,v 1.5 2010/06/01 18:00:28 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/stat.h>
#include <sys/mman.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "bsdctype.h"
const _BSDCTypeLocale _DefaultBSDCTypeLocale = {
@ -40,3 +50,130 @@ const _BSDCTypeLocale _DefaultBSDCTypeLocale = {
};
const _BSDCTypeLocale *_CurrentBSDCTypeLocale = &_DefaultBSDCTypeLocale;
typedef struct {
_BSDCTypeLocale bl;
uint8_t blp_ctype_tab [_CTYPE_NUM_CHARS + 1];
int16_t blp_tolower_tab[_CTYPE_NUM_CHARS + 1];
int16_t blp_toupper_tab[_CTYPE_NUM_CHARS + 1];
} _BSDCTypeLocalePriv;
static __inline void
_bsdctype_init_priv(_BSDCTypeLocalePriv *blp)
{
blp->blp_ctype_tab [0] = (uint8_t)0;
blp->blp_tolower_tab[0] = (int16_t)EOF;
blp->blp_toupper_tab[0] = (int16_t)EOF;
blp->bl.bl_ctype_tab = &blp->blp_ctype_tab [0];
blp->bl.bl_tolower_tab = &blp->blp_tolower_tab[0];
blp->bl.bl_toupper_tab = &blp->blp_toupper_tab[0];
}
static __inline int
_bsdctype_read_file(const char * __restrict var, size_t lenvar,
_BSDCTypeLocalePriv * __restrict blp)
{
const _FileBSDCTypeLocale *fbl;
uint32_t value;
int i;
if (lenvar < sizeof(*fbl))
return EFTYPE;
fbl = (const _FileBSDCTypeLocale *)(const void *)var;
if (memcmp(&fbl->fbl_id[0], _CTYPE_ID, sizeof(fbl->fbl_id)))
return EFTYPE;
value = ntohl(fbl->fbl_rev);
if (value != _CTYPE_REV)
return EFTYPE;
value = ntohl(fbl->fbl_num_chars);
if (value != _CTYPE_CACHE_SIZE)
return EFTYPE;
for (i = 0; i < _CTYPE_CACHE_SIZE; ++i) {
blp->blp_ctype_tab [i + 1] = fbl->fbl_ctype_tab[i];
blp->blp_tolower_tab[i + 1] = ntohs(fbl->fbl_tolower_tab[i]);
blp->blp_toupper_tab[i + 1] = ntohs(fbl->fbl_toupper_tab[i]);
}
#if _CTYPE_CACHE_SIZE != _CTYPE_NUM_CHARS
for (i = _CTYPE_CACHE_SIZE; i < _CTYPE_NUM_CHARS; ++i) {
blp->blp_ctype_tab [i + 1] = 0;
blp->blp_tolower_tab[i + 1] = i;
blp->blp_toupper_tab[i + 1] = i;
}
#endif
return 0;
}
static __inline int
_bsdctype_load_priv(const char * __restrict path,
_BSDCTypeLocalePriv * __restrict blp)
{
int fd, ret;
struct stat st;
size_t lenvar;
char *var;
fd = open(path, O_RDONLY);
if (fd == -1)
goto err;
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
goto err;
if (fstat(fd, &st) == -1)
goto err;
if (!S_ISREG(st.st_mode)) {
close(fd);
return EBADF;
}
lenvar = (size_t)st.st_size;
if (lenvar < 1) {
close(fd);
return EFTYPE;
}
var = mmap(NULL, lenvar, PROT_READ,
MAP_FILE|MAP_PRIVATE, fd, (off_t)0);
if (var == MAP_FAILED)
goto err;
if (close(fd) == -1) {
ret = errno;
munmap(var, lenvar);
return ret;
}
switch (*var) {
case 'B':
ret = _bsdctype_read_file(var, lenvar, blp);
break;
default:
ret = EFTYPE;
}
munmap(var, lenvar);
return ret;
err:
ret = errno;
close(fd);
return ret;
}
int
_bsdctype_load(const char * __restrict path,
_BSDCTypeLocale ** __restrict pbl)
{
int sverr, ret;
_BSDCTypeLocalePriv *blp;
sverr = errno;
errno = 0;
blp = malloc(sizeof(*blp));
if (blp == NULL) {
ret = errno;
errno = sverr;
return ret;
}
_bsdctype_init_priv(blp);
ret = _bsdctype_load_priv(path, blp);
if (ret) {
free(blp);
errno = sverr;
return ret;
}
*pbl = &blp->bl;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: bsdctype.h,v 1.3 2010/05/30 08:28:53 tnozaki Exp $ */
/* $NetBSD: bsdctype.h,v 1.4 2010/06/01 18:00:28 tnozaki Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -31,13 +31,26 @@
#include "ctype_local.h"
typedef struct _BSDCTypeLocale {
const unsigned char *ctype_tab;
const short *tolower_tab;
const short *toupper_tab;
typedef struct {
char fbl_id[8];
uint32_t fbl_rev;
uint32_t fbl_num_chars;
uint8_t fbl_ctype_tab [_CTYPE_NUM_CHARS];
int16_t fbl_tolower_tab[_CTYPE_NUM_CHARS];
int16_t fbl_toupper_tab[_CTYPE_NUM_CHARS];
} __packed _FileBSDCTypeLocale;
typedef struct {
const unsigned char *bl_ctype_tab;
const short *bl_tolower_tab;
const short *bl_toupper_tab;
} _BSDCTypeLocale;
extern const _BSDCTypeLocale _DefaultBSDCTypeLocale;
extern const _BSDCTypeLocale *_CurrentBSDCTypeLocale;
__BEGIN_DECLS
int _bsdctype_load(const char * __restrict, _BSDCTypeLocale ** __restrict);
__END_DECLS
#endif /*_BSDCTYPE_H_*/

View File

@ -1,127 +0,0 @@
/* $NetBSD: ctypeio.c,v 1.13 2010/06/01 13:52:08 tnozaki Exp $ */
/*
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: ctypeio.c,v 1.13 2010/06/01 13:52:08 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "bsdctype.h"
#include "ctypeio.h"
int
__loadctype(const char * __restrict path, _BSDCTypeLocale ** __restrict pdata)
{
FILE *fp;
char id[sizeof(_CTYPE_ID) - 1];
uint32_t i, len;
char *ptr;
uint8_t *new_ctype;
int16_t *new_tolower, *new_toupper;
_BSDCTypeLocale *data;
_DIAGASSERT(path != NULL);
_DIAGASSERT(pdata != NULL);
fp = fopen(path, "r");
if (fp == NULL)
return ENOENT;
if (fread(id, sizeof(id), 1, fp) != 1 ||
memcmp(id, _CTYPE_ID, sizeof(id)) != 0)
goto bad0;
if (fread(&i, sizeof(uint32_t), 1, fp) != 1 ||
(i = ntohl(i)) != _CTYPE_REV)
goto bad0;
if (fread(&len, sizeof(uint32_t), 1, fp) != 1 ||
(len = ntohl(len)) != _CTYPE_CACHE_SIZE)
goto bad0;
ptr = malloc(sizeof(*data) + ((sizeof(uint8_t) +
sizeof(int16_t) + sizeof(int16_t)) * (_CTYPE_NUM_CHARS + 1)));
if (ptr == NULL) {
fclose(fp);
return ENOMEM;
}
data = (_BSDCTypeLocale *)(void *)ptr;
ptr += sizeof(*data);
(new_ctype = (void *)ptr)[0] = (uint8_t)0;
ptr += sizeof(uint8_t);
if (fread((void *)ptr, sizeof(uint8_t), len, fp) != len)
goto bad1;
ptr += sizeof(uint8_t) * _CTYPE_NUM_CHARS;
(new_toupper = (void *)ptr)[0] = (int16_t)EOF;
ptr += sizeof(int16_t);
if (fread((void *)ptr, sizeof(int16_t), len, fp) != len)
goto bad1;
ptr += sizeof(int16_t) * _CTYPE_NUM_CHARS;
(new_tolower = (void *)ptr)[0] = (int16_t)EOF;
ptr += sizeof(int16_t);
if (fread((void *)ptr, sizeof(int16_t), len, fp) != len)
goto bad1;
#if BYTE_ORDER == LITTLE_ENDIAN
for (i = 1; i <= len; i++) {
new_toupper[i] = ntohs(new_toupper[i]);
new_tolower[i] = ntohs(new_tolower[i]);
}
#endif
for (i = _CTYPE_CACHE_SIZE + 1; i <= _CTYPE_NUM_CHARS; i++) {
new_ctype[i] = 0;
new_toupper[i] = i;
new_tolower[i] = i;
}
fclose(fp);
data->ctype_tab = (const unsigned char *)new_ctype;
data->toupper_tab = (const short *)new_toupper;
data->tolower_tab = (const short *)new_tolower;
*pdata = data;
return 0;
bad1:
free(data);
bad0:
fclose(fp);
return EFTYPE;
}

View File

@ -1,29 +0,0 @@
/* $NetBSD: ctypeio.h,v 1.4 2009/10/21 01:07:45 snj Exp $ */
/*
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
__BEGIN_DECLS
int __loadctype(const char * __restrict, _BSDCTypeLocale ** __restrict pdata);
__END_DECLS

View File

@ -1,4 +1,4 @@
/* $NetBSD: iswctype_sb.c,v 1.10 2010/06/01 13:52:08 tnozaki Exp $ */
/* $NetBSD: iswctype_sb.c,v 1.11 2010/06/01 18:00:28 tnozaki Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: iswctype_sb.c,v 1.10 2010/06/01 13:52:08 tnozaki Exp $");
__RCSID("$NetBSD: iswctype_sb.c,v 1.11 2010/06/01 18:00:28 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@ -36,7 +36,9 @@ __RCSID("$NetBSD: iswctype_sb.c,v 1.10 2010/06/01 13:52:08 tnozaki Exp $");
#define _CTYPE_NOINLINE
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#define _ISWCTYPE_FUNC(name) \

View File

@ -1,4 +1,4 @@
/* $NetBSD: localeio_lc_ctype.c,v 1.3 2010/06/01 13:52:08 tnozaki Exp $ */
/* $NetBSD: localeio_lc_ctype.c,v 1.4 2010/06/01 18:00:28 tnozaki Exp $ */
/*-
* Copyright (c)2008 Citrus Project,
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: localeio_lc_ctype.c,v 1.3 2010/06/01 13:52:08 tnozaki Exp $");
__RCSID("$NetBSD: localeio_lc_ctype.c,v 1.4 2010/06/01 18:00:28 tnozaki Exp $");
#endif /* LIBC_SCCS and not lint */
#include "reentrant.h"
@ -49,7 +49,6 @@ __RCSID("$NetBSD: localeio_lc_ctype.c,v 1.3 2010/06/01 13:52:08 tnozaki Exp $");
#include "aliasname_local.h"
#include "bsdctype.h"
#include "ctypeio.h"
/*
* macro required by all template headers
@ -76,7 +75,7 @@ _localeio_LC_CTYPE_create_impl(const char * __restrict root,
snprintf(path, sizeof(path),
"%s/%s/LC_CTYPE", root, name);
return __loadctype(path, pdata);
return _bsdctype_load(path, pdata);
}
static __inline void
@ -86,10 +85,10 @@ _PREFIX(build_cache)(struct _locale_cache_t * __restrict cache,
_DIAGASSERT(cache != NULL);
_DIAGASSERT(data != NULL);
cache->ctype_tab = data->ctype_tab;
cache->tolower_tab = data->tolower_tab;
cache->toupper_tab = data->toupper_tab;
cache->mb_cur_max = (size_t)1;
cache->ctype_tab = data->bl_ctype_tab;
cache->tolower_tab = data->bl_tolower_tab;
cache->toupper_tab = data->bl_toupper_tab;
cache->mb_cur_max = (size_t)1;
}
static __inline void
@ -97,9 +96,9 @@ _PREFIX(fixup)(_BSDCTypeLocale *data)
{
_DIAGASSERT(data != NULL);
_ctype_ = data->ctype_tab;
_tolower_tab_ = data->tolower_tab;
_toupper_tab_ = data->toupper_tab;
_ctype_ = data->bl_ctype_tab;
_tolower_tab_ = data->bl_tolower_tab;
_toupper_tab_ = data->bl_toupper_tab;
}
/*