kiconvctl を覗く2006年07月22日 06時10分19秒

/usr/src/usr.sbin/kiconvctl/kiconvctl.c を見てみる。kiconvctl では以下のようなオプションがある。

# kiconvctl 
usage: kiconvctl add [-v] encoding
       kiconvctl add [-v] -l locale-name
       kiconvctl drvlist
       kiconvctl list [-u]
       kiconvctl load
       kiconvctl unload [-f]

add はどのように行なわれているのかを調べる。

まずは、main 探す。cspair_add が add の時に呼ばれている。


        if (verbose)
                printf("Adding tables \"%s\" <-> \"%s\"\n", ENCODING_UNICODE, csp);

        error = kiconv_add_xlat16_cspairs(ENCODING_UNICODE,
            kiconv_quirkcs(csp, KICONV_VENDOR_MICSFT));
        if (error)
                return (error);
        error = kiconv_add_xlat16_cspairs(ENCODING_UNICODE, csp);
        if (error)
                return (error);

man kiconv で出てくる、関数が呼ばれていたわけだ。さもありなんといったところか。

kiconv_add_xlat16_cspairs() は/usr/src/lib/libkiconv/xlat16_iconv.c にある。my_iconv_init() が kiconv_xlat16_open() の中で呼ばれている。


static int
my_iconv_init(void)
{
        void *iconv_lib;

        iconv_lib = dlopen("libiconv.so", RTLD_LAZY | RTLD_GLOBAL);
        if (iconv_lib == NULL) {
                warn("Unable to load iconv library: %s\n", dlerror());
                errno = ENOENT;
                return (-1);
        }
        my_iconv_open = dlsym(iconv_lib, "iconv_open");
        my_iconv = dlsym(iconv_lib, "iconv");
        my_iconv_close = dlsym(iconv_lib, "iconv_close");

        return (0);
}

my_iconv_init() を見ると、dlopen で libiconv.so を読み込んでいる。

# locate libiconv.so
/usr/local/lib/libiconv.so
/usr/local/lib/libiconv.so.3

libiconv.so は /usr/local にあるので、ports から入った物だ。kiconv はユーザ空間の libiconv を読み込んでいる。

少々驚いたのは、libiconv が /usr 等の FreeBSD のベースシステムにあるわけでは無いことだ。perl は一昔前はベースに入っていたが、管理の繁雑さのためにベースシステムから追い出された。それに伴って、ベースシステムにあった perl で書かれたプログラムは全て書き直されたのだ。

kiconv は敢えて ports からのライブラリに依存している。動的に読み込めるのだから、libiconv をわざわざベースシステムでも管理するよりも理に適っていると思う。

前回次回