Bug 11635 - setlocale() doesn't support path based locale specification
Summary: setlocale() doesn't support path based locale specification
Status: RESOLVED INVALID
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.12
: P2 enhancement
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-25 14:56 UTC by Yann Droneaud
Modified: 2014-06-30 17:56 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yann Droneaud 2010-05-25 14:56:22 UTC
I've created a locale definition with localedef -f UTF-8 -i fr_FR
$PWD/fr_FR.UTF-8 which create a private definition.

According to The Open Group Base Specifications Issue 7 / IEEE Std 1003.1-2008:

  If the name contains one or more <slash> characters, name shall be interpreted
  as a pathname where the created locale definitions shall be stored.

The path can latter be used as LC_* environment variables values:
 
  The value that is used to specify a locale when using environment variables 
  shall be the string specified as the name operand to the localedef  utility 
  when the locale was created.

  [...]

  When the value of a locale environment variable begins with a <slash> ( '/' ), 
  it shall be interpreted as the pathname of the locale definition; the type of 
  file (regular, directory, and so on) used to store the locale definition is 
  implementation-defined. 


Example: LC_ALL=$PWD/fr_FR.UTF-8 locale

But this doesn't work under GLIBC.

According to strace: setlocale() implementation first look to "locale-archive",
then search the LC_ALL value in a directory lookup, e.g. the system directory,
defined at build time. See the following log:

open("/opt/glibc-devel/lib/locale//home/ydroneaud/tmp/fr_FR.UTF-8//LC_CTYPE",
O_RDONLY) = -1 ENOENT (No such file or directory)
open("/opt/glibc-devel/lib/locale//home/ydroneaud/tmp/fr_FR.utf8/LC_CTYPE",
O_RDONLY) = -1 ENOENT (No such file or directory)
open("/opt/glibc-devel/lib/locale//home/ydroneaud/tmp/fr_FR/LC_CTYPE", O_RDONLY)
= -1 ENOENT (No such file or directory)
open("/opt/glibc-devel/lib/locale//home/ydroneaud/tmp/fr.UTF-8//LC_CTYPE",
O_RDONLY) = -1 ENOENT (No such file or directory)
open("/opt/glibc-devel/lib/locale//home/ydroneaud/tmp/fr.utf8/LC_CTYPE",
O_RDONLY) = -1 ENOENT (No such file or directory)
open("/opt/glibc-devel/lib/locale//home/ydroneaud/tmp/fr/LC_CTYPE", O_RDONLY) =
-1 ENOENT (No such file or directory)

Where /opt/glibc-devel/lib/locale is the system locale directory and
/home/tmp/ydroneaud/tmp/fr_FR.UTF-8 the path given as LC_ALL.
Comment 1 Ulrich Drepper 2010-05-25 15:11:18 UTC
The LC_* variables don't contain paths.  Why should they?  Paths are specified
in LOCPATH.
Comment 2 Yann Droneaud 2010-05-25 15:25:49 UTC
(In reply to comment #1)
> The LC_* variables don't contain paths.  Why should they? 

So, you, as a member of the Austin group, should ask for the removal of this
feature from the Open Group specifications.

Regards.
Comment 3 Petr Baudis 2010-05-25 20:10:45 UTC
This is a conformance issue; either glibc should implement POSIX properly, or if
you think the spec is not sane, a defect against POSIX should be filed as the
bug is closed.
Comment 4 Ulrich Drepper 2010-05-25 20:26:39 UTC
It's not a conformance issue.  There is nothing that can be done for
LC_ALL=/some/path.  The standard only requires that  if the envvar points to a
file it is used.  With LC_ALL there is no single file and pointing to a
directory does not fulfill the requirements of the standard.  And I have no
interest whatsoever to add a bogus extension which would allow doing this. 
Nobody should ever use this.  The specification for localedef doesn't describe
the format of the output files and therefore this whole portion of the spec is
utterly bogus useless crap.
Comment 5 Yann Droneaud 2010-05-26 08:50:28 UTC
(In reply to comment #4)
> It's not a conformance issue.  There is nothing that can be done for
> LC_ALL=/some/path.  The standard only requires that  if the envvar points to a
> file it is used. 

Not necessarily a file, it could be a directory.

> With LC_ALL there is no single file and pointing to a
> directory does not fulfill the requirements of the standard.  

The path to be given to LC_* is the same as the path given to localedef.
Whether it's a single file or a directory, it's up to the implementation.

example:

  localedef -f UTF-8 -i fr_FR /home/foo/locales/fr_FR.UTF-8

  LC_ALL=/home/foo/locales/fr_FR.UTF-8 locale
  LC_CTYPE=/home/foo/locales/fr_FR.UTF-8 locale


> And I have no
> interest whatsoever to add a bogus extension which would allow doing this. 

The kind of bogus extension would be to use the path given in LC_* variables
instead of the hard-coded ones.

> Nobody should ever use this.  

Yes, probably.

I think the purpose of this extension is to allow user of a proprietary/closed
system to be able to use specific locales.

Having the glibc sources, I can rebuild it with any locale I want, so I'm not
stuck for my tests, but it would be easier to use the facility given by the
standard.

> The specification for localedef doesn't describe
> the format of the output files and therefore this whole portion of the spec is
> utterly bogus useless crap.

The specification of this feature doesn't rely on the underlying format of the
localedef output (hopefully).


If you don't want to implement this part of the POSIX specification, it's not a
problem for me, but please don't say it doesn't exists (in the specification).
The resolution for this bug isn't INVALID, but WONTFIX instead.

Regards.