[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[debian-devel:15367] Re: bash の初期化がおかしい



At Tue, 29 Oct 2002 17:56:17 +0900,
Satoshi Koike wrote:

> 鵜飼さんが作られた patch の場合には、LC_ALL, LC_CTYPE, LANG の順で探索
> して、環境変数が定義されていれば、LC_CTYPE の設定にそれを使う、という
> 事を明示して書かれていると解釈しました。
> 
> ですが、setlocale の man page の 50 行目からの段落を読むと、なさった環
> 境変数の探索は、setlocale(LC_CTYPE, "") の内部でなされる事が保証される
> 事が、setlocale の仕様として定められていると読めます。
> 
> 以下、その部分の引用です。適当に桁折りしてあります。
> 
> > For glibc, first (regardless of category), the environment variable
> > LC_ALL is inspected, next the environment variable with the same
> > name as the category (LC_COLLATE, LC_CTYPE, LC_MESSAGES,
> > LC_MONETARY, LC_NUMERIC, LC_TIME) and finally the environment
> > variable LANG. The first existing environment variable is used.
> 
> ですので、元のコード setlocale(LC_CTYPE, "") と同じ動作になると思われ
> ますが、いかがでしょうか?

違います。sh_get_env_value() でとれるのは今動いているbashで設定した
環境変数(でbashの子プロセスに適用される環境変数)であって、bashそれ
自体の環境変数ではないからです。

つまり ~/.bashrc で export LANG=ja_JP.eucJP としている状態で

 % LANG=C bash

とした場合
 bashの環境変数 LANG は C
 bashから起動するプロセスでの環境変数 LANG は ja_JP.eucJP
となります。

で、setlocale(LC_CTYPE, "")はそのプロセスの環境変数を参照するので
bashの中で setlocale()をこのようによんでも LANG=C として動くことに
なるので問題の症状がでているわけです。

# putenv("LANG=ja_JP.eucJP") とかする方がいいのかもしれない?

> それとも、
> 
> >  1) ~/.bashrc の LANG=ja_JP.eucJP が処理される
> >    => setlocale(LC_ALL, "ja_JP.eucJP")
> 
> この段階で setenv("LANG", "ja_JP.eucJP") の様な処理がなされないままで、
> setlocale(LC_CTYPE, "") が行なわれる為に問題が発生する、という事でしょ
> うか?でしたら、そちらの方が本質的な問題だと思われます。まだコードを追っ
> てないので、そう行えない、他の要因があるのかもしれませんが。

ちがいます。1)->2)->3) の順番で処理されています。
# LANG=C ltrace -o /tmp/bash.trace -l /lib/libc.so.6 -e setlocale bash

> 例えば、Solaris と Linux で、
> 
>      1  #include <stdio.h>
>      2  #include <locale.h>
>      3  #include <string.h>
>      4  #include <errno.h>
>      5
>      6  int main()
>      7  {
>      8    setlocale(LC_ALL, "ja_JP.eucJP");
>      9    setlocale(LC_CTYPE, "C");
>     10    puts(strerror(ENOENT));
>     11    return 0;
>     12  }
> 
> というようなコードを実行させますと、Linux では ?????????????????????? 
> と表示されるのは、今回の問題と同じような動作なのですが、Solaris の場合
> には、「ファイルもディレクトリもありません。」と、日本語(EUC-JP)で表示
> されてしまいます。今回の件も、この辺りの挙動の差異に似ているので、そう
> ではないかと私は考えています。

linux では LC_CTYPE によって gettext()する時に メッセージ を iconv で
変換しているのでそのせいでしょう。変換できない文字セットは ? に変換されます。

-- 
鵜飼文敏