[FreeBSD-users-jp 96345] Re: FreeBSD-11.2 の ja_JP.eucJP 環境
内藤 祐一郎
naito.yuichiro @ gmail.com
2018年 11月 6日 (火) 15:02:00 UTC
内藤です。
> FreeBSD ワークショップでも話が出た (出ない?) ようですが、
私がワークショップで話した内容は次の通りです。
11.2のソースのlib/libedit/read.c の L350-L378 に以下のコードがあり、
read(2) で1バイトずつ読み込んでは mbrtowc で wchar_t に変換するコードがあります。
switch (ct_mbrtowc(cp, cbuf, cbp)) {
case (size_t)-1:
if (cbp > 1) {
/*
* Invalid sequence, discard all bytes
* except the last one.
*/
cbuf[0] = cbuf[cbp - 1];
cbp = 0;
break;
} else {
/* Invalid byte, discard it. */
cbp = 0;
goto again;
}
case (size_t)-2:
/*
* We don't support other multibyte charsets.
* The second condition shouldn't happen
* and is here merely for additional safety.
*/
if ((el->el_flags & CHARSET_IS_UTF8) == 0 ||
cbp >= MB_LEN_MAX) {
errno = EILSEQ;
*cp = L'\0';
return -1;
}
/* Incomplete sequence, read another byte. */
goto again;
mbrtowc()ではlocaleに従いバイト列を wchar_t に変換するわけですが、
eucJP や UTF-8 では当然1バイト読んだだけでは変換できません。
2バイト目や3バイト目が必要なため、mbrtowc()は -2 を返し、
続きを読み込んでくれと返しますが、呼び出し元では
el_flags に CHARSET_IS_UTF8 のフラグが立っていないとリトライせずに
エラー終了します。
libedit のこの関数(read_char)がエラー終了すると /bin/sh は標準入力が
閉じられたのと同じ動作をして終了してしまいます。
このCHARSET_IS_UTF8 がどこで立てられているのかと言うと、
lib/libedit/el.c:L97-105 の部分なのですが、
/*
* Initialize all the modules. Order is important!!!
*/
el->el_flags = 0;
if (setlocale(LC_CTYPE, NULL) != NULL){
if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
el->el_flags |= CHARSET_IS_UTF8;
}
この処理は /bin/sh の起動直後で ~/.profile が読み込まれる前に実行されます。
そのため、/bin/sh の起動時に locale が UTF-8 だと UTF-8 は扱えますが、
ログインシェルのように /bin/sh の起動時の locale が C だと UTF-8 が通りません。
試しに /etc/login.conf で locale を UTF-8 にすると /bin/sh の起動時に locale が
設定されるので、UTF-8が通るようになります。
また、見ての通り、locale が eucJP の場合も CHARSET_IS_UTF8 が立つことは
ありません。
ここで、locale を一切無視してに常に CHARSET_IS_UTF8 を立てるようにすると、
とりあえず eucJP も UTF-8 も通りましたが、eucJP の場合でヒストリに
ゴミが入る問題が手元では発生しましたので、使える状態ににはありませんでした。
と、ここまでがワークショップで話した内容です。
その後なのですが、私個人が eucJP を使いたいとは思っていないこともあり
調査は進んでいません。
UTF-8 を通すだけのパッチならば、先ほどの CHARSET_IS_UTF8 の初期化位置を
直せば良いので簡単なのですが、それでは解決になってませんから。。。
また、この内容では平林さんの /bin/sh の parser.h が問題だという話は
全く無関係に思いますし、渡辺さんの UTF-8 では入力できたという報告とも
矛盾します。
はてさて、真実はどこにといった感じもあり、あんまり進展していません。。。
--
内藤 祐一郎
naito.yuichiro @ gmail.com
freebsd-users-jp メーリングリストの案内