POSIXに於けるSAORIの扱いについて
この文書では、POSIX環境に於ける、栞のすべきSAORIの扱いについて説明します。
概要
SAORIはWindows環境ではDLLとして実現されているのに対し、POSIXでは
dlopen(3)
可能なダイナミックローダブルライブラリとして実現する。
ゴーストに同梱されているDLLは通常Windows用なので、その他のOSでは使えない。この問題に対処するため、
栞はDLLのファイル名を基に利用可能なライブラリを検索するフォールバック処理を行う。
処理の流れ
- ロードすべきSAORIのDLLを saori\ssu.dll とする。
- 栞はまずこのDLLを試しに dlopen(3) してみる。dlopenに成功し、且つdlsym(3)で必要なシンボルを
取り出す事が出来たならこのライブラリをそのまま使って良いが、通常このファイルはWindows用のDLLファイルなので、
dlopen(3)には失敗する。
- 失敗したなら、栞は環境変数 SAORI_FALLBACK_PATH を見る。この環境変数はPATHと同じ形式、すなわち
コロン区切りの絶対パスである。もしこの変数が存在していたなら、栞は問題のDLLと同名のファイル、
すなわち ssu.dll と云う名前のファイルを、SAORI_FALLBACK_PATHで与えられたパスから検索する。
- 見付かれば、そのファイルを本来のDLLの代わりにロードして呼び出す。見付からなければ諦める。
- SAORIのload()には、元のDLLのある場所が渡される。フォールバック先では*ない*。
ファイル構成
SAORI_FALLBACK_PATHの通った位置にDLLと同名のファイルを置く事になるわけだが、実際にはライブラリ本体は
libssu.soといった通常の慣習に従った名前を付けておき、ssu.dllからシンボリックリンクを張るようにした方が望ましい。
例:
% pwd
/usr/local/lib/saori
% ls -l
-rwxr-xr-x x foo bar xxxxx 1 1 00:00 libssu.so
lrwxr-xr-x x foo bar xxxxx 1 1 00:00 ssu.dll -> libssu.so
安全策: SAORI_FALLBACK_ALWAYS
通常の処理の流れでは、まず初めに(十中八九Windows用である)DLLファイルをdlopen(3)してみる事になるが、
万が一そのプラットフォームで利用可能なライブラリでないのにdlopen(3)やdlsym(3)に成功すると、
栞はクラッシュする事になる。このような事は滅多に起るものではないはずだが、本来のDLLを開いてみる事はせずに
最初からフォールバックへ移行する手段を提供した方が、より安全ではある。
栞はSAORIの検索を始める際、環境変数SAORI_FALLBACK_ALWAYSを見て、これが空でも"0"でもなければ
この時点でフォールバックへ移行した方が良い。
dlopenのオプションについて
-
RTLD_LAZYとRTLD_NOW: 恐らくどちらも安全。まあ普通は未解決なシンボルのあるライブラリなど
作らない筈なので、効率を考えてRTLD_LAZYにした方が良いだろうか。
-
RTLD_GLOBAL: これは一応ポータブルではあるようだが、Darwin環境では"-dylib"フラグ付きでリンクした
ライブラリに対してのみ利用可能である、といった制限があるので、出来れば使わない方が安全である。
-
RTLD_LOCAL: これはポータブルでない。DarwinのManPageには載っているが、Linuxのものには載ってすらいない。
この文書ではdlopenのオプションとして RTLD_LAZY のみを用いる事を推奨する。
プロトタイプ
SAORIモジュールは次のシンボルを外部公開していなければならない。
- int load(char* data, long length);
- int unload(void);
- char* request(char* data, long* length);
char*は呼び出し側が malloc(3)
で確保し、受取り側が free(3) で解放する。
各シンボルの使い方はSAORI仕様書に示されている。
問題点
-
同名のdllで動作の違う複数のSAORIがあるとすれば、そのうちの一つしか正常に動作させる事が出来ない。
元々ゴーストのディレクトリで独立していた名前空間を破壊し、ファイルを一ヶ所に集めてしまう為である。
load()で渡されるディレクトリにある元のDLLの中身を覗くなどしてDLLの違いを判別するハックも考えられるが、
これは飽く迄もハックである。
更新履歴
- 2004年2月12日 細部を修正。dlopenのオプションについて追記。
- 2004年2月11日 公開。この時点では「里々POSIX」のみがこの仕様に基いて実装されている。