refactoring old locale-db(BSDCTYPE) loading method with mmap(2).
This commit is contained in:
parent
9a35d7972b
commit
d8217122b9
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_*/
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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) \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue