Hi, I have a serie of patches for adding support of xlocale in libc (10 currently, but not completely terminated) I want to be reviewed for comments and OK.
I intend to commit them all at same time and after 5.8 lock I think. They will need a libc major bump, and some bluk build of ports too before commiting. These patches add gradually xlocale support in libc. Each commit should be compilable and produce a usable libc.so (but you will need previous patches in the serie). Please note the patches aren't cvs diff but plain text patches (I used quilt). This first commit add minimal locale_t support. The function naming mainly follows NetBSD notation. locale_t is an opaque pointer to struct _locale_t, which, with this commit, only contains "flags" member (others members will be added gradually by others patches). The flag is (will be) used to discriminate installed state (used by one thread) from unused one. A state is installed only on one thread at a time (if you intend to call uselocale(3) repetively with one thread_t, it will be silenciously duplicated). LC_GLOBAL_LOCALE is, like NetBSD, a pointer on _lc_global_locale which will contains the global state for locale. The implementation of global/per-thread state use _THREAD_PRIVATE macros from thread_private.h, which allow to manage different code path for program linked with or without pthread: - _current_locale() is used to retreive the current state: per-thread thread if exists, else the global one. - _set_current_locale() is used to change the current state: restore global state in thread or change the per-thread state. Thanks for your comments. -- Sebastien Marie Index: b/lib/libc/locale/Makefile.inc =================================================================== --- a/lib/libc/locale/Makefile.inc 2015-07-03 13:15:19.000000000 +0200 +++ b/lib/libc/locale/Makefile.inc 2015-07-03 13:16:23.563565923 +0200 @@ -12,7 +12,7 @@ wcstombs.c wctob.c wctomb.c wcstof.c wcstod.c wcstold.c wcstol.c \ wcstoul.c wcstoll.c wcstoull.c wcstoimax.c wcstoumax.c \ setrunelocale.c runeglue.c rune.c runetable.c ___runetype_mb.c \ - _wctrans.c wcsxfrm.c + _wctrans.c wcsxfrm.c xlocale.c MAN+= nl_langinfo.3 setlocale.3 iswalnum.3 towlower.3 \ btowc.3 mblen.3 mbrlen.3 mbrtowc.3 mbsinit.3 mbsrtowcs.3 \ Index: b/lib/libc/locale/xlocale.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/lib/libc/locale/xlocale.c 2015-07-05 06:52:14.054110929 +0200 @@ -0,0 +1,72 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2015 Sebastien Marie <sema...@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> + +#include "thread_private.h" +#include "xlocale_private.h" + +/* + * hold the global state + */ +struct _locale_t _lc_global_locale = { + XLOCALE_INSTALLED +}; + + +/* + * global storage for per-thread locale state + */ +_THREAD_PRIVATE_KEY(xlocale_storage); +static struct _locale_t * xlocale_storage; + +/* + * return the current locale + */ +struct _locale_t * +_current_locale() +{ + struct _locale_t ** loc_storage = _THREAD_PRIVATE(xlocale_storage, + xlocale_storage, NULL); + + if ((loc_storage == NULL) || (*loc_storage == NULL)) + return (&_lc_global_locale); + else + return (*loc_storage); +} + + +/* + * set the current locale, and return the previous one. + * will return NULL on error. + */ +struct _locale_t * +_set_current_locale(struct _locale_t * newloc) +{ + struct _locale_t ** loc_storage = _THREAD_PRIVATE(xlocale_storage, + xlocale_storage, NULL); + struct _locale_t * oldloc = _current_locale(); + + if (newloc == &_lc_global_locale) + newloc = NULL; + + if (loc_storage != NULL) { + *loc_storage = newloc; + return (oldloc); + } else + return (NULL); +} Index: b/include/locale.h =================================================================== --- a/include/locale.h 2015-07-03 13:12:37.351814997 +0200 +++ b/include/locale.h 2015-07-03 13:16:23.573565344 +0200 @@ -87,6 +87,15 @@ __BEGIN_DECLS struct lconv *localeconv(void); char *setlocale(int, const char *); + +#if __POSIX_VISIBLE >= 200809 +struct _locale_t; +typedef struct _locale_t * locale_t; + +extern struct _locale_t _lc_global_locale; +#define LC_GLOBAL_LOCALE (&_lc_global_locale) + +#endif /* __POSIX_VISIBLE >= 200809 */ __END_DECLS #endif /* _LOCALE_H_ */ Index: b/lib/libc/locale/xlocale_private.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/lib/libc/locale/xlocale_private.h 2015-07-05 06:52:03.814017792 +0200 @@ -0,0 +1,36 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2015 Sebastien Marie <sema...@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef _XLOCALE_PRIVATE_H_ +#define _XLOCALE_PRIVATE_H_ + +#include <sys/cdefs.h> + +struct _locale_t { + int flags; +}; + +#define XLOCALE_INSTALLED (1 << 0) + +#define xlocale_is_installed(flags) (flags & XLOCALE_INSTALLED) + +__BEGIN_DECLS +extern struct _locale_t _lc_global_locale; +extern struct _locale_t * _current_locale(void); +extern struct _locale_t * _set_current_locale(struct _locale_t *); +__END_DECLS + +#endif /* _XLOCALE_PRIVATE_H_ */