The format of locale data can be incompatible between libc versions, and loading incompatible data can lead to 'setlocale' returning EINVAL at best or triggering an assertion failure at worst. See https://lists.gnu.org/archive/html/guix-devel/2015-09/msg00717.html for background information. To address that, this patch changes libc to look for locale data in version-specific sub-directories. So, if LOCPATH=/foo:/bar, locale data is searched for in /foo/X.Y and /bar/X.Y, where X.Y is the libc version number. That way, a single 'LOCPATH' setting can work even if different libc versions coexist on the system. --- a/intl/l10nflist.c +++ b/intl/l10nflist.c @@ -25,6 +25,10 @@ # include #endif +#ifdef _LIBC +# include +#endif + #include #if defined _LIBC || defined HAVE_ARGZ_H @@ -164,6 +168,9 @@ _nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list, /* Allocate room for the full file name. */ abs_filename = (char *) malloc (dirlist_len +#ifdef _LIBC + + strlen (VERSION) + 1 +#endif + strlen (language) + ((mask & XPG_TERRITORY) != 0 ? strlen (territory) + 1 : 0) @@ -185,6 +192,10 @@ _nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list, memcpy (abs_filename, dirlist, dirlist_len); __argz_stringify (abs_filename, dirlist_len, ':'); cp = abs_filename + (dirlist_len - 1); +#ifdef _LIBC + *cp++ = '/'; + cp = stpcpy (cp, VERSION); +#endif *cp++ = '/'; cp = stpcpy (cp, language);