@ -17,8 +17,9 @@ char *__strchrnul(const char *, int);
static struct __locale_map * findlocale ( const char * name , size_t n )
static struct __locale_map * findlocale ( const char * name , size_t n )
{
{
static int lock [ 2 ] ;
static void * volatile loc_head ;
static void * volatile loc_head ;
struct __locale_map * p , * new , * old_head ;
struct __locale_map * p , * new = 0 ;
const char * path = 0 , * z ;
const char * path = 0 , * z ;
char buf [ 256 ] ;
char buf [ 256 ] ;
size_t l ;
size_t l ;
@ -28,11 +29,18 @@ static struct __locale_map *findlocale(const char *name, size_t n)
for ( p = loc_head ; p ; p = p - > next )
for ( p = loc_head ; p ; p = p - > next )
if ( ! strcmp ( name , p - > name ) ) return p ;
if ( ! strcmp ( name , p - > name ) ) return p ;
LOCK ( lock ) ;
for ( p = loc_head ; p ; p = p - > next )
if ( ! strcmp ( name , p - > name ) ) {
UNLOCK ( lock ) ;
return p ;
}
if ( ! libc . secure ) path = getenv ( " MUSL_LOCPATH " ) ;
if ( ! libc . secure ) path = getenv ( " MUSL_LOCPATH " ) ;
/* FIXME: add a default path? */
/* FIXME: add a default path? */
if ( ! path ) return 0 ;
for ( ; * path ; path = z + ! ! * z ) {
if ( path ) for ( ; * path ; path = z + ! ! * z ) {
z = __strchrnul ( path , ' : ' ) ;
z = __strchrnul ( path , ' : ' ) ;
l = z - path - ! ! * z ;
l = z - path - ! ! * z ;
if ( l > = sizeof buf - n - 2 ) continue ;
if ( l > = sizeof buf - n - 2 ) continue ;
@ -45,20 +53,19 @@ static struct __locale_map *findlocale(const char *name, size_t n)
new = malloc ( sizeof * new ) ;
new = malloc ( sizeof * new ) ;
if ( ! new ) {
if ( ! new ) {
__munmap ( ( void * ) map , map_size ) ;
__munmap ( ( void * ) map , map_size ) ;
return 0 ;
break ;
}
}
new - > map = map ;
new - > map = map ;
new - > map_size = map_size ;
new - > map_size = map_size ;
memcpy ( new - > name , name , n ) ;
memcpy ( new - > name , name , n ) ;
new - > name [ n ] = 0 ;
new - > name [ n ] = 0 ;
do {
new - > next = loc_head ;
old_head = loc_head ;
loc_head = new ;
new - > next = old_head ;
break ;
} while ( a_cas_p ( & loc_head , old_head , new ) ! = old_head ) ;
return new ;
}
}
}
}
return 0 ;
UNLOCK ( lock ) ;
return new ;
}
}
static const char envvars [ ] [ 12 ] = {
static const char envvars [ ] [ 12 ] = {
@ -85,11 +92,10 @@ int __setlocalecat(locale_t loc, int cat, const char *val)
int builtin = ( val [ 0 ] = = ' C ' & & ! val [ 1 ] )
int builtin = ( val [ 0 ] = = ' C ' & & ! val [ 1 ] )
| | ! strcmp ( val , " C.UTF-8 " )
| | ! strcmp ( val , " C.UTF-8 " )
| | ! strcmp ( val , " POSIX " ) ;
| | ! strcmp ( val , " POSIX " ) ;
struct __locale_map * data , * old ;
switch ( cat ) {
switch ( cat ) {
case LC_CTYPE :
case LC_CTYPE :
a_store ( & loc - > ctype_utf8 , ! builtin | | val [ 1 ] = = ' . ' ) ;
loc - > ctype_utf8 = ! builtin | | val [ 1 ] = = ' . ' ;
break ;
break ;
case LC_MESSAGES :
case LC_MESSAGES :
if ( builtin ) {
if ( builtin ) {
@ -100,10 +106,7 @@ int __setlocalecat(locale_t loc, int cat, const char *val)
}
}
/* fall through */
/* fall through */
default :
default :
data = builtin ? 0 : findlocale ( val , n ) ;
loc - > cat [ cat - 2 ] = builtin ? 0 : findlocale ( val , n ) ;
if ( data = = loc - > cat [ cat - 2 ] ) break ;
do old = loc - > cat [ cat - 2 ] ;
while ( a_cas_p ( & loc - > cat [ cat - 2 ] , old , data ) ! = old ) ;
case LC_NUMERIC :
case LC_NUMERIC :
break ;
break ;
}
}